Jump to content
Search Community

Simple way to change property by a factor (relative value)

trych test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

Hi there,

 

I was wondering if there is a simple way to change a property by a certain factor.

I know you can set relative values by using addition and subtraction, like so

gsap.to(box, {
  width: '+=200',
  height: '-=50'
});


So I am somewhat confused why you cannot do the same thing with multiplication and division like so

gsap.to(box, {
  width: '*=2',   // multiply the current value by 2
  height: '/=2'   // divide the current value by 2
});

? This would seem rather logical to me, since *= and /= are standard JS operators just as += and -=.

Since this is not possible apparently, is there a simple alternative? The simplest way I could come up with was

gsap.to(box, {
  width: (ix, target) => gsap.getProperty(target, 'width') * 2,
  height: (ix, target) => gsap.getProperty(target, 'height') / 2
});

which seems quite complicated for such a standard thing as doubling a property value.

Is there any simpler alternative that I am missing?

Thanks a lot!

Link to comment
Share on other sites

  • Solution

Very fair question, @trych - it's just that *= and /= are extremely uncommon use cases and we didn't want to add the kb or take the very slight performance hit of adding that conditional logic across all tweens. It didn't seem worth it for something you could still accomplish with the existing API the way you did it (good job). If you're doing that a lot and want to simplify things, you could encapsulate it into a reusable function like: 

 

function parse(value) {
	if (typeof value !== "string" || !/^(?:\*=|\/=)/.test(value)) {
		return value;
	}
	let n = parseFloat(value.substr(2)),
		factor = value.charAt(0) === "*" ? n : 1 / n,
		func = function(i, target) {
			for (let p in this.vars) {
				if (this.vars[p] === func) {
					return gsap.getProperty(target, p) * factor;
				}
			}
		}
	return func;
}

Usage: 

gsap.to(".target", {
  scaleX: parse("*=2"),
  scaleY: parse("/=2")
});

There may be some edge cases that won't work with, but it should be pretty solid for most cases. 

 

Does that clear things up? 

  • Like 3
Link to comment
Share on other sites

Thanks @GreenSock, that does clear things up.

And thanks for the parse function. That will come in handy.

However, I am not really conviced that *= would be a really uncommon use case. Judging by the projects that I have done with gsap so far, I need something like this literally all the time. And I always needed to work awkwardly around it, which does not feel very gsap-like. I mean there are now so many different notations to handle tween timing in the timeline, that it feels strange that the property manipulation is somewhat limited.

If performance is an issue, I wonder, would it maybe be an option to just include the *= option (without the /=, because instead of /=2 one could of course just do *=0.5) and if that would keep the performance hit within acceptable limits? I really believe people could benefit from an option that allows them to easily scale a property value by a certain factor.

Link to comment
Share on other sites

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...