Jump to content
GreenSock

Enrypase

Members
  • Posts

    6
  • Joined

  • Last visited

Enrypase's Achievements

  1. I'm posting the final code down here: function BackgroundCloud(props){ // Current element let thisEl // Refreshes the component let isLoaded = useContext(props.pageLoaded) // Maxiumum left attribute that the cloud must reach & animation const maxLeft = useRef(0) const animation = useRef([]) function updateWindow(evt){ // If it is the first execution update the left parameter and set currentHeight & currentWidth if(!evt){ resetComponent() } // --> This code must be executed in both vertical and horizontal resize <-- maxLeft.current = 2 * thisEl.width() + $(window).width() // Adapting cloud to new top const parent = thisEl.parent().parent().parent() const fromTop = parent.offset().top const parentDistance = fromTop + parent.height() / 2 let top = props.top if(top.includes("vh")){ top = top.replace("vh", "") top = top * 0.01 top = $(window).height() * top }else if(top.includes("px")){ top = top.replace("px", "") } thisEl.css("--top", String(parentDistance + top).concat("px")) // Delete every ongoing animation killAnimation() // Create a new animation animation.current.push(gsap.to(thisEl, {left: maxLeft.current, duration: props.duration, ease: Linear.easeNone, onComplete: resetComponent})) } // Delete every ongoin animation function killAnimation(){ for(let i = 0; i < animation.current.length; i++){ animation.current[i].kill() } animation.current = [] } // Exec when the site is loaded/the component refreshed useEffect(() => { if(isLoaded){ updateWindow() $(window).on("resize", updateWindow) } }, []) // Reset a cloud (called when the component reaches the end) function resetComponent(){ thisEl = $(`#${props.propId}`) thisEl.css("left", -2 * thisEl.width()) killAnimation() animation.current.push(gsap.to(thisEl, {left: maxLeft.current, duration: props.duration, ease: Linear.easeNone, delay: props.delay, onComplete: resetComponent})) } // Return default cloud return( <div className="backgroundCloudContainer"> <img src={props.background} className="backgroundCloud" id={props.propId} draggable="false" alt={props.propId} style={{ "--z-index": props.zIndex, "--top": props.top, "--scale": props.scale }}/> </div> ) } To fix the problem I did the following things: 1) Using an array to store every animation I create (so I can .kill() everything) 2) Using useRef() instead of saving data in plain variables 3) Fixed the event listeners because I inserted the jquery .off() method that removes every listener from the element that, of course, made my solution not working Now I'm planning to remove the array and setting overwrite to "auto" or true so I'll save a piece of performance. Anyway, thanks for helping me. Hope that the problem I had will help someone else : D
  2. I did not include a demo because it worked perfectly in that... Anyways, I figured out the problem, and was *not* about gsap. Would be helpful to describe it and write the solution even if was because external to gsap?
  3. Before trying those things together, I noticed that React calls multiple times my function, so, is enabling overwriting a good way for "skipping" some problems? And is gsap.defaults({overwrite: "auto"}); a good way for enabling it? (From: )
  4. My goal is to update an animation on a window resize event So I thought the easiest way was to delete the animation with .kill() and to create a new one with the updated variable
  5. I create my first animation in of updateWindow() else{ animation = gsap.to(thisEl, {left: maxLeft, duration: props.duration, ease: Linear.easeNone, repeat: -1, delay: props.delay}) } This is just a piece of all the code. I'll try right now to provide a codePen [EDIT:] In the meanwhile I'll share all the component code down here, maybe it helps... import React, {useEffect, useContext} from "react" import {gsap, Linear} from "gsap" import $ from "jquery" import "../style/backgroundCloud.css" function BackgroundCloud(props){ // Current element let thisEl // Refreshes the component let isLoaded = useContext(props.pageLoaded) // Maxiumum left attribute that the cloud must reach & animation let maxLeft, animation function updateWindow(evt){ // If it is the first execution update the left parameter and set currentHeight & currentWidth if(!evt){ thisEl = $(`#${props.propId}`) thisEl.css("left", -2 * thisEl.width()) } // --> This code must be executed in both vertical and horizontal resize <-- maxLeft = 2 * thisEl.width() + $(window).width() // Adapting cloud to new top const parent = thisEl.parent().parent().parent() const fromTop = parent.offset().top const parentDistance = fromTop + parent.height() / 2 let top = props.top if(top.includes("vh")){ top = top.replace("vh", "") top = top * 0.01 top = $(window).height() * top }else if(top.includes("px")){ top = top.replace("px", "") } thisEl.css("--top", String(parentDistance + top).concat("px")) if(evt){ animation.kill() animation = gsap.to(thisEl, {left: maxLeft, duration: props.duration, ease: Linear.easeNone, repeat: -1, delay: props.delay}) }else{ animation = gsap.to(thisEl, {left: maxLeft, duration: props.duration, ease: Linear.easeNone, repeat: -1, delay: props.delay}) } } // Exec when the site is loaded/the component refreshed useEffect(() => { if(isLoaded){ updateWindow() $(window).off().on("resize", updateWindow) } }, []) function killComponent(){ if(animation){ animation.kill() } } // Return default cloud return( <div className="backgroundCloudContainer"> <img src={props.background} className="backgroundCloud" id={props.propId} draggable="false" alt={props.propId} style={{ "--z-index": props.zIndex, "--top": props.top, "--scale": props.scale }}/> <button onClick={killComponent}>CLICK</button> </div> ) } export default BackgroundCloud I'm trying to replicate the same situation in JS but everything works fine. So, maybe, the problem is with React
  6. Hi everybody, I have the following problem: it seems like I can't kill the animations. I have this animation: gsap.to(thisEl, {left: maxLeft, duration: props.duration, ease: Linear.easeNone, repeat: -1, delay: props.delay}) Googling I found out that I can't update the variables once the animation is started. So i thouht that a good idea was to delete/kill the animation and starting a new one with the updated value. The code is the following: // Maxiumum left attribute that the cloud must reach & animation let maxLeft, animation // This funcion is executed on window resize (evt != null) and for the first time the program is executed (evt === undefined) function updateWindow(evt){ // If it is the first execution update the left parameter and set currentHeight & currentWidth if(!evt){ thisEl = $(`#${props.propId}`) thisEl.css("left", -2 * thisEl.width()) } // Updating the variable maxLeft = 2 * thisEl.width() + $(window).width() // If the resize event occurs, delete the animation and start a new one if(evt){ animation.kill() animation = gsap.to(thisEl, {left: maxLeft, duration: props.duration, ease: Linear.easeNone, repeat: -1, delay: props.delay}) } // If this is the first execution start the first animation else{ animation = gsap.to(thisEl, {left: maxLeft, duration: props.duration, ease: Linear.easeNone, repeat: -1, delay: props.delay}) } } function stopAnimation(){ animation.kill() } /* Other code... */ <button onClick={stopAnimation}>CLICK</button> So, it seems like the animation.kill() inside updateWindow() does not work. And the animation.kill() that is executed when the button is clicked does not work either. (The animation still being executed) Thanks in advance :D
×