Jump to content


  • Posts

  • Joined

  • Last visited

Everything posted by danboyle8637

  1. Is there anyway we can get access to the value of the drawsvg while it's tweening? I didn't see anything in the docs... other than the live attribute which made me think it might be possible.
  2. @Rodrigo Thanks, but I think I have this working. At least on my code sandbox project. I am going to be testing it on my dev site and across browsers to see what happens but I am not losing any animation performance when my SVG gets triggered by the intersection observer. The short of it was I think two things. One... I have an "exit" animation that's slightly different so when the SVG goes out of the root, it runs that animation. Then when it comes back into the root, it runs the "original" animation. Two... I am using state to trigger the animation running. I'm not sure if my thought process is correct, but because I'm triggering a rerender of the component and the animation is changing, I'm getting a new instance of the animation. I think that thought process of what react is doing is correct. Anyway, after I test it some more, I'll report back.
  3. Thanks! As I was researching the best ways to do scroll animations... that's when I learned about intersection observer. And for performance reasons, "they" said to stay away from scroll events because the window is constantly listening even when the element is out of the viewport. My needs are pretty small... I think. The most animations I have are on a page where I have small benefit paragraphs with a SVG icon. I wanted to animate these icons on scroll. Some of them just for user experience (something cool)... some of them because they help show what the benefit paragraph is talking about... a little demo. I've used scroll magic in the past and it seems to work fine, but I feel like I always need to be on the bleeding of performance and page speed. Thanks for the demos. I'll have to dig into the moon landing one for sure.
  4. @Rodrigo @mikel Not sure... I changed my code sandbox and moved the animation to the SVG component. https://codesandbox.io/embed/intersection-observer-svg-tweenmax-u6ief It works or at least seems to but if you scroll up and down the screen... you'll notice the animation starts to "die"... it moves less and less each time. But the isIntersecting property still fires correctly. I've tried it will TweenMax and TimelineMax but they both do the same thing. I wanted to use Intersection Observer because it's performant... and I don't think ScrollMagic uses it... it still listens to scroll events... I think. Is ScrollMagic still the best option for scroll based animations?
  5. Nevermind. I'm still getting some strange behavior with the animation. I must be a react thing. I'll update my example once I run through a few ideas. I also look at this tutorial again which helped. https://medium.com/the-non-traditional-developer/how-to-use-an-intersectionobserver-in-a-react-hook-9fb061ac6cb5 A little confused on how a state change is handled from within a ref... but that's a react thing. But by returning the entry that's being observed... and then using the isIntersecting property... you can trigger the animations and it does work. Now I need to test it with 10 or more observers on one page! Thanks! @mikel Thanks too for you pen. I like to see all these examples.
  6. I asked a question about intersection observer here: I wanted to update because I got my intersection observer working. I set it up as a hook to watch DOM elements you pass in from any given React component. I found a three year old post saying that Intersection Observer has issues with SVG. And through experimenting, I found you can only observe the top level <svg> element. But through observing the <svg> as a whole, you can still pass a reference through to my observer hook to trigger an animation. In this codesandbox: https://codesandbox.io/embed/intersection-observer-svg-tweenmax-u6ief When you scroll down, you can see the little compass icon starts animating when it hits 200px from the bottom of the view port. But when I scroll the icon off the screen and back on, I can't get my animation to replay. I am using a TweenMax but I have tried to use a timeline and that doesn't work either. I hope my code is followable.
  7. @Rodrigo Thanks!! I'll report back if I can get all of this working correctly.
  8. @ZachSaucier no nothing ill has happened yet. My only worry at this point is making sure I kill my tweens and timelines appropriately. For example... in a component, I might call a tween like this: const Component = () => { const nodeRef = useRef(null) useEffect(() => { // imported up above of course... compassIconAni(nodeRef.current) return () => { // import TweenMax above // Does this kill the tween even through the actual Tween // is located in another file? TweenMax.killTweensOf(nodeRef.current) } }, [nodeRef.current]) return // Stuff } I'm not sure if that call to killTweensOf() actually kills the tween. Is there a way to figure out for sure if a tween is "dead"? I didn't see anything in the docs.
  9. My question is more of a best practice question. I'm in a react app and right now, I'm defining all of my tweens as separate functions and importing them when needed. Is there any reason why "you" should not define Tweens in a separate file? I'm doing this because I plan on passing them to a Intersection Observer as the callback.
  10. @elegantseagulls Nice. Cleaning up the animations worked. Is it a good idea to always kill and/or destroy animations when unmounting a component? I'm guessing yes. Thank you for the help!
  11. @elegantseagulls Ahh.... great idea! Nice thank you I am going to try this first thing in the morning. It makes sense... I hope it works. I'll report back.
  12. No because I don't have any <def> tags in my SVG... I am going to build a CodeSandbox tonight. I only get the error when I navigate away from the page that uses DrawSVG. When I navigate to it... nothing. Here is an example of an arrow component I'm drawing... Maybe it's ScrollMagic messing things up? import React, { Component } from "react" import { TimelineMax, TweenMax } from "gsap" import ScrollMagic from "scrollmagic" import DrawSVG from "../greensock/DrawSVGPlugin" class SolidArrowDownTransition extends Component { constructor(props) { super(props) this.drawSVG = DrawSVG this.arrowBody = null this.arrowHead = null this.setArrowBodyRef = element => { this.arrowBody = element } this.setArrowHeadRef = element => { this.arrowHead = element } } componentDidMount() { const arrowTl = new TimelineMax() const controller = new ScrollMagic.Controller() TweenMax.set([this.arrowBody, this.arrowHead], { autoAlpha: 0 }) arrowTl.set([this.arrowBody, this.arrowHead], { autoAlpha: 1, drawSVG: "0%", }) arrowTl .to(this.arrowBody, 1, { drawSVG: "100%" }) .to(this.arrowHead, 0.6, { drawSVG: "100%" }, "-=0.3") const scene = new ScrollMagic.Scene({ triggerElement: this.arrowBody, triggerHook: 0.68, duration: 500, }).setTween(arrowTl) controller.addScene(scene) } render() { const { width, height, className } = this.props return ( <svg id="solid-arrow-down-transition" xmlns="http://www.w3.org/2000/svg" className={className} width={width} height={height} viewBox="0 0 70.9 249.25" > <path ref={this.setArrowHeadRef} id="arrow-head" d="M3.33 219.13l25.09 26.82 27.74-34.38" fill="none" stroke="#d7d7d7" strokeLinecap="round" strokeLinejoin="round" strokeWidth="6.62" /> <path ref={this.setArrowBodyRef} id="arrow-body" d="M21.05 3.31c14.79 10.05 28.19 22.65 36.87 38.28s12.32 34.51 7.55 51.74c-6.22 22.46-25.23 38.94-35.69 59.77a85.68 85.68 0 0 0-3.67 67.39" fill="none" stroke="#d7d7d7" strokeLinecap="round" strokeLinejoin="round" strokeWidth="6.62" /> </svg> ) } } export default SolidArrowDownTransition
  13. Sorry I mistyped above. I have not set display to none anywhere in my codebase. I only use opacity set to zero. And I just changed to autoAlpha so see if that made any difference. But I still get this error. I'll try to reproduce. I am using React if that makes any difference with drawSVG.
  14. Just wanted to check if anybody has seen this error in Firefox related to DrawSVG Error: Some browsers like Firefox won't report measurements of invisible elements (like display:none or masks inside defs). My SVGs are invisible in the sense of display none. I only have opacity set to zero and drawSVG: "0%" when I set up my Tweens. Anybody else seen this?
  15. @Jonathan Thanks. The useEffrect() method in the SVG component is the same - or is supposed to be - the same as componentDidMount() in a class based component. The helper functions I have in my component that create the animations are outside the useEffect() but I've put them in the useEffect() and I still get the Error. I'm not sure what's going on. If anybody else has info that would be great. I guess I'm just going to convert all of my animation components to class based components and see what happens.
  16. So I've read the other posts in the forum about how FireFox throws this NS_Error_Failure when an SVG is not mounted in the DOM... as I understand it, either with a display of none or visibility of 0. I'm building in React and I think I've isolated which SVG animation is giving me problems. I copied it to a codesandbox and it works on initial load. But if I refresh the codesandbox, I'll start to get it a lot. I'm not sure why. I don't mess with display or visibility. I do a lot of transforms. In my actual site, I use ScrollMagic but because I can replicate the error with this, I don't think that's the problem. Here's the link to the CodeSandbox just in case: https://codesandbox.io/s/dazzling-keller-r2p6g?fontsize=14
  17. Just a strange update... switched to class component and everything works perfect. One thing I tried was moving my instantiation of my timeline outside my functional component to see if it worked... it did work! But then the timing of the animations got all wonky. Sometimes they would be snappy... sometimes they would be super delayed even though I had no delay. I'll see if I can replicate on a CodeSandbox later... but I have to get this site DONE! Thanks for all the help!
  18. @Rodrigo Sweet thanks... I haven't gone through your answer yet. But just wanted to say thanks for the indepth answer too. I'll be pouring through it and playing with it tonight for sure.
  19. Thanks again. I'll keep messing with it. You did just give me an idea to try out. I have been re-writing my timelines without the add function. So do you pretty much only use add for function calls or labels then?
  20. Whoa! Didn't expect that. I don't know if I can do that in my site because with the tl outside the function... i think it might be global and then conflict with other tl's I've created... but then again since those are in functions themselves... maybe not. Thanks @PointC for your help so far. I tried console logging the tl object in each of my functions and it does log with the right data I set up so it does exist. I just don't understand...
  21. The brackets tell React to only run the code when the component initially mounts. So I figured that was the best time to set up the timeline. Without the brackets... the function run anytime the component re-renders. In this case that would be with every click of the toggle because it's changing the state of the form. In my demo... if I get rid of the brackets rather than reverse... it just jumps back.
  22. Sorry... let's try this one: https://codesandbox.io/s/184vowy7mj?fontsize=14
  23. Okay. I have been staring at this for a day now and it's possible I'm so fried I'm missing something... but... I'm using these toggles in a form to turn on and off certain questions. The form works and the toggles work but I can't get their animations to work. I linked to a CodeSandbox with a little example. In this example... I can toggle the switch on... but it won't reverse. I feel like I'm misusing Greensock someway. Below is also my SVG component in my actual website. I have commented out some code, but when I try to set the timeline in my initial useEffect call... and then I try to play or reverse it based on the click... nothing happens. If I put in console.log statements into the click handler... they are called correctly. If I just put in a TweenMax call into the click handler... the switches animate correctly. What am I missing? Here's the code and thanks! import React, { useRef, useEffect } from "react" import { TimelineMax, Power2, TweenMax } from "gsap" import { useFormStore } from "../context/FormContext" const FormToggleSwitch = ({ width, height, className, handleWebsiteClick, name, }) => { const [formState, dispatch] = useFormStore() const toggleSwitchRef = useRef(null) const tl = new TimelineMax({ paused: true }) useEffect(() => { tl.add( TweenMax.fromTo( toggleSwitchRef.current, 0.6, { x: 0, fill: "#F96666", }, { x: 36, ease: Power2.easeInOut, fill: "#54ba5e", } ), 0 ) }, []) if (formState.haveWebsite && name === "websiteToggle") { //console.log("go to green") tl.play() // TweenMax.to(toggleSwitchRef.current, 0.6, { // x: 36, // ease: Power2.easeInOut, // fill: "#54ba5e", // }) } else { tl.reverse() } if (formState.haveTimeline && name === "timelineToggle") { // console.log("go to red") tl.play() // TweenMax.to(toggleSwitchRef.current, 0.6, { // x: 0, // ease: Power2.easeInOut, // fill: "#F96666", // }) } else { tl.reverse() } return ( <svg id="toggle-switch" xmlns="http://www.w3.org/2000/svg" className={className} width={width} height={height} viewBox="0 0 70 34.48" onClick={handleWebsiteClick} > <g id="body"> <path d="M22.57 38a16.24 16.24 0 0 1 0-32.48h35.52a16.24 16.24 0 0 1 0 32.48z" transform="translate(-5.33 -4.54)" fill="#ebebeb" /> <path d="M58.09 6.54a15.24 15.24 0 0 1 0 30.48H22.57a15.24 15.24 0 0 1 0-30.48h35.52m0-2H22.57A17.24 17.24 0 0 0 5.33 21.78 17.24 17.24 0 0 0 22.57 39h35.52a17.24 17.24 0 0 0 17.24-17.22A17.24 17.24 0 0 0 58.09 4.54z" transform="translate(-5.33 -4.54)" fill="#d7d7d7" /> </g> <circle ref={toggleSwitchRef} cx="17.07" cy="17.24" r="12.93" fill="#f96666" id="switch" /> </svg> ) } export default FormToggleSwitch
  24. @GreenSock Cool... I did do that... but can I ask why you wrapped it in in array? I still can't get it working but I'll make a codesandbox in the next couple days. Thanks for your help!
  25. import React, { useEffect, useRef } from "react" import { TimelineMax, TweenMax } from "gsap" import MorphSVGPlugin from "../greensock/MorphSVGPlugin" import { useMenuOpenStore } from "../context/MenuOpenContext" const MenuIcon = ({ width, height, className }) => { // My state so I know when the menu is open and closed const [{ menuOpen }, dispatch] = useMenuOpenStore() // Initiallized timelinemax const tl = new TimelineMax({ paused: true }) // Setup refs to access the paths const topMenuBarRef = useRef(null) const middleMenuBarRef = useRef(null) const bottomMenuBarRef = useRef(null) const rightCloseRef = useRef(null) const leftCloseRef = useRef(null) useEffect(() => { tl.to(middleMenuBarRef.current, 0.3, { x: -60, autoAlpha: 0, }) .to(topMenuBarRef.current, 0.3, { morphSVG: leftCloseRef.current, }) .to(bottomMenuBarRef.current, 0.3, { morphSVG: rightCloseRef.current, }) }, []) useEffect(() => { if (menuOpen) { console.log("play") tl.play() } else { console.log("reverse") tl.reverse() } }) return ( <svg xmlns="http://www.w3.org/2000/svg" className={className} width={width} height={height} viewBox="0 0 194.27 162.68" > <g id="close-menu-icon" fill="#fff" stroke="#ebebeb" strokeLinecap="round" strokeMiterlimit="10" strokeWidth="24" > <path ref={rightCloseRef} id="right-cross" d="M28 150.68l59.83-59.83L166.68 12" /> <path ref={leftCloseRef} id="left-cross" d="M166.68 150.68l-59.83-59.83L28 12" /> </g> <g id="menu-icon" fill="#ebebeb" stroke="#ebebeb" strokeLinecap="round" strokeMiterlimit="10" strokeWidth="24" > <path ref={topMenuBarRef} id="top-menu-bar" d="M12 31.57h169.93" /> <path ref={middleMenuBarRef} id="middle-menu-bar" d="M71.95 81.28h110.32" /> <path ref={bottomMenuBarRef} id="bottom-menu-bar" d="M38.38 131h143.89" /> </g> </svg> ) } export default MenuIcon This is my component. It's a standalone SVG that changes based on my menu being open or closed. I don't use morphSVG in setting up the timeline. I import morphSVG based on the files location in my project. But I don't know how to get my app to know about it because it's not being used. Not sure if I need to do something with webpack.