chenxin Posted March 19, 2020 Posted March 19, 2020 I want to animate the property uPosx and uPosy of this.pageCurlMaterial object, but the value can only be signed with the setProperty function. How can I use gsap in this case? I think maybe I need to call setProperty on the onUpdate callback, but I don't know how to form it. this.pageCurlMaterial.setProperty("uPosx", this.pointerStartPosx) this.pageCurlMaterial.setProperty("uPosy", this.pointerStartPosy)
ZachSaucier Posted March 19, 2020 Posted March 19, 2020 Hey chenxin. Cases like this are where using a proxy object is useful. You can use the callbackScope property to pass in what this refers to if you need to. Alternatively you could save this to a different variable and refer to that inside of the onUpdate. Something like this should work: let proxy = {x: this.pointerStartPosx, y: this.pointerStartPosy); gsap.to(proxy, {x: targetXVal, y: targetYVal, callbackScope: this, onUpdate: function() { this.pageCurlMaterial.setProperty("uPosx", proxy.x); this.pageCurlMaterial.setProperty("uPosy", proxy.y); }}); 1
GreenSock Posted March 19, 2020 Posted March 19, 2020 Here's a helper function I whipped up that'll automatically add multi-purpose getter/setter methods to your object without the "get" and "set" in front: function wrapSetters(target, names) { if (names) { names.split(",").forEach(name => { let cappedName = name.charAt(0).toUpperCase() + name.substr(1), setter = target["set" + cappedName], getter = target["get" + cappedName]; (setter && getter) || console.warn("No getter/setter defined for", name); target[name] = function(value) { return arguments.length ? setter.call(target, value) : getter.call(target); }; }); } else { Object.keys(target).forEach(name => { let getter, setter; if (name.substr(0, 3) === "set" && (getter = target["get" + name.substr(3)])) { setter = target[name]; target[name.charAt(3).toLowerCase() + name.substr(4)] = function(value) { return arguments.length ? setter.call(target, value) : getter.call(target); }; } }); } } Usage: var obj = { _opacity: 0, setOpacity(value) { this._opacity = value; }, getOpacity() { return this._opacity; } }; wrapSetters(obj); // <- loops through all enumerable properties, finds any that start with "set" and have a matching "get" function, adds a new function without the get/set for convenience... gsap.to(obj, {opacity: 1, duration: 2, ease: "none", onUpdate: () => console.log(obj.getOpacity())}); // -OR- you can feed in a comma-delimited list of property names (without the get/set in front) and it'll just do those: wrapSetters(obj, "opacity"); So basically, with that helper function your tweening code could be as concise as this from now on... gsap.to(wrapSetters(obj), {opacity: 1, duration: 3}); gsap.to(wrapSetters(obj2), {x: 100, duration: 1}); ... And you should only need to run that function once on each object you're animating. Zach's method is also an excellent solution. I just figured that we've had a few people ask about this now, so a helper method might...um...help 1
GreenSock Posted March 19, 2020 Posted March 19, 2020 Actually, sorry, I rushed when I was reading the original post and didn't catch that your particular setup doesn't use names like "setOpacity()" and "getOpacity()", etc. - you use a standard "setProperty()" and "getProperty()" method for everything. That actually makes it even easier: function proxySetters(target, names) { names.split(",").forEach(name => { target[name] = function(value) { return arguments.length ? target.setProperty(name, value) : target.getProperty(name); }; }); } Example: var obj = { _opacity: 0, _x: 0, setProperty(name, value) { this["_" + name] = value; }, getProperty(name) { return this["_" + name]; } }; proxySetters(obj, "opacity,x"); gsap.to(obj, {opacity: 1, x: 100, duration: 2, ease: "none", onUpdate: () => console.log("opacity:", obj.getProperty("opacity"), "x:", obj.getProperty("x"))}); So with the helper function your tweens could be as concise as: gsap.to(proxySetters(this.pageCurlMaterial, "uPosx,uPosy"), { uPosx: 500, uPosy: 100, duration: 2 }); Better? 5
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now