Jump to content
Search Community

All Activity

This stream auto-updates

  1. Past hour
  2. OK I think I figured it out. Wasnt as complicated as I thought... https://codesandbox.io/p/sandbox/react-gsap-starter-template-y8z5hd?file=%2Fsrc%2Findex.js
  3. Pleased to meet you @mvaneijgen, I'm a Jr. SWE who is now doing a R&D(Research and Development) on figuring out the tech stack that can provide me huge advantage of animating our company's site and it's under development so we have plenty of time to do it. And so provided the design from our company I found a reference https://www.anyways.co/ footer, in which they have inertial effects. I am trying to achieve it but when I glanced through the GSAP docs I found that inertial effect is a club plugin. Also sorry for the less information which I gave you before.
  4. Today
  5. Hi @Rodrigo, it took me a while to come back to this, but with a fresh head I came up with a slightly different idea. With a combination of a dynamic top of the viewport value for the start marker and ScrollTrigger.refresh(); it works fine: https://codepen.io/emjay/pen/YzMbmvg/b470cafeaf6e4f2fd39203126e8f3f67 I think it's totally fine to do it that way, don't you?
  6. Hi guys Stackblitz is not working for me for whatever reason, but codesanbox seems fine. Is there a react gsap starter template for codesandbox somebody can point me to please, or briefly describe how I can set one up please?
  7. Hi @Sharath Lingam welcome to the forum! Sure you can, but the question is how much time do you have and what is your skill level? The beauty of GSAP is you can build anything you like! So there is probably a way with the tools GSAP gives you can build your own inertia logic, but that means you also have to do all the debugging and all the trouble shooting your self, so the question becomes how much time do you want to spend figuring this out? Our reply will be "just use the inertia plugin, there is a lot of time spend figuring it all out, so that you don't have to!". Your question feels a bit like asking a carpenter if you can borrow all their professional tools, but without their tools they can't do their job... But again feel free to roll your own logic, there is nothing wrong with a bit of coding and figuring things out by your self. In theory inertia is just animating something and slowly getting to a 0 value that feels correct, but I think when you do go the roll your own route you'll come across a lot of hurdles that will take a lot to figure out. Hope it helps and happy tweening!
  8. Hi @Manoj Khatri welcome to the forum! Check out the post by our own @Carl
  9. Can I create inertia like effect without InertiaPlugin, with only by using free plugins?
  10. How we can create this type of carousel using GSAP? Anyone who knows can help
  11. Yesterday
  12. Hi, This is the simplest way I can think of doing that: https://codepen.io/GreenSock/pen/LYvoaNb Hopefully this helps. Happy Tweening!
  13. I'd go even simpler with yoyo tweens and repeatDelay. Something like this. https://codepen.io/PointC/pen/JjVqxgY/63a3e8ecfaf75286961b6e2ec36abed7 Just my 2 cents. YMMV. Happy tweening. Just FYI - the original pen that I forked had tweens with a 0.1 → 1 second duration on a timeline that was 100 seconds long. With scrub set to true they were animating super fast because they were only a tiny fraction of the duration. .1% - 1%.
  14. I doubt you'll run into performance problems with this TBH, since you have a rather small collection of elements. IMHO though this seems simpler to understand, follow and maintain: const blockElements = gsap.utils.toArray(".block"); const block1 = blocks.querySelector(".block-1"); const block2 = blocks.querySelector(".block-2"); const block3 = blocks.querySelector(".block-3"); const blockSettings = [ { element: block1, position: 30 }, { element: block2, position: 50 }, { element: block3, position: 60 } ]; blockSettings.forEach((b, i) => { const block = blockElements[i]; const otherBlocks = blockElements.filter((block, j) => i !== j); tl.add(() => { gsap.to(block, { opacity: 1, duration: 1, scale: 1 }); gsap.to(otherBlocks, { opacity: 0, duration: 1, scale: 1.2 }); }, b.position); }); You don't have to resort to that conditional block and anything that results in simpler and shorter code, is going to make more sense if you have to look at it in 6 months. Here is a fork of your demo: https://codepen.io/GreenSock/pen/oNORmKL Is worth mentioning that using the add() to add an anonymous function is the same as using call(): const tl = gsap.timeline(); tl.add(() => {}, position); // Exactly the same tl.call(() => {}, [/*parameters*/], position); Hopefully this helps. Happy Tweening!
  15. Hi @MarOne, You can check the resources in the Webflow installation page on our Learning Center: https://gsap.com/resources/Webflow#installation Also we have a brand new installation video, where @Cassie goes into a lot of detail including webflow: This starts right with webflow, but you can go to youtube and check the chapters on the video so you can jump directly to a specific section. Hopefully this helps. Happy Tweening!
  16. wow it works fine, i replaced the useEffect with useGsap thanks a lot
  17. After more tinkering, i think i found a solution: https://codepen.io/Valentin-Ilas/pen/ZEZNVRX?editors=1111 Basically I'm using tl.add() to run animations independently from the scrub on the parent container. Then i can specify for each one where during the progress it should run. Seems to work backwards too. But is this approach efficient? or do you see any performance issues?
  18. Can Anybody please tell me how to use Gsap Club plugins in a webflow project? It's soooo complicated and it shouldn't be like that?
  19. Hi, (stack : Next JS) i'm close to achieve an effect but am stuck! Here is the result of where i am for now : https://youtu.be/tXUPHLRPiDA As you can see, I'd like to make a transition on clicking to a project thumbnail. Problem : I don't want the container to scaleY up, but i want to keep the infos/image inside to a normal ratio. I tied to animate height, instead of scaleY, but then I have to also animation the scrollTo, and it was a bit messy... Here is the ProjectThumb component (I do have a project list with several ProjectThumb) : import React, { useRef, useState } from "react"; import { useGSAP } from "@gsap/react"; import gsap from "gsap"; import { lineAnimation, projectContainerAnimation, scrollAnimation, subtitleAnimation, titleAnimation, } from "../animations/animations"; import { ScrollToPlugin } from "gsap/ScrollToPlugin"; import { ScrollTrigger } from "gsap/ScrollTrigger"; import Image from "next/image"; import { useRouter } from "next/navigation"; gsap.registerPlugin(ScrollTrigger); gsap.registerPlugin(ScrollToPlugin); const ProjectThumb = ({ project, setClicked, clicked, }: { project: any; setClicked: React.Dispatch<React.SetStateAction<number | null>>; clicked: number | null; }) => { const lineRef = useRef<HTMLDivElement>(null); const thumbContainerRef = useRef<HTMLDivElement>(null); const titleRef = useRef(null); const subTitleRef = useRef(null); const imageRef = useRef(null); const router = useRouter(); const [timeline, setTimeline] = useState<any>(); const [timeline2, setTimeline2] = useState<any>(); // set line animation timeline up useGSAP(() => { if (lineRef.current) { const tl2 = gsap.timeline({ scrollTrigger: { trigger: lineRef.current, start: "top 85%", toggleActions: "play end resume reverse", }, }); tl2.add(lineAnimation(lineRef)); setTimeline2(tl2); } }, [lineRef]); // Set project elements timeline up useGSAP(() => { const tl = gsap.timeline(); setTimeline(tl); // show off all project container but the one clicked if (clicked && clicked !== project.id && thumbContainerRef.current) { timeline.to( thumbContainerRef.current, { opacity: 0, duration: 0.5, }, `<${Math.abs((clicked - project.id) * 0.5) / 3}` ); } }, [clicked, thumbContainerRef]); const handlePlayAnimation = () => { if ( thumbContainerRef.current && subTitleRef.current && titleRef.current && timeline2 && timeline ) { setClicked(project.id); timeline2.clear(); timeline2.to(lineRef.current, { scaleX: 0, duration: 0.5, }); const offset = window.innerHeight * 0.5 - thumbContainerRef.current.getBoundingClientRect().height / 2 - 32; const thumbContainerScale = window.innerHeight / thumbContainerRef.current.getBoundingClientRect().height; timeline .add(scrollAnimation(thumbContainerRef, offset)) .add(titleAnimation(titleRef), "-=0.4") .add(subtitleAnimation(subTitleRef), "-=0.25") .add( projectContainerAnimation(thumbContainerRef, thumbContainerScale), "<=0.3" ); // .then(() => router.push(`/projects/${project.id}`)); } }; return ( <div className={`project_container_${project.id} overflow-hidden min-h-[25vh] relative`} ref={thumbContainerRef} > <div ref={lineRef} className="projectLine scale-x-0 h-2 bg-slate-500 opacity-100" ></div> <div onClick={handlePlayAnimation} className="project_infos button absolute w-full h-full z-10 cursor-pointer" > <div></div> <div className="project_title flex gap-4 p-8 items-end text-white" key={project.id} > <h3 ref={titleRef} className="project_title text-2xl w-full text-slate-800" > {project.title} </h3> <p ref={subTitleRef} className="project_subtitle w-full text-slate-800" > {project.subtitle} </p> </div> </div> <Image ref={imageRef} src={project.images.thumbnail} width={1920} height={1080} alt={project.title} className="h-full object-cover aspect-square opacity-30 absolute" /> </div> ); }; export default ProjectThumb; And here are the animations called by the previous component : import gsap from "gsap"; import { ScrollTrigger } from "gsap/ScrollTrigger"; import { ScrollToPlugin } from "gsap/ScrollToPlugin"; gsap.registerPlugin(ScrollTrigger); gsap.registerPlugin(ScrollToPlugin); export const lineAnimation = (ref: any) => { return gsap.to(ref.current, { scaleX: 1, transformOrigin: "left", duration: 0.75, }); }; export const thumbContainerAnimation = (ref: any) => { return gsap.to(ref.current, { height: "100vh", transformOrigin: "top center", duration: 1, ease: "expo.in", }); }; export const scrollAnimation = (ref: any, offset: number) => { return gsap.to(window, { duration: 0.75, scrollTo: { y: ref.current, offsetY: offset }, ease: "expo.inOut", }); }; export const titleAnimation = (ref: any) => { return gsap.to(ref.current, { duration: 0.4, y: -50, opacity: 0, ease: "expo.in", }); }; export const subtitleAnimation = (ref: any) => { return gsap.to(ref.current, { duration: 0.35, y: -50, opacity: 0, ease: "expo.in", }); }; export const projectContainerAnimation = (ref: any, scale: number) => { return gsap.to(ref.current, { scaleY: scale, transformOrigin: "center", duration: 1.2, ease: "power4.inOut", }); };
  20. So basically i saw this demo here: https://codepen.io/snorkltv/pen/vYVBPJq and decided to try it out in react but for some reason the code only actvates when i've scrolled to the bottom is there any reason why? here's mine : https://stackblitz.com/edit/vitejs-vite-83dipo?file=src/App.jsx
  21. I've been trying to use the position parameter and I feel like I'm close but not quite there yet I noticed some interesting behaviour: if scrub is set to true, then the a duration seems to be needed. So i added duration: 100 which seems to work more as a percentage If i use the position parameter on each block, with values such as 20, 30 50 etc, they seem to trigger based on the percentage as well. Now what i can't seem to be able to do is to make the fade-in more animated instead of running it instantly and how to control the duration of the fade in. Please see the example below: https://codepen.io/Valentin-Ilas/pen/abxrRYe
  22. I'm not 100% sure I follow what you're trying to do. I forked the codepen and made some changes to it: https://codepen.io/GreenSock/pen/wvZbQKX At the end the pinnedContainer config is not needed since any of the pinned elements is adding any vertical space. Hopefully this helps. Happy Tweening!
  23. Just so you know, you could just call tween.revert() instead of doing both kill() and clearProps. You could also record the progress in your resize handler, and then re-apply that to make things continuous: https://codepen.io/GreenSock/pen/ZEZNmpz?editors=0010
  24. That is exactly what the position parameter can do. Another way is to keep the logic you have now, but find a way to run it just once and not everytime the GSAP instance updates, that's too wasteful. Happy Tweening!
  25. Hi Rodrigo, I tried to illustrate it in the following codepen but I think i didn't get it quite right. So the idea is that there is a pinned container which is connected to a scroll trigger and at precise moments in the timeline, for example when the progress is 0.3 then the block 1 should appear. If the progress goes to 0.74 then block 2 should appear. All 3 blocks are in the same position just only 1 visible at a time. https://codepen.io/Valentin-Ilas/pen/abxrRYe?editors=1111
  26. That is mostly because GSAP handles all the transforms using the 3D transform matrix: https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix3d While setting a single transform using CSS does just that, applies a single transform. When you do that and then animate the same property with GSAP, GSAP takes that value applied by CSS and uses it's own method for transforms. That is why we recommend doing what you tried and worked, use GSAP to set all the initial transforms that will be animated with GSAP, to avoid that extra step when the animation first runs. Also sometimes is a good idea to use the advice from the FOUC article to prevent annoying flashes before the JS runs. Happy Tweening!
  27. Hi, Just create a loop for the cards, add a couple of to() instances to the timeline and using the position parameter create an overlap with the previous card: https://codepen.io/GreenSock/pen/WNWBaKz Hopefully this helps. Happy Tweening!
  28. Maybe it was hardware acceleration issues? This morning, I also changed something in my storybook that seemed to help - even though I can't explain why. On initial load, I set the initial segment position with GSAP, and that seemed to make a huge difference. Any theories why setting GSAP styles on the initial item made the difference? The flickering i was seeing seemed to happen for the first transition between segments. After this change, it seems to be fluid. But I don't understand why. Is it best practice to set initial GSAP styles on all elements before animating? Thanks so much for your help @Rodrigo This is what i added: /** * Animation to play when the segment is the initial segment */ setInitialSegment: () => gsap.core.Timeline; .... // For setting the initial animation state with gsap values ctx.add("setInitialSegment", () => { return gsap.set(sectionRef.current, { ...TRANSLATION_BASE, yPercent: 0, autoAlpha: 1, scale: 1, }); }); .... useEffect(() => { /** * If the previous segment is null, then this is the initial segment */ if (previousSegment === null) { /** * Establish gsap styles on the initial segment */ if (isActive) { if (ctx && "setInitialSegment" in ctx) { ctx?.setInitialSegment?.(); } } return; }
  1. Load more activity
×
×
  • Create New...