benoit958 Posted February 5, 2023 Share Posted February 5, 2023 Hello there, I came accross a very strange and specific issue using threejs + gsap. I’m working with threejs and using a timeline to animate textures offsets (it moves the texture on a 3d sphere). Everything works well but I need to be able to switch from a texture to another at certain points of the animation. I want to reuse the same material but switch to another image at a certain position. To do so I decided to use “.call” to trigger a function (setTexture). Problem is when I'm doing this, the animation for that material is not playing anymore. The texture has switched but the “y” offset value is not updated. (When I'm just using setTexture without gsap, I'm able to switch my texture and it's still animated so the problem doesn't seems to come from here) Anyway, here is the code I'm using var setTexture = function(material, texture){ material.map = new THREE.TextureLoader().load(texture.map); console.log('test') } // setTexture(sphere.material[0], textures[1]); tl.call(setTexture, [sphere.material[0], textures[1]], "1") tl.fromTo(sphere.material[0].map.offset, {y:-1},{y:1, duration:2}, "2"); tl.fromTo(sphere.material[2].map.offset, {y:-1},{y:1, duration:8}, "10"); tl.fromTo(sphere.material[1].map.offset, {y:-1},{y:1, duration:8}, "11"); tl.fromTo(sphere.material[3].map.offset, {y:-1},{y:1, duration:8}, "13"); tl.fromTo(sphere.material[0].map.offset, {y:-1},{y:1, duration:8}, "16"); Many thanks for you help !! B Link to comment Share on other sites More sharing options...
Solution GreenSock Posted February 5, 2023 Solution Share Posted February 5, 2023 Without a minimal demo, it's tough to diagnose but it kinda sounds to me like you might be expecting targets to get dynamically swapped out or something. You're setting up your tweens to reference the "offset" of a specific object that's stored in an Array, and then you think that putting a new object in that spot in the Array will somehow also change all the references to that original object, but that's not how JavaScript works. A simplified version: let textures = [texture1]; gsap.to(textures[0], {x: 100}); textures[0] = texture2; // which texture's x will animate to 100? So I think you're just facing a fundamental JavaScript referencing issue, unrelated to GSAP. The "offset" object you're tweening remains fixed even though you're loading a new "map". That new "map" has a completely different "offset" object I'd guess. 1 Link to comment Share on other sites More sharing options...
benoit958 Posted February 5, 2023 Author Share Posted February 5, 2023 Thank you for your reply, Sorry, my code is a bit confusing. texture.map is a url. It's not a js object. Again, if I'm doing this manually, my texture is well replaced without changing the object’s material offset and I’m still able to animate it. material.map = new THREE.TextureLoader().load('myurl'); But when I'm doing it using a callback with .call or .add my material’s offset is not animated anymore. This is the exact same method just not triggers by a timeline object.. I’m going to do a codepen example. Link to comment Share on other sites More sharing options...
GreenSock Posted February 5, 2023 Share Posted February 5, 2023 7 minutes ago, benoit958 said: I’m going to do a codepen example. Yeah, that'll be super helpful. The simpler the better. No need to have 7 different tweens. Only the absolutely essential parts to clearly illustrate the issue. I'm sure it'll become clear once we see the minimal demo. 👍 Link to comment Share on other sites More sharing options...
benoit958 Posted February 5, 2023 Author Share Posted February 5, 2023 Here is a codepen See the Pen oNMVpGw by mi-re (@mi-re) on CodePen Actually, while I was doing it I get what you meant (and feel a bit stupid of my mistake 😂 ) I guess I need to find a way to switch my texture image’s property and not the entire “map” object to keep reference to the offset “y” property right ? Link to comment Share on other sites More sharing options...
GreenSock Posted February 6, 2023 Share Posted February 6, 2023 5 hours ago, benoit958 said: Actually, while I was doing it I get what you meant (and feel a bit stupid of my mistake 😂 ) No worries. We've all been there. Actually, there are many ways to accomplish this. Here's one: See the Pen qByvKjK?editors=0010 by GreenSock (@GreenSock) on CodePen Basically just re-create your timeline and skip to the appropriate progress so that it appears seamless. Another way to do it is to use a proxy object (a generic object that's solely for the purpose of holding the properties you want to tween), and then apply them in an onUpdate to the actual material.map.offset. I hope that helps! 1 1 Link to comment Share on other sites More sharing options...
benoit958 Posted February 6, 2023 Author Share Posted February 6, 2023 Many thanks, what I’ve ended up with is to store the offset property and re-apply it to the map object, right after texture swap. Works well that way. Thanks for the example and explanation See the Pen xxJByjz by mi-re (@mi-re) on CodePen 1 Link to comment Share on other sites More sharing options...
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