Jump to content
Search Community

coldgroove

Members
  • Posts

    6
  • Joined

  • Last visited

coldgroove's Achievements

  1. Hey @Rodrigo! Thanks a lot for the Observer advice. I had no clue about that plugin. It's awesome! As much as I'm not sure if gsap is a perfect match w/React, there is always a solution in GSAP if devs know about their needs. Observer solved all the problems mentioned. Thanks once again!
  2. Hey again, thx for the reply and the stackblitz template. Here is the minimal demo. and the application itself fullscreen. Hope this helps @mvaneijgen
  3. Hi! We really like this 3d carousel idea and tried to implement our own version. We have two main problems: 1 - Can't figure out how they made the scrolltrigger infinite 2 - Tried to add a drag option as well with Draggable plugin and wanted to bind it to the scrolltrigger so the card positions are in sync with it. Here is our implementation (couldnt make it as a pen because I'm lazy and dont know how to create a react envo in codepen but hey, here is the live demo if you wanna see how it looks and behaves): vars and useEffect: const numberOfCards = allCases.length; const angleOfCards = 360 / numberOfCards; const cardGaps = numberOfCards > 6 ? Math.pow(numberOfCards, 2.2) : -angleOfCards / numberOfCards; useEffect(() => { gsap.registerPlugin(ScrollTrigger, Draggable); const root = rootRef.current; const container = containerRef.current; const cards = cardRefs.current; const dragProxy = dragProxyRef.current; // Mouse Tracking animation const onMouseMove = (e) => { if (!root || !container || !cards) return; const { clientX, clientY } = e; const { width: clientWidth, height: clientHeight } = root.getBoundingClientRect(); const rotateXVal = (clientY - clientHeight / 2) * 0.06; const rotateYVal = (clientWidth / 2 - clientX) * 0.01; container.style.transform = `rotateX(${rotateXVal}deg) rotate(${rotateYVal}deg)`; }; document.addEventListener("mousemove", onMouseMove); // Gsap Animations with scroll and drag const ctx = gsap.context(() => { if (!root || !container || !cards || !dragProxy) return; // Drag Draggable.create(dragProxy, { type: "x", trigger: cards, bounds: container, onDrag: function () { const progress = (this.startX - this.x) * 0.008; cards.forEach((card, idx) => { card.style.transform = `rotateY(${ (idx + progress) * angleOfCards }deg) translateZ(320px) translate3d(0px,0px,${cardGaps}px)`; }); }, }); // Scroll ScrollTrigger.create({ pin: true, scrub: true, invalidateOnRefresh: false, start: "top top", end: "+=10000", //i set the end as a big number to at least rotate the carousel one whole turn since i can't make it infinite tried to mimic it trigger: root, // markers: true, }); cards.forEach((card, idx) => { ScrollTrigger.create({ scrub: true, start: "top top", end: "max", trigger: container, onUpdate: (self) => { gsap.delayedCall(0.1, () => { card.style.transform = `rotateY(${ (idx + self.progress * 10) * angleOfCards }deg) translateZ(320px) translate3d(0px,0px,${Math.abs( (cardGaps * (cards.length + 5)) / cards.length )}px)`; }); gsap.delayedCall(1, () => { card.style.transform = `rotateY(${ (idx + self.progress * 10) * angleOfCards }deg) translateZ(320px) translate3d(0px,0px,${cardGaps}px)`; }); }, }); }); }); return () => { ctx.revert(); document.removeEventListener("mousemove", onMouseMove); }; }, []); JSX: <section className={s.root} ref={rootRef}> <div className={s.carouselContainer} ref={containerRef}> {allCases && allCases.map((c, idx) => { return ( <div key={c.id} onMouseEnter={() => setSelectedCaseIdx(idx)} style={{ transform: `rotateY(${ idx * angleOfCards }deg) translateZ(320px) translate3d(0px,0px,${cardGaps}px)`, }} ref={(e) => createRefs(cardRefs, e, idx)} className={s.carouselCard} > <CustomLink link={c.caseLink} className="z-10"> <NextImage layout="fill" media={c.bgImg} objectFit="cover" className="rounded-lg" /> <div className={s.content}> <p className={classNames(s.description, "text-lg")}> {c.description} </p> <h3 className={s.bigTitle}>{c.bigTitle}</h3> </div> </CustomLink> </div> ); })} </div> <div ref={dragProxyRef} className="invisible absolute" /> </section> Here is the related css classes just in case something is wrong with it? .root { @apply pt-20 2xl:pt-32 px-20 min-h-screen text-primary relative; } .carouselContainer { @apply relative flex justify-center items-center; min-height: 650px; width: 100%; transform-style: preserve-3d; perspective: 1300px; /* transform-origin: center center calc(-300px / 100); */ } .carouselCard { @apply rounded-lg; overflow: hidden; width: 320px; aspect-ratio: 0.67; position: absolute; transition: transform 1s; -webkit-box-reflect: below 10px linear-gradient(transparent, transparent, #0005); }
  4. Hey there uhm, I'm trying to make a similar effect but got stuck so maybe you guys can help me? I've basically copied @PointC 's svg pattern with the mask one not the clipPath, and I only want to have a vertical mask with 2 fixed colors changing into each other. So I only changed the svg size to be width=100% height=100% just to make it a fullscreen one. There is no probs there. However why do you select the rect's that are inside of definition tags for x and y animations? I got confused about that because if I select those my mask doesn't change neither with scaleY: 0, or height:0. Nonetheless if I attach my ref to the rect that you defined as "this is the fixed color background with white as the fill, but the stroke changes", it works. I mean it's kinda. The blueScreen is going upwards with scaleY: 0. But the mask doesnt work so the other text isn't showing up for some reason. I've removed the stroke stuff too if its related. This is my svg el with a few changes: <svg id="maskDemo" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 400 200" > <title>Invert SVG text fill color with masks</title> <defs> <mask id="theMask"> <rect id="maskerH" width="400" height="200" x="-400" y="0" fill="#fff" /> <rect id="maskerV" width="400" height="200" x="0" y="200" fill="#fff" /> </mask> </defs> {/* <!-- this is the fixed color background with white as the fill, but the stroke changes --> */} <rect id="bgFixed" ref={blueScreenRef} width="400" height="200" fill={data.textColorCode} // stroke="#94c356" // stroke-width="4" /> {/* <!-- this text color changes based on the chosen color swatch--> */} <g id="startColor" fill={data.bgColorCode} fontSize="100"> <text className="theCount" textAnchor="end" x="220" y="140"> 100 </text> <text textAnchor="start" x="230" y="140"> % </text> </g> <g mask="url(#theMask)"> {/* <!-- this is the changeable color background based on the swatch click--> */} <rect id="bgChange" width="400" height="200" fill="#94c356" /> {/* <!-- this is the duplicate text group revealed by the masks it's always white --> */} <g id="end" fill="white" fontSize="100"> <text className="theCount" textAnchor="end" x="220" y="140"> 100 </text> <text textAnchor="start" x="230" y="140"> % </text> </g> </g> </svg> and this is my useEffect: useEffect(() => { const ctx = gsap.context(() => { const sharedScrollTrigger = { start: "top top", trigger: sectionRef.current, invalidateOnRefresh: false, scrub: 1, end: () => "+=4500", // markers: true, }; // pinning the section gsap.to(sectionRef.current, { scrollTrigger: { start: "top top", pin: true, trigger: sectionRef.current, invalidateOnRefresh: false, scrub: 1, end: () => "+=5000", // markers: true, }, }); // close the blueScreen gsap.fromTo( blueScreenRef.current, { scaleY: 1, }, { scaleY: 0, scrollTrigger: sharedScrollTrigger, } ); // other anims... }, sectionRef); return () => ctx.revert(); }, []); What am i doing wrong in here brothas? I think i suck with the svg's @PointC ? any help would be greatly appreciated.
  5. @Rodrigo Big thanks, I'm new to GSAP and learning alot since I've started working with it, I've copied and pasted this sandbox that I've found on the internet because I'was too lazy to implement one-to-one copy of my production code, I'm using the latest version with context and everything. I've tried to tweak the params with hardcoded values but somehow couldnt get it working. Now it all makes sense, thanks again this solved my issue!
  6. Hi, i want to limit the max-width of the dom element called "pin-spacer" created by ScrollTrigger however nothing seems to be working, here is a codesandbox to show the effect => https://codesandbox.io/s/wandering-dust-xjhf4h?file=/src/App.js
×
×
  • Create New...