Search the Community
Showing results for tags 'hovering'.
-
I've been struggling with this code all day. I've tried everything to get the hover effect to work correctly with a .reverse() but this was the closest I could get to it working correctly. Apparently, it works fine when hovering and unhovering the mouse, but if I repeat these actions, the animation freezes or does weird things. How can I fix this, or is there a better way to do this hover animation? I'd appreciate any help.
- 1 reply
-
- gsap
- scrambletext
-
(and 3 more)
Tagged with:
-
The direction of Marquee changes on hovering when scrolling upwards but it works fine when scrolling downwards. Somebody pls help me with this. ? CodePen File attached! HTML: <div class="marquee"> <div class="marquee-inner"> <div class="marquee-part"> Technology Redefined <div class="shape"></div> </div> <div class="marquee-part"> Technology Redefined <div class="shape"></div> </div> <div class="marquee-part"> Technology Redefined <div class="shape"></div> </div> <div class="marquee-part"> Technology Redefined <div class="shape"></div> </div> <div class="marquee-part"> Technology Redefined <div class="shape"></div> </div> <div class="marquee-part"> Technology Redefined <div class="shape"></div> </div> </div> </div> JS let currentScroll = 0; let isScrollingDown = true; const marquee = document.querySelector('.marquee'); const marq = document.querySelector('.marquee-part'); const mrq = document.querySelector('.marquee-inner'); const loop = horizontalLoop(mrq, { paused: false, repeat: -1, }); marquee.addEventListener("mouseenter", () => { gsap.to(loop, { timeScale: 3, ease: "power1.in" }); }); marquee.addEventListener("mouseleave", () => { gsap.to(loop, { timeScale: 1 }); }); window.addEventListener("scroll", function() { if(window.pageYOffset > currentScroll){ isScrollingDown = true; }else{ isScrollingDown = false; } gsap.to(loop, { timeScale: isScrollingDown ? 1 : -1, }).totalProgress(1); currentScroll = window.pageYOffset; }); /*---------------HORIZONTAL LOOP FN-------------------*/ function horizontalLoop(items, config) { items = gsap.utils.toArray(items); config = config || {}; let tl = gsap.timeline({repeat: config.repeat, paused: config.paused, defaults: {ease: "none"}, onReverseComplete: () => tl.totalTime(tl.rawTime() + tl.duration() * 100)}), length = items.length, startX = items[0].offsetLeft, times = [], widths = [], xPercents = [], curIndex = 0, pixelsPerSecond = (config.speed || 1) * 100, snap = config.snap === false ? v => v : gsap.utils.snap(config.snap || 1), // some browsers shift by a pixel to accommodate flex layouts, so for example if width is 20% the first element's width might be 242px, and the next 243px, alternating back and forth. So we snap to 5 percentage points to make things look more natural totalWidth, curX, distanceToStart, distanceToLoop, item, i; gsap.set(items, { // convert "x" to "xPercent" to make things responsive, and populate the widths/xPercents Arrays to make lookups faster. xPercent: (i, el) => { let w = widths[i] = parseFloat(gsap.getProperty(el, "width", "px")); xPercents[i] = snap(parseFloat(gsap.getProperty(el, "x", "px")) / w * 100 + gsap.getProperty(el, "xPercent")); return xPercents[i]; } }); gsap.set(items, {x: 0}); totalWidth = items[length-1].offsetLeft + xPercents[length-1] / 100 * widths[length-1] - startX + items[length-1].offsetWidth * gsap.getProperty(items[length-1], "scaleX") + (parseFloat(config.paddingRight) || 0); for (i = 0; i < length; i++) { item = items[i]; curX = xPercents[i] / 100 * widths[i]; distanceToStart = item.offsetLeft + curX - startX; distanceToLoop = distanceToStart + widths[i] * gsap.getProperty(item, "scaleX"); tl.to(item, {xPercent: snap((curX - distanceToLoop) / widths[i] * 100), duration: distanceToLoop / pixelsPerSecond}, 0) .fromTo(item, {xPercent: snap((curX - distanceToLoop + totalWidth) / widths[i] * 100)}, {xPercent: xPercents[i], duration: (curX - distanceToLoop + totalWidth - curX) / pixelsPerSecond, immediateRender: false}, distanceToLoop / pixelsPerSecond) .add("label" + i, distanceToStart / pixelsPerSecond); times[i] = distanceToStart / pixelsPerSecond; } function toIndex(index, vars) { vars = vars || {}; (Math.abs(index - curIndex) > length / 2) && (index += index > curIndex ? -length : length); // always go in the shortest direction let newIndex = gsap.utils.wrap(0, length, index), time = times[newIndex]; if (time > tl.time() !== index > curIndex) { // if we're wrapping the timeline's playhead, make the proper adjustments vars.modifiers = {time: gsap.utils.wrap(0, tl.duration())}; time += tl.duration() * (index > curIndex ? 1 : -1); } curIndex = newIndex; vars.overwrite = true; return tl.tweenTo(time, vars); } tl.next = vars => toIndex(curIndex+1, vars); tl.previous = vars => toIndex(curIndex-1, vars); tl.current = () => curIndex; tl.toIndex = (index, vars) => toIndex(index, vars); tl.times = times; tl.progress(1, true).progress(0, true); // pre-render for performance if (config.reversed) { tl.vars.onReverseComplete(); tl.reverse(); } return tl; }
-
I get this Error Message when trying to stop the marquee on mouse hover! Pls Help!! Error: Invalid property pauseOnHover set to true Missing plugin? gsap.registerPlugin() Code: HTML: <div class="marquee"> <div class="marquee-inner"> <div class="marquee-part"> Technology Redefined <div class="shape"></div> </div> <div class="marquee-part"> Technology Redefined <div class="shape"></div> </div> <div class="marquee-part"> Technology Redefined <div class="shape"></div> </div> <div class="marquee-part"> Technology Redefined <div class="shape"></div> </div> <div class="marquee-part"> Technology Redefined <div class="shape"></div> </div> <div class="marquee-part"> Technology Redefined <div class="shape"></div> </div> </div> </div> CSS: gsap.registerPlugin(ScrollTrigger); let currentScroll = 0; let isScrollingDown = true; let shapes = document.querySelectorAll(".shape"); const links = document.querySelectorAll(".marquee-inner"); let marquee = document.querySelector('.marquee-inner'); let tween = gsap.to(".marquee-part", { xPercent: -100, repeat: -1, duration: 5, ease: "linear", pauseOnHover: true, }).totalProgress(0.5); let loop = gsap.to(links, { repeat: -1, speed: 1 + 0.5, draggable: true, reversed: false, paddingRight: parseFloat(gsap.getProperty(links[0], "marginRight", "px")) }); marquee.addEventListener("mouseenter", () => { loop.pause() }) marquee.addEventListener("mouseleave", () => { loop.play() }) gsap.set(".marquee-inner", {xPercent: -10}); window.addEventListener("scroll", function() { if(window.pageYOffset > currentScroll){ isScrollingDown = true; }else{ isScrollingDown = false; } gsap.to(tween, { timeScale: isScrollingDown ? 1 : -1, }).totalProgress(1); currentScroll = window.pageYOffset; });
-
Im trying to achieve a smooth repetitive up and down "floating" effect on x amount of elements - each element with it's own id. After a little while of "floating" the up and down tweening seems to get sluggish. (my real test uses 5 x 100kb images that has been preloaded before tweening) Im using one function to define the up tweening and another to define the down tweening and then throw each element back and forth these two functions. Any suggestion on how I can achieve the same effect more efficient and perhaps even in some smarter way without the two functions are very welcome! My bet is there some "bottleneck" there and that I can perhaps do some simple re-usable timeline instead? Follow the Codepen to see the concept of it