Devotee007
Content Type
Profiles
Forums
Store
Blog
Product
Showcase
FAQ
Downloads
Posts posted by Devotee007
-
-
I'm trying to reverse a stagger, it works as it is now, but I want it to start from the "top" on the reverse. Not it's just reversing the animation. If that make sense?
//Devotee007See the Pen jORrMgN by Devotee007 (@Devotee007) on CodePen
-
Ah, ok, thanks for the info, I didn't know that about the helper function. The solution you did is what I'm looking for, thank you for the help!
//Devotee007
- 1
-
Thanks for the reply!
I tried it, but I get the same result after changing it to overflow:hidden. The scroll keeps on going but it doesn't repeat directly from the top, there's a long gap before the text starts over from the top. It should be on going without the gap. -
Hi,
I don't know what's wrong. No matter how many words I put in the scroll comes to an end. What have I missed?
//Devotee007See the Pen zYybRmx by Devotee007 (@Devotee007) on CodePen
-
I don't get why this text gets blurry and jmupy on scale. I have done this before without this problem. It seems I can't use willChange anymore. The animation won't work at all then. The font is thin I know, but I have tried with different fonts, same result. What am I missing?
See the Pen ZEVqobP by Devotee007 (@Devotee007) on CodePen
-
9 hours ago, GreenSock said:
There are other ways to do it too, like using CSS variables or a proxy object that animates a raw string and applies it in an onUpdate.
I would really appreciate if you could show me an example of this. -
Can I have more than one timline inside the same context?
-
Thank you!
-
Is it possible to animate to a value like the one below, I have searched but can't find any info about it.
border-radius: 0 0 70% 70%/0 0 35% 35%;
-
I got it to work now! Thanks @Cassie and @Rodrigo for the input and help!
Working code:
const mobileMenu = useRef<HTMLDivElement>(null); const menuTl = useRef<GSAPTimeline>(gsap.timeline()); const toggleMobileMenu = () => { if (menuTl.current !== null) { menuTl.current.reversed(!menuTl.current.reversed()); setTopMenuVisible(!activeMobileTopMenu); setActiveSubLevel(-1); setActiveSubSubLevel(-1); } }; useLayoutEffect(() => { const ctx = gsap.context(self => { menuTl.current = gsap.timeline({ paused: true }); menuTl.current.to( ".js-mobile-overlay", { // yPercent: 170, y: "85vh", ease: "expo.inOut", duration: 1.1 }, 0 ); menuTl.current.to( ".js-mobile-menu", { y: 0, ease: "expo.inOut", duration: 0.9 }, 0.1 ); menuTl.current.to( ".js-pie-top", { strokeDasharray: "0,100", autoRound: false, ease: "expo.in", duration: 0.5 }, 0.1 ); menuTl.current.to( ".js-pie-bottom", { strokeDasharray: "0,100", strokeDashoffset: "-25", autoRound: false, ease: "expo.in", duration: 0.5 }, 0.1 ); menuTl.current.to( ".menu-toggle-titles", { y: -14, ease: "power4.inOut", duration: 0.4 }, 0.5 ); menuTl.current .to( ".js-pie-middle", { rotation: 90, y: 8, x: -4, transformOrigin: "center", ease: "back.out(1.4)", duration: 0.5 }, 0.6 ) .reverse(); }, mobileMenu); return () => ctx.revert(); }, []);
- 2
-
Inside toggleMobileMenu I get error that
menuTl.current' is possibly 'undefined'
const toggleMobileMenu = () => { menuTl.current.reversed(!menuTl.current.reversed()); };
But inside the useLayOutEffect I don't get any warnings. I tried to add this to the const for menuTl
const menuTl = useRef<GSAPAnimation>();
But it didn't do any difference.
EDIT:
I managed to remove the errors with this code:
const btn = useRef<HTMLButtonElement>(null); const menuTl = useRef<GSAPTimeline>(gsap.timeline()); const toggleMobileMenu = () => { console.log("test"); if (menuTl.current !== null) { console.log("test2"); // menuTl.current.reversed(!menuTl.current.reversed()); menuTl.current.reversed(!menuTl.current.reversed()); } }; useLayoutEffect(() => { const ctx = gsap.context(self => { menuTl.current = gsap.timeline({ paused: true }); menuTl.current.to( ".js-mobile-overlay", { // yPercent: 170, y: "85vh", ease: "expo.inOut", duration: 1.1 }, 0 ); menuTl.current .to( ".js-pie-top", { strokeDasharray: "0,100", autoRound: false, ease: "expo.in", duration: 0.5 }, 0.1 ) .reverse(); }, btn); return () => ctx.revert(); }, []);
But nothing happen when I click the button. I get this error below in the console. But I got the class mentioned in the code.
react_devtools_backend.js:2655 GSAP target .js-mobile-overlay not found. https://greensock.com at TopMenu (http://localhost:6006/components-stories-TopMenu-stories.iframe.bundle.js:370:30) at unboundStoryFn (http://localhost:6006/vendors-node_modules_storybook_addon-actions_preview_js-node_modules_storybook_addon-backgrou-313dcc.iframe.bundle.js:16918:12) at ErrorBoundary (http://localhost:6006/vendors-node_modules_storybook_addon-actions_preview_js-node_modules_storybook_addon-backgrou-313dcc.iframe.bundle.js:14550:5) at WithCallback (http://localhost:6006/vendors-node_modules_storybook_addon-actions_preview_js-node_modules_storybook_addon-backgrou-313dcc.iframe.bundle.js:14430:23)
-
58 minutes ago, Cassie said:
Glad you got it working, but I would suggest against using that code as it's not doing correct animation cleanup and it's using an old version of React (hence why it's working without cleanup, this is mainly important after React 18 due to strict mode)
If you do go ahead with it, you may run into issues. Just a little FYI so you're aware. ☺️Thanks for the heads up! Will see if I get it to work with the code example below.
-
7 minutes ago, Rodrigo said:
Hi,
As @Cassie mentions that is a very old example. Is better to use this as a reference:
https://stackblitz.com/edit/vitejs-vite-4jhqox
This is also another option leveraging all the options GSAP Context offers to achieve the same result:
function App() { const svgContainer = useRef(); const ctx = useRef(); const toggleMenuTimeline = () => { ctx.current.toggleMenu(); }; useLayoutEffect(() => { ctx.current = gsap.context((self) => { const menuTl = gsap .timeline({ paused: true }) .to('#topBar', { duration: 0.2, x: 52, stroke: '#006600', rotation: 45, }) .to('#middleBar', { duration: 0.2, alpha: 0 }, 0) .to( '#bottomBar', { duration: 0.2, x: 52, stroke: '#006600', rotation: -45 }, 0 ) .reverse(); self.add('toggleMenu', () => { menuTl.reversed(!menuTl.reversed()); }); }, svgContainer); return ctx.current.revert(); }, []); return (/*...*/); }
Happy Tweening!
Thanks will try this. But I had problems with current and useRef and to have it in it's own function App(){}. before I got it to work.
I have the timeline directly inside of the code below, is that why it doesn't work with a function, does it have to be it's own component?
export const TopMenu: React.FC<TopMenuProps> = ({primaryNavLinks,secondaryNavLinks,languages}) => {export const TopMenu: React.FC<TopMenuProps> = ({ primaryNavLinks, secondaryNavLinks, languages }) => { ... };
-
I solved it with this code, taken from: https://codesandbox.io/s/gsap-hamburger-toggle-menu-u07i6?file=/src/App.js:1045-1073,
const [tlMenu] = useState(gsap.timeline({ paused: true })); useEffect(() => { tlMenu.to( ".js-mobile-overlay", { // yPercent: 170, y: "85vh", ease: "expo.inOut", duration: 1.1 }, 0 ); tlMenu.to( ".js-mobile-menu", { y: 0, ease: "expo.inOut", duration: 0.9 }, 0.1 ); tlMenu.to( ".js-pie-top", { strokeDasharray: "0,100", autoRound: false, ease: "expo.in", duration: 0.5 }, 0.1 ); tlMenu.to( ".js-pie-bottom", { strokeDasharray: "0,100", strokeDashoffset: "-25", autoRound: false, ease: "expo.in", duration: 0.5 }, 0.1 ); tlMenu.to( ".menu-toggle-titles", { y: -14, ease: "power4.inOut", duration: 0.4 }, 0.5 ); tlMenu .to( ".js-pie-middle", { rotation: 90, y: 8, x: -4, transformOrigin: "center", ease: "back.out(1.4)", duration: 0.5 }, 0.6 ) .reverse(); }, []); const toggleMobileMenu = () => { tlMenu.reversed(!tlMenu.reversed()); setTopMenuVisible(!activeMobileTopMenu); setActiveSubLevel(-1); setActiveSubSubLevel(-1); };
Still don't know why it works though. Shouldn't I need context to be able to use different classes and so on?
-
I have looked at this code https://stackblitz.com/edit/gsap-react-basic-f48716?file=src%2FApp.js and copied:
const container = useRef(); const tl = useRef(); const toggleTimeline = () => { tl.current.reversed(!tl.current.reversed()); }; useLayoutEffect(() => { const ctx = gsap.context((self) => { const boxes = self.selector('.box'); tl.current = gsap .timeline() .to(boxes[0], { x: 120, rotation: 360 }) .to(boxes[1], { x: -120, rotation: -360 }, '<') .to(boxes[2], { y: -166 }) .reverse(); }, container); // <- Scope! return () => ctx.revert(); // <- Cleanup! }, []);
and put it inside of of this:export const TopMenu: React.FC<TopMenuProps> = ({ primaryNavLinks, secondaryNavLinks, languages }) => { ... };
Inside ofreturn (..);
I have put these two on a div and a button.
ref={container} onClick={toggleTimeline}
Doing this I get error on tl.current ('tl.current' is possibly 'undefined'.ts(18048)) and self.selector (Cannot invoke an object which is possibly 'undefined'.ts(2722)'self.selector' is possibly 'undefined'.ts(18048))
Is this because the code is inside ofexport const TopMenu: React.FC<TopMenuProps> = ({ primaryNavLinks, secondaryNavLinks, languages }) => {...};
Or what else have I missed?
I just want a timline that can play forward on button click and reverse itself on next click on same button. The timeline I want to use is this one,See the Pen JjBgQrO?editors=0010 by Devotee007 (@Devotee007) on CodePen
-
I have tried to set up a bit of my code stackblitz. I don't know if that's enough code? I have tried to use current in different ways but I get the error "Property 'current' does not exist on type 'void'.ts(2339)" so I have reverted back to the code seen on the link. Can it be that current won't work when I have it inside this:
export const TopMenu: React.FC<TopMenuProps> = ({primaryNavLinks,secondaryNavLinks,languages}) => {--};
Here's the link to stackblitz: https://stackblitz.com/edit/gsap-react-basic-f48716-8mtrkg?file=src%2FApp.js,src%2Fgsap-react.tsx
-
I got the below code to work so that the animation just play on button click, but it doesn't reverse, it plays the animation from the start every time I click the button. So even if handleMenuClick is true or false it plays the timeline forward.
const [isBoxVisible, setIsBoxVisible] = useState(false); const [menuClicked, setMenuClicked] = useState(false); const tl = gsap.timeline({ paused: true, reversed: true }); tl.set(".box", { y: 0 }); tl.to(".box", { y: 90, ease: "power3", duration: 2 }); function handleMenuClicked() { setMenuClicked(prevMenuClicked => { console.log("before", prevMenuClicked); const newMenuClicked = !prevMenuClicked; console.log("after", newMenuClicked); return newMenuClicked; }); } useEffect(() => { setIsBoxVisible(true); }, []); useEffect(() => { console.log("IF: " + menuClicked); tl.progress() === 0 ? tl.play() : tl.reverse(); }, [menuClicked, tl]);
-
I have a React component for a top menu. I have animated the menu with CSS (Tailwind), but I want, of course, use GSAP instead. I have just started and this is the first time I use React, so a bit of a newbie. Below is the code that I have for the GSAP animation. The thing that happens in then I click on the buttons that starts CSS-animations the GSAP animation below fires as well. The page doesn't reload or anything. Is there something in the below code that I have forgotten to use?
export const TopMenu: React.FC<TopMenuProps> = ({ primaryNavLinks, secondaryNavLinks, languages }) => { // GSAP CODE const component = useRef(null); useEffect(() => { let ctx = gsap.context(() => { console.log("GSAP"); gsap.from(".box", { opacity: 0, y: -90, ease: "power3", duration: 2 }); }, component); }); //END GSAP CODE
-
Quote
Hope I got that right @Devotee007 - and the animation is starting to look pretty cool!
@barthendrix, that was correct and thank you for liking the animation and continue the thread!
@GreenSock, thank you, now I learned something new, didn't know about auto-round. That cleared things up.
- 4
-
@mvaneijgen, this is the updated codepen I changed this:
stroke-dashoffset from 0 to -125
<circle class="bottom" cx="50%" cy="50%" r="15.9" stroke="pink" stroke-dasharray="25 100" stroke-dashoffset="-125"></circle>
After that the flickering stopped. In the video file in previous post you can see the "flickering". When I just did the animation with CSS it was smooth.
After changing from 0 to -125 the ease on the animation seem to happen backwards on the pink area. See video file in this post. Both the green and pink are has ease:"back.in" when I recorded it.
Thank you for your tip about the code, I will updated.
- 1
-
Yes on the pink one. This solved the jumpy bit, but I can't animate in with ease now, because the pink one has a negative value, so ease-out is happens on the wrong end.
-
Solved it by changing stroke-dashoffset from 0 to -125
<circle class="bottom" cx="50%" cy="50%" r="15.9" stroke="pink" stroke-dasharray="25 100" stroke-dashoffset="-125"></circle>
And then this GSAP code.
const tl = gsap.timeline({ paused: true, reversed: true})
tl.to('.top', {strokeDasharray: "0,100", duration:.3}, 0)
tl.to('.bottom', {strokeDasharray: "0,100", duration:.3}, 0)
tl.to('.icon', {x:"7.5rem", duration:.3}, .1)const playBtn = document.getElementById('icon')
playBtn.addEventListener('click', () => {
tl.reversed() ? tl.play() : tl.reverse()
})//Devotee007
-
@barthendrix, don't you see the pink section jumping/staggering against the blue aqua pie bit? For me it jumps a lot. What browser do you use?
Ah, thanks! I misspelled that.
- 1
-
Hi,
I have this code for a CSS animation of a pie chart. It works fine.
.icon:hover .bottom {
stroke-dasharray: 0 100;
stroke-dashoffset: -25;
}
But when I do this with GSAP - tl.to('.bottom', {strokeDasharray: "0,100", strokeDashoffset: "-25", dutation:.3}, 0) the animation stagger.
What am I doing wrong? using stroke-dashoffset: -25; was the only solution I found to reverse the animation of the pink pie part. Is there another solution?
//Devotee007See the Pen JjBgQrO by Devotee007 (@Devotee007) on CodePen
Reverse stagger from different starting point?
in GSAP
Posted
@mvaneijgen, thank you! That helped me a lot.