Jump to content
Search Community

Can i check if a timeline actually will animate anything?

Christian Eide

Go to solution Solved by Christian Eide,

Recommended Posts

Christian Eide
Posted

Hi! 

 

I have a setup where animations is added dynamically to a timeline. The setup will also que animations so that one animation has to be complete before the next animation run. This setups is perfect for us and solves our usecase perfectly.

 

The problem is that sometimes the dynamic animations do not actually animate anything, but they are still added to the cue. For example if an element is animated from the current x position (100) to a new x position (100) with the same value. The animation will be added to the timeline, but no visible change will be visible to the user.

 

Offcourse I could check if the x-value actually has changed and prevent the animation from happening, but my animations are both scale, position, rotation, opacity, blur and other properties. And even then an animation from filter: blur(0) to a new value where filter is undefined is also no visible animation to the user. So it is difficult to maintain a good logic to handle this over time.

 

Therefore I wondered if it was possible to check this in gsap in some way? That I can add the animation to the timeline, but than check with gsap if this actually will animate anything? I have read the docs and tried to find something on the forums, but with no luck.

 

See the codepen for an example. First press on the button will animate the block 100px. The next will animate from 100 to 100, so no visible change, but as the statusbar shows an animations is still happening in the timeline.

See the Pen jEMyOpv by christianeide (@christianeide) on CodePen.

Rodrigo
Posted

Hi @Christian Eide and welcome to the GSAP Forums!

 

Yeah there isn't anything in our API that tests for that directly but we have methods that can help you with it. I assume that you want to prevent a Tween being placed right after another that animates the same element's property to the same value, in that case you can use the getChildren() method in order to get an array and check for the last element in the array and see if it has the same target and vars, just loop through the objects of both Tweens:

https://gsap.com/docs/v3/GSAP/Timeline/getChildren()

 

You can check the vars object of both Tweens and loop through the vars object and check if the properties and values are the same.

https://gsap.com/docs/v3/GSAP/Tween/vars

 

Also you can use the getTweensOf() method in order to get all the Tweens that target the same element:

https://gsap.com/docs/v3/GSAP/gsap.getTweensOf()

 

You can check their position in the parent Timeline and see if one or more of them have the issue you're looking for using the vars object I mentioned above.

 

As you can see there are tools in our API to get around this and find out what you're looking for, but specific use cases such as yours, require custom solutions that fit the needs of the project.

 

Hopefully this helps

Happy Tweening!

  • Like 1
Christian Eide
Posted

Hi again. Thank you so much for your answer and suggestion!

 

I have tried your proposed solution, and Im pretty close but not entirely. The biggest problem is some formating and units of some of the values.

 

The value for transformOrigin gives me the desiredValue/new value of `50% 50%` , but the currentValue is transformed to pixels into `960px 540px 0px`

I have tried to add unit to getProperty, but I have not found the correct unit to get percentage values out? Or can I do this the other way and convert my new/desiredValue to px as well? Meaning to use the gsap.getProperty to get a value from a vars? I have tried that, but then gsap.getProperty(vars, "transformOrigin") returns percentages.

 

Im also having issues with filter values that are currently `url("#wb-50") blur(24px)` but as `url(#wb-50) blur(24px)`  from vars. I could ofcourse make an easy function that strips ", but it makes me a bit worried that I might not be able to handle all possible details. But maybe this is my best luck?

 

function isNoOpAnimation(animation) {
	if (!animation || typeof animation.getChildren !== 'function') {
		return true;
	}

	const tweens = animation.getChildren(true, true, false);

	return tweens.every((tween) => {
		const targets = typeof tween.targets === 'function' ? tween.targets() : [];
		const vars = tween.vars || {};

		return targets.every((target) => {
			return Object.entries(vars).every(([prop, desiredValue]) => {
				if (typeof desiredValue === 'function' || desiredValue === undefined) {
					return true;
				}

				const currentValue = gsap.getProperty(target, prop);

				return areValuesEqual(currentValue, desiredValue, prop);
			});
		});
	});
}

 

Rodrigo
Posted

Hi,

 

Yeah for complex strings like filters you'll have to create your own custom code in order to parse those values, based on the values you expect to find there. I'd go with a regular expression that covers most of the filters values, or checks the parenthesis and the values inside of it.

 

As for the transform origin, keep in mind that you can pass a third argument to the getProperty method and tell GSAP to return a specific unit for that property:

gsap.to(".box", {
  rotation: 45,
  onComplete: () => {
    // Third parameter tells to get the value in pixels
    // This considers a box element that is a 100px square
    console.log(gsap.getProperty(".box", "transformOrigin", "px")); // 50px 50px 0px
  },
});

Hopefully this helps

Happy Tweening!

GreenSock
Posted

For formatting, GSAP just delivers what the browser reports which is often in px. 

 

I haven't had time to read through the entire thread, but if I were you, I might consider having my own version of the animation-related data stored in Arrays or objects so that you have complete control over the formatting of everything and you can do your own comparisons (instead of treating the GSAP timelines as your "source of truth")... and then simply feed that into a function that creates the GSAP animations out of the data. Heck, you could even attach each animation's data to the tween using the "data" property so that you can inspect it later if necessary. 

 

I hope that helps! 

  • Like 1
  • 4 weeks later...
  • Solution
Christian Eide
Posted

Hi again, and sorry for the late reply. This task was suddenly delayed.

 

I have tried more with gsap, and the solution with checking gsap variables has to many potential pitfalls.

 

I already have the animation related data stored, just not handling the issues mentioned here where blur(0) and a not defined blur value should actually be the same value. But I will create a solution based on this outside of gsap instead and handle my cases there.

 

Thank you for your time and quick reponse!

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...