RickGove Posted August 9, 2020 Share Posted August 9, 2020 Using React, I have added GSAP to two apps within one website. This is deployed to both GitHub Pages, and Netlify. While working great on my npm localhost, all the animations run when the page is first loaded, not when the component is scrolled into view, as it does on my LocalHost... import React from 'react'; import { GlobalStyle } from './GlobalStyle'; import HeaderDeterminer from './header/HeaderDeterminer'; import ScrollToTop from './scrollToTop/'; import About from './about/'; import Contact from './contact/'; import Tools from './tools/'; import Projects from './projects/Projects'; import Footer from './footer/'; class App extends React.Component { render() { return ( <React.Fragment> <GlobalStyle /> <HeaderDeterminer /> <ScrollToTop /> <About /> <Contact /> <Tools id="Tools" /> <Projects /> <Footer /> </React.Fragment> ); } } export default App; About, Contact, and Tools all have GSAP animation and are use ScrollToggle here they are: ABOUT: import React, { useEffect } from 'react'; import { gsap } from 'gsap'; import ScrollTrigger from 'gsap/ScrollTrigger'; import { ShowSubhead, ShowCaseCon, ShowH1, ShowImg, AboutTitle, AboutWPDiv, } from './AboutStyle'; import MoreInfo from '../MoreInfo/'; import FindOutMore from '../FindOutMore/'; import meA from '../../img/RBG.jpg'; function ShowCase() { useEffect(() => { gsap.registerPlugin(ScrollTrigger); const tl = gsap.timeline({ scrollTrigger: { trigger: '.triggerAbout', toggleActions: 'play reset play reset', start: -600, }, }); const delay = 2; const stagger = 0.5; tl.from('.anName', { duration: delay, opacity: 0, x: -1000, ease: 'power4', }); tl.from('.anB', { duration: delay / 2, opacity: 0, y: -100, stagger: stagger, ease: 'bounce', }); tl.from('.anSub', { duration: delay / 2, opacity: 0, y: -100, ease: 'bounce', }); tl.from('.anC', { y: -100, duration: delay, opacity: 0, ease: 'power3', }); return function () { tl.kill(); }; }); return ( <AboutWPDiv> <div classname="triggerAbout" /> <ShowCaseCon id="About"> <AboutTitle> <div className="anName"> <ShowH1>Hi, I'm Rick Gove</ShowH1> </div> </AboutTitle> <div className="anB"> <ShowImg src={meA}></ShowImg> </div> <ShowSubhead className="anSub">Junior Web Developer</ShowSubhead> <div> <FindOutMore /> <MoreInfo /> </div> </ShowCaseCon> </AboutWPDiv> ); } export default ShowCase; Contact: import React, { useEffect } from 'react'; import gsap from 'gsap'; import ScrollTrigger from 'gsap/ScrollTrigger'; import { ContactCon, ContactDiv, ContactA, EmailImg } from './ContactStyle'; import { ShowH1 } from '../about/AboutStyle'; import email from '../../img/logo_email.png'; import linked from '../../img/logo_linked.png'; import leet from '../../img/logo_leet.png'; import logoGit from '../../img/logo_github.png'; // import facebook from '../../img/logo_facebook.png'; import twitter from '../../img/logo_twitter.png'; export default function () { const st = { trigger: '.trigger', start: 'top 50%', end: 'bottom 50%', toggleActions: 'play reverse play reverse', }; useEffect(() => { window.addEventListener('scroll', checkIfViewed); checkIfViewed(); gsap.registerPlugin(ScrollTrigger); gsap.from('.anImg', { opacity: 0, x: -1000, top: -500, endTrigger: 200, stagger: 0.2, duration: 1.5, rotate: 360, ease: 'power4', scrollTrigger: st, }); gsap.from('.anTitleCont', { opacity: 0, x: -1000, duration: 1, ease: 'power4', scrollTrigger: st, }); }); function checkIfViewed() { // Get the current component let comp = document.getElementById('Contact'); if (comp !== null) { // Get it's position in the viewport let bounding = comp.getBoundingClientRect(); if (bounding.top <= 0 && bounding.top >= ~bounding.height) { } else { } } } return ( <ContactCon id="Contact"> <div className="trigger" /> <ContactDiv> <div className="anTitleCont"> <ShowH1 col="white">Contact Me</ShowH1> <br /> </div> <div className="anImg"> <ContactA href="https://github.com/RickGove"> <EmailImg src={logoGit} /> </ContactA> </div> <div className="anImg"> <ContactA href="https://leetcode.com/rickbgove/"> <EmailImg src={leet} /> </ContactA> </div> <div className="anImg"> <ContactA href="mailto:rick.gove.developer@gmail.com"> <EmailImg src={email} /> </ContactA> </div> <div className="anImg"> <ContactA href="http://www.linkedin.com/in/richard-gove-developer"> <EmailImg src={linked} /> </ContactA> </div> {/* <div className="anImg"> <ContactA href="FaceBook"> <EmailImg src={facebook} /> </ContactA> </div> */} <div className="anImg"> <ContactA href="https://twitter.com/@gove_rick"> <EmailImg src={twitter} /> </ContactA> </div> </ContactDiv> </ContactCon> ); } and Tools: import React, { useEffect } from 'react'; import gsap from 'gsap'; import ScrollTrigger from 'gsap/ScrollTrigger'; import { Container } from '../GlobalStyle'; import { Box, BoxImg, BoxCon, BoxGrid, H3Box, PBox, ToolsTitle, } from './ToolsStyle'; import { tools } from '../data/Data'; import { ShowH1 } from '../about/AboutStyle'; import logoTool from '../../img/logo_tools.png'; export default function Boxes() { const stTools = { trigger: '.anTitleTools', start: 'top 50%', end: 'bottom 100%', endTrigger: '.toolsTriggerEnd', toggleActions: 'play reverse play reverse', }; useEffect(() => { gsap.registerPlugin(ScrollTrigger); gsap.from('.anTool', { opacity: 0, scale: 0, endTrigger: 200, stagger: 0.4, duration: 1.5, pin: true, ease: 'slow', scrollTrigger: stTools, }); gsap.from('.anTitleTools', { opacity: 0, scale: 0, ease: 'power4', duration: 2, scrollTrigger: stTools, }); }); function renderTools() { const colors = [ '#778beb', '#786fa6', '#303952', '#e15f41', '#596275', '#f5cd79', ]; return tools.map((tool) => { let last = ''; let randomColor = colors[Math.round(Math.random() * (colors.length - 1))]; if (last === randomColor) { randomColor = colors[Math.round(Math.random() * (colors.length - 1))]; } else { last = randomColor; } return ( <Box key={tool.name} bg={randomColor} id={tool.name}> <BoxImg src={tool.logo} /> <H3Box>{tool.name}</H3Box> <PBox>{tool.Description}</PBox> </Box> ); }); } return ( <BoxCon id="Tools"> <Container> <ToolsTitle> <ShowH1 col="black"> <div className="anTitleTools"> <BoxImg src={logoTool} r="30px" sz="45px" /> Tools </div> </ShowH1> </ToolsTitle> <BoxGrid className="anTool" id="BoxGrid"> {renderTools()} </BoxGrid> <div className="toolsTriggerEnd" /> </Container> </BoxCon> ); } And a similar issue is happening on a second app where two components are loaded into one page, but only the first component is animating. I had previously only deployed it to: rickgove.github.io But I signed up for Netlify when it didn't work just to see if it was a GitHub pages issue. It is equally not working on both. http://rickgove.github.io/ and https://adoring-murdock-e54ed4.netlify.app/#/ both behave in the same way Maybe it's something wrong with my ScrollTrigger code? I'm not sure Link to comment Share on other sites More sharing options...
Ihatetomatoes Posted August 9, 2020 Share Posted August 9, 2020 Hi Rick, I don't see much wrong with your ScrollTrigger but you are not using useRef to target your elements, which I think might be the issue. This guide might help: https://ihatetomatoes.net/react-and-greensock-tutorial-for-beginners/ Once you update your code to use useRef it would be great if you create a demo using https://codesandbox.io/ That way we can see if/what is wrong with your GSAP or ScrollTrigger code. 2 Link to comment Share on other sites More sharing options...
RickGove Posted August 10, 2020 Author Share Posted August 10, 2020 Thank you. I have updated the code. Unfortunately, I can't run CodePen on this machine. It's very old and slow. Here is my new code, and the same things are happening. export default function Contact () { const anImg = useRef(), anTitleCont = useRef(); const st = { trigger: '.trigger', start: 'top 50%', end: '70% 50%', toggleActions: 'play reverse play reverse', }; useEffect(() => { gsap.registerPlugin(ScrollTrigger); gsap.from('.anImg', { opacity: 0, x: -1000, top: -500, stagger: 0.2, duration: 1.5, rotate: 360, ease: 'power4', scrollTrigger: st, }); gsap.from('.anTitleCont', { opacity: 0, x: -1000, duration: 1, ease: 'power4', scrollTrigger: st, }); },[]); return ( <ContactCon id="Contact"> <div className="trigger" /> <ContactDiv> <div ref={anTitleCont} className="anTitleCont"> <ShowH1 col="white">Contact Me</ShowH1> <br /> </div> <div ref={anImg} className="anImg"> <ContactA href="https://github.com/RickGove"> <EmailImg src={logoGit} /> </ContactA> </div> <div ref={anImg} className="anImg"> <ContactA href="https://leetcode.com/rickbgove/"> <EmailImg src={leet} /> </ContactA> </div> <div ref={anImg} className="anImg"> <ContactA href="mailto:rick.gove.developer@gmail.com"> <EmailImg src={email} /> </ContactA> </div> <div ref={anImg} className="anImg"> <ContactA href="http://www.linkedin.com/in/richard-gove-developer"> <EmailImg src={linked} /> </ContactA> </div> {/* <div className="anImg"> <ContactA href="FaceBook"> <EmailImg src={facebook} /> </ContactA> </div> */} <div className="anImg"> <ContactA href="https://twitter.com/@gove_rick"> <EmailImg src={twitter} /> </ContactA> </div> </ContactDiv> </ContactCon> ); } import React, { useEffect, useRef } from 'react'; import gsap from 'gsap'; import ScrollTrigger from 'gsap/ScrollTrigger'; import { Container } from '../GlobalStyle'; import { Box, BoxImg, BoxCon, BoxGrid, H3Box, PBox, ToolsTitle, } from './ToolsStyle'; import { tools } from '../data/Data'; import { ShowH1 } from '../about/AboutStyle'; import logoTool from '../../img/logo_tools.png'; export default function Boxes() { const anTool = useRef(), anTitleTools = useRef(), triggerTools = useRef(), toolsTriggerEnd = useRef(); useEffect(() => { const stTools = { trigger: triggerTools.current, start: 'top 50%', end: 'bottom 60%', endTrigger: toolsTriggerEnd.current, toggleActions: 'play reverse play reverse', }; gsap.registerPlugin(ScrollTrigger); gsap.from(anTool.current, { opacity: 0, scale: 0, stagger: 0.4, duration: 1.5, ease: 'slow', scrollTrigger: stTools, }); gsap.from(anTitleTools.current, { opacity: 0, scale: 0, ease: 'power4', duration: 2, scrollTrigger: stTools, }); }, []); function renderTools() { const colors = [ '#778beb', '#786fa6', '#303952', '#e15f41', '#596275', '#f5cd79', ]; return tools.map((tool) => { let last = ''; let randomColor = colors[Math.round(Math.random() * (colors.length - 1))]; if (last === randomColor) { randomColor = colors[Math.round(Math.random() * (colors.length - 1))]; } else { last = randomColor; } return ( <Box key={tool.name} bg={randomColor} id={tool.name}> <BoxImg src={tool.logo} /> <H3Box>{tool.name}</H3Box> <PBox>{tool.Description}</PBox> </Box> ); }); } return ( <BoxCon id="Tools"> <div ref={triggerTools} /> <Container> <ToolsTitle> <ShowH1 col="black"> <div ref={anTitleTools} className="anTitleTools"> <BoxImg src={logoTool} r="30px" sz="45px" /> Tools </div> </ShowH1> </ToolsTitle> <BoxGrid ref={anTool} className="anTool" id="BoxGrid"> {renderTools()} </BoxGrid> <div ref={toolsTriggerEnd} className="toolsTriggerEnd" /> </Container> </BoxCon> ); } import React, { useEffect, useRef } from 'react'; import { gsap } from 'gsap'; import { ShowSubhead, ShowCaseCon, ShowH1, ShowImg, AboutTitle, AboutWPDiv, } from './AboutStyle'; import MoreInfo from '../MoreInfo/'; import FindOutMore from '../FindOutMore/'; import meA from '../../img/RBG.jpg'; function ShowCase() { const triggerAbout = useRef(), anName = useRef(), anSub = useRef(), anB = useRef(); useEffect(() => { const tl = gsap.timeline(); const delay = 2; const stagger = 0.5; tl.from(anName.current, { duration: delay, opacity: 0, x: -1000, ease: 'power4', }); tl.from(anB.current, { duration: delay / 2, opacity: 0, y: -100, stagger: stagger, ease: 'bounce', }); tl.from(anSub.current, { duration: delay / 2, opacity: 0, y: -100, ease: 'bounce', }); return function () { tl.kill(); }; }, []); return ( <AboutWPDiv> <div ref={triggerAbout} className="triggerAbout" /> <ShowCaseCon id="About"> <AboutTitle> <div ref={anName} className="anName"> <ShowH1>Hi, I'm Rick Gove</ShowH1> </div> </AboutTitle> <div ref={anB} className="anB"> <ShowImg src={meA}></ShowImg> </div> <ShowSubhead ref={anSub} className="anSub"> Junior Web Developer </ShowSubhead> <div> <FindOutMore /> <MoreInfo /> </div> </ShowCaseCon> </AboutWPDiv> ); } export default ShowCase; Link to comment Share on other sites More sharing options...
RickGove Posted August 10, 2020 Author Share Posted August 10, 2020 Okay, I've managed to get a codepen up and running: See the Pen RwaPmrQ?editors=0010 by rickgove (@rickgove) on CodePen I'm also going to npm run build this single file version and deploy it and see what happens. Link to comment Share on other sites More sharing options...
Ihatetomatoes Posted August 10, 2020 Share Posted August 10, 2020 Thanks for putting together the Codepen. I am getting this error: Uncaught SyntaxError: Unexpected token '<' There seems to be an issue with your syntax. I am short on time now to find the typo or the unclosed tag. Make sure your codepen works without gsap first, then we can help with any gsap related issues. 1 Link to comment Share on other sites More sharing options...
ZachSaucier Posted August 10, 2020 Share Posted August 10, 2020 Also please strip out everything unrelated to the issue being asked about. The video in the thread below goes into more detail about how to do that. Link to comment Share on other sites More sharing options...
RickGove Posted August 10, 2020 Author Share Posted August 10, 2020 Thank you, I see this error too now, not sure what it is. However, when I deploy the codepen to my GitHub pages site, all the animations work great. Do you have any idea what could be causing this issue on the bigger page? I am using: react-router (hashrouter) Redux would any of these things cause such odd behaviors? I am going to rebuild it tomorrow component by component and try and make it all work, thanks for your time, but it's definitely something on my side. 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