Jump to content
Search Community

fr8877

Members
  • Posts

    6
  • Joined

  • Last visited

fr8877's Achievements

  1. Well that was ridiculously easy! I knew I was missing something. Thanks so much for the wonderful help and quick response!
  2. import React, { ReactNode, useLayoutEffect, useRef, createRef } from "react"; import { gsap } from "gsap"; import ScrollTrigger from 'gsap/ScrollTrigger'; gsap.registerPlugin(ScrollTrigger); export interface Props { letter: string; } const Header = () => { const container = useRef<HTMLDivElement>(null); const windowSize = useRef([window.innerWidth, window.innerHeight]); const nameRef = useRef<HTMLDivElement>(null); let name: string = "MY NAME"; let nameArr: string[] = name.split(''); const letterRefs: any[] = []; useLayoutEffect(function(): any { let width = windowSize.current[0]; let height= windowSize.current[1]; let x = (): number => { return Math.random() * (width - 200); } let y = (): number => { return Math.random() * (height - 200); } console.log(letterRefs); letterRefs.forEach(letterRef => { let floating = gsap.fromTo(letterRef.current, { x: x, y: y, }, { id: "letters", duration: Math.random() * 100, x: x, y: y, }); let scrollAnim = gsap.to(letterRef.current, { x: (): number => { if (nameRef.current){ // floating.pause(); let nameWidth = nameRef.current.clientWidth; return (width/2) - (nameWidth/2); } else { return width/1.5 } }, y: (): number => { if (nameRef.current){ let nameHeight = nameRef.current.clientHeight; return (height/2) - (nameHeight/2) } else { return height/1.5 } }, duration: 3, scrollTrigger: { // trigger: container.current, // pin: container.current, start: 10, markers: true, }, }) }); }, []); return( <div className="container" ref={container}> <div className="name" ref ={nameRef}> { nameArr.map((value, index) => { const newLetterRef = createRef<HTMLDivElement>(); letterRefs[index] = newLetterRef; return <div key={index} className="letter" ref={newLetterRef}> <div>{value}</div> </div> }) } </div> </div> ) }; export default Header; I'm probably missing something obvious here. I'm currently using forEach to animate each of my div elements in the same way. However, this means that all my animations need to be within it otherwise they can't interact and I am so sure that there is a better, cleaner way. I'm trying to pause `floating ` on Scrolltrigger but because it is currently only accessible within the loop its already paused on load.
  3. Ummm, not quite haha The click is working how I would like it to (clicking anywhere on the element just iterates to the next item in the array which defines the content behaviour), it's the drag that is not behaving how I would expect. I would think that dragging it would also move linearly through the snaps array but after completing a full rotation it misses items in the array and goes straight on to the next one. This happens when being dragged in either direction.
  4. Sorry, I'm very new to this. Lets see if I can explain a bit better. What I am trying to do is very similar to this https://greensock.com/forums/topic/16022-draggable-spin-getting-it-to-fully-rotate-instead-of-stopping/ except that it also allows onClick. My problem is that if `onClick` is enabled, when you drag the `liveSnap` skips the some of the numbers in the `snaps` array. It only happens on drag, not on click. There doesn't seem to be any pattern to the numbers skipped. I've fixed my code up a bit, thanks to Sahils example above but, it is still doing it. The `onRotate` function is only toggling the visibility of other elements on the page and does not effect the draggable element. I hope this is clearer, thanks for sticking with me! var position = 0; var snaps = [0, 45, 135, 180, 225, 315, 360]; var adjusting = false; var clockButton = document.querySelector('#clock-button'); function getClosestIndex(value, choices) { var i = choices.length; var closest = 0; var absDif = 9999999999; var dif, val; while (--i > -1) { val = choices[i]; dif = Math.abs(val - value); if (dif < absDif) { closest = i; absDif = dif; } } return closest; } function onLiveSnap(value) { position = getClosestIndex((value + 360 * 99999999) % 360, snaps); onRotate(snaps[position]); return snaps[position]; } var draggable = Draggable.create([clockButton], { type: "rotation", dragResistance: 0, onDrag: onRotate, liveSnap: onLiveSnap, onClick: function(e){ adjusting = true; this.update(); if (snaps[position] === 0 ){ snaps[position] = 45; } else if (snaps[position] === 45){ snaps[position] = 135; } else if (snaps[position] === 135){ snaps[position] = 180; } else if (snaps[position] === 180){ snaps[position] = 225; } else if (snaps[position] === 225){ snaps[position] = 315; } else { snaps[position] = 0; } TweenLite.set(this.target, { rotation: snaps[position] }); this.endDrag(); adjusting = false; }, onRelease: function() { if(this.tween && (adjusting || this.timeSinceDrag() > 0.02)){ this.tween.kill(); } } });
  5. Hi Sahil, thanks for your answer. I don't want it to snap with the mouse, I just want it to rotate in set increments when it is clicked anywhere on the button, does that make sense?
  6. Hey friends, I'm trying to get my element to have the same behaviour when it is clicked as when it is dragged and I just can't seem to make it happen. The jsfiddle is: https://jsfiddle.net/fr8877/zpsem6mc/173/ In my actual project the clock button does rotate on click but if you try and drag after you've clicked or click after you've dragged, it works for a couple of snaps and then breaks. In the jsfiddle the clock button just doesn't rotate at all. Its my first time using it so I'm not sure where I've gone wrong there. Please help!
×
×
  • Create New...