Jump to content

paulorero last won the day on June 21 2020

paulorero had the most liked content!


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by paulorero

  1. To bring this thread to an end. I made your code @Rodrigo to work with functional components without killing the tween on prop caused re-renders.. https://stackblitz.com/edit/gsap-react-stop-wheel-cl3pqo In order to use dynamically updating props in the spinning Tween, I used React.useRef to save those values. Refs dont trigger rerender and therefor the tween won't be killed and reinitialized or something. They can be used in the useEffect hook without it running again. React.useEffect(() => { if (typeof stopAt !== "number") return; stopAtRef.current = stopAt; }, [stopAt]); onComplete: () => { console.log("onComplete", { stopAt, stopAtRef: stopAtRef.current }); // The stop position can be checked on every tween iteration without useEffect running again if (loopIterationRef.current >= 2 && typeof stopAtRef.current === "number") { spinTweenRef.current.timeScale(0); gsap.to(wheelRef.current, { rotation: `+=${stopAtRef.current + 360}`, duration: (1.8 * (stopAtRef.current + 360)) / 360, onComplete: () => { setSpinning(false); if (onStopSpinning) { onStopSpinning(); } }, }); } else { loopIterationRef.current++; spinTweenRef.current.play(0); } }; I really appreciate your help. This forum and gsap are just great.
  2. Yes good point. But in this case it's really secondary and I implemented it just to disable some buttons while spinning
  3. I made the stop position customizable and pass it into the wheel componenent. There I moved away from the infinite spinning with onRepeat and used onComplete to check each time if it's time to stop. It kinda works and the correct stop position is guaranteed. What is your oppinion to this approach? https://stackblitz.com/edit/gsap-react-stop-wheel-vyxgea Now all the tweens are inside componentDidMount() - is this the way to go? How would you implement a reset feature e.g. after the wheel stopped, one can play it again.
  4. This looks great at first glance! I'll have a look to the whole stopping angle stuff. You used the timescale technice which is a bit tricky for stopping at a specific angle that's why I used different tweens in the first place. Will come back soon to this thread. Thank you!!
  5. I tried a lot but anything will result in a rerender of the component which will kill the animation... Is it possible to use the same timeline/tween at the same "play head" after a rerender happened? I see no way to achieve this. Can't imagine I'm the only one with this problem. How would you handle this in a class component? I dont see a way to do it either. thx
  6. I dont really get how this whole GSAP instance inside useState should work when we initiate them inside a useEffect. How do you suggest the dynamic props are passed into the instance? In this Pen I added the instances into react useState. It's not working because they are not added into the dependency array. When I do it also fails. https://codepen.io/paulborm/pen/YzwGgMw Timescale does not work in this case because the wheel must stop at an asynchronus point.
  7. I agree with you. Unfortunately I am not able to use a class component in this case. Adding the GSAP instances into the state doesn't really work for me (maybe I did something wrong). Setting tweens which include the dynamic props, requires the useEffect to include them in it's dependency array. Which then leads to a lot of rerenders, calulation and loops. const [spinning, setSpinning] = React.useState(false); const [stopTween, setStopTween] = React.useState(null); const [startTween, setStartTween] = React.useState(null); const [loopTween, setLoopTween] = React.useState(null); const circleRef = React.useRef(null); const loopIteration = React.useRef(0); const stopRotation = 360 + stopAt; const handleStartSpinning = () => { setSpinning(true); }; React.useEffect(() => { setStopTween( gsap.to(circleRef.current, { rotation: `+=${stopRotation}`, // Calculate the new duration ... // ... to make the transition between spinning and ... // ... stopping as smooth as possible. duration: stopRotation / 360, paused: true, }) ); }, [stopRotation]); React.useEffect(() => { setLoopTween( gsap.to(circleRef.current, { rotation: "+=360", ease: "none", duration: 0.5, onComplete: () => { // The props won't update in here... if ( loopIteration.current >= fullSpins && typeof stopAt === "number" ) { stopTween.play(); } else { loopIteration.current++; loopTween.play(0); } }, paused: true, }) ); }, [stopTween, loopTween, fullSpins, stopAt]); React.useEffect(() => { setStartTween( gsap.to(circleRef.current, { rotation: "+=360", ease: "power1.in", duration: 1, onComplete: () => loopTween.play(), paused: true, }) ); }, [loopTween]); React.useEffect(() => { if (spinning) { startTween.play(); } }, [spinning, startTween]);
  8. With this solution the wheel won't stop smoothly as it is supposed to be. The wheel needs to start spinning, spin infite until it gets a stop position and then stop smoothly on the provided position. Just like this but in React: https://codepen.io/paulborm/pen/XWmygvB
  9. Hi there, TL;DR How to prevent the gsap animations to be aborted in react because of a rerender/prop change How to use dynamic props/state inside a gsap tween without beeing interrupted I'm building a spinng wheel with dynamic start- and end-points. You guys already helped me a lot with this: Now I need to implement this into an acutal react application. The biggest problem is, that I use dynamic Properties inside my gsap tweens to calculate e.g. the stop position or when to stop animation. React rerenders my component and aborts the whole animation as soon as a property changes. Of course react should do that - but how to I keep my animation running? What my code should do: start spinning by clicking the "Start Spinning" Button Wheel is spinning infinite Stop wheel by clicking the "Stop Spinning" Button Wheel at least the minimum amount (5) and then stops at the set position What my code actually does: start spinning by clicking the "Start Spinning" Button Wheel is spinning infinite Clicking "Stop Spinning" does not work -> triggers in my local invironment a rerender and aborts the animation in codepen it flickers and then nothing happens (the stop position is never passed into the tween) ... In the codepen it actually does not rerender but the updated prop won't be passed into the tween. const loopAnim = gsap.to(circleRef.current, { rotation: "+=360", ease: "none", duration: 0.5, onComplete: () => { // The props won't update in here... if (loopIteration.current >= fullSpins && typeof stopAt === "number") { stopAnim.play(); } else { loopIteration.current++; loopAnim.play(0); }, paused: true });
  10. Calculating the duration based on the stop position seems to work okay for now. https://codepen.io/paulborm/pen/XWmygvB Thank you very much!
  11. Hi ZachSaucier, thank you for your answer Something like that also was my first try. I like your solution because the start and loop phase blend nicely. The end phase how ever is not as smooth because the tween needs to travel more distance in a fixed duration... Is there a way to combine these two approaches (using timeScale, using multiple tweens in timeline)? My goal would be an dynamic animation like the example using `timeScale`. But I have no idea how to achieve something like this. It would be cool if we could just append the final rotation onto the tween in the "pause" event handler. var rotateCD, pauseTween, playBtn = document.getElementById("play"), pauseBtn = document.getElementById("pause"), audio = document.createElement("audio"); rotateCD = gsap .to("#creature", { rotation: 360, duration:0.3, ease: 'none', repeat: -1, paused: true }) .timeScale(0); play.onclick = function() { rotateCD.play(); gsap.to(rotateCD, {timeScale: 1, duration:3}); }; pause.onclick = function() { // Adding the final rotation here would be ideal gsap.to(rotateCD, { rotation: 36, timeScale: 0, duration:3, onComplete: function() { this.pause(); }}); };
  12. Hi there, I want to create an animated wheel which starts at a specific degree and ends at a specific degree. Until it's requested to stop/pause it needs to spin infinite. So basically there are three stages "starting", "spinning", "stopping". The difficult task is to start and stop spinning with some momentum to feel natural. I have found multiple very helpful forum posts about that topic. They all stop at a random degree. Especially this seams to be a very similar problem but the solution is missing the momentum at start and stop position. Thanks in advance