Jump to content
Search Community

Search the Community

Showing results for 'normalize lerp clamp'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • GreenSock Forums
    • GSAP
    • Banner Animation
    • Jobs & Freelance
  • Flash / ActionScript Archive
    • GSAP (Flash)
    • Loading (Flash)
    • TransformManager (Flash)

Product Groups

  • Club GreenSock
  • TransformManager
  • Supercharge

Categories

There are no results to display.


Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Personal Website


Twitter


CodePen


Company Website


Location


Interests

Found 373 results

  1. There are a few helper functions that can save you from figuring out the math/logic: To find the scroll position of a particular element: https://gsap.com/docs/v3/HelperFunctions/helpers/getScrollLookup/ To find the scroll position of a particular animation: https://gsap.com/docs/v3/HelperFunctions/helpers/getScrollPosition If you want to scroll to the start of the 2nd animation, for example, you could do this: https://codepen.io/GreenSock/pen/vYMqVVL?editors=1010 function getScrollPosition(animation, progress) { let p = gsap.utils.clamp(0, 1, progress || 0), nested = !animation.scrollTrigger, st = nested ? animation.parent.scrollTrigger : animation.scrollTrigger, containerAnimation = st.vars.containerAnimation, range = st.end - st.start, position = st.start + range * p; if (containerAnimation) { st = containerAnimation.scrollTrigger; return (st.start + (st.end - st.start) * (position / containerAnimation.duration())); } else if (nested) { let start = st.start + (animation.startTime() / animation.parent.duration()) * range, end = st.start + ((animation.startTime() + animation.duration()) / animation.parent.duration()) * range; return start + (end - start) * p; } return position; }
  2. The name onLeave implies the trigger is leaving the trigger zone not that it is outside. If I instantiated five scroll triggers four of which were outside the viewport you’re saying four onLeave events firing makes sense? If the code is firing events that should be triggered by user interaction on instantiation then that’s a bug. If that’s not the case then the name of the onleave callback should be something that reflects its purpose accurately. I’ll look at clamp. Thanks for the tip.
  3. That's because the first ScrollTrigger instance is passed the end marker and the second one is passed the start marker, makes total sense: You have to take a look at the clamp feature in ScrollTrigger: Yep I'm aware of what custom hooks do in React, I wrote parts of our useGSAP hook. Hopefully this helps. Happy Tweening!
  4. Hi, The first issue in your code is that you're using the quick setter on the parent element, that is the element that contains the grid, and not the grid elements so staggering will have no effect whatsoever. Then I fail to see the point of a quick setter if you can achieve the same with just a GSAP Tween that gets overwritten if another is created. Something like this: useGSAP(() => { let proxy = { translate: 0 }, translateSetter = gsap.quickSetter('.video-container', 'y', 'px'), clamp = gsap.utils.clamp(-1000, 1000); ScrollTrigger.create({ onUpdate: (self) => { translateSetter(clamp(self.getVelocity() / -100)); gsap.to('.video-container', { y: 0, duration: 0.2, stagger: 0.05, overwrite: true, }); }, }); }); Here is a fork of your demo with that approach: https://stackblitz.com/edit/react-hnfbhc?file=src%2FApp.js Hopefully this helps. Happy Tweening!
  5. Hi @OliverHH and welcome to the GSAP Forums! I'm afraid that is not possible, at least not in a simple way. Maybe there is a way to achieve that with enough custom logic but is beyond the scope of the help we provide in these free forums. ScrollTrigger does provides a duration option for the snap configuration that gives you the possibility to either set a fixed duration of the snapping or set a min and max durations: duration [Number | Object] - the duration of the snapping animation (in seconds). duration: 0.3 would always take 0.3 seconds, but you can also define a range as an object like duration: {min: 0.2, max: 3} to clamp it within the provided range, based on the velocity. That way, if the user stops scrolling close to a snapping point, it'd take less time to snap than if the natural stopping point is far from a snapping point. Something like this: snap: { duration: { min: 0.5, max: 1, } } But those values can't be altered as the ScrollTrigger instance is snapping though. Hopefully this helps. Happy Tweening!
  6. Hello everyone, I'm currently trying to replicate the effect demonstrated in the uploaded GIF. While I've successfully implemented the easing effect, I'm encountering difficulties with the stagger effect. I've experimented with various approaches, with the latest attempt shown below. I can prepare a CodePen example if needed. Perhaps I'm overlooking something simple. Any guidance or suggestions would be greatly appreciated. Thank you! useGSAP(() => { let proxy = { translate: 0 }, translateSetter = gsap.quickSetter(".video-grid-content-container", "translateY", "px"), clamp = gsap.utils.clamp(-40, 40); ScrollTrigger.create({ onUpdate: (self) => { let translate = clamp(self.getVelocity() / -100); if (Math.abs(translate) > Math.abs(proxy.translate)) { proxy.translate = translate; gsap.to(proxy, { translate: 0, duration: 0.4, stagger: { amount: 10, from: "start" }, overwrite: true, onUpdate: () => translateSetter(proxy.translate) }); } } }); });
  7. Hi, I don't have time to go through all your HTML and CSS, but I believe that is creating a problem where not enough scrolling is generated to accommodate all the animations you want to create, that's why using clamp in the end configuration object forces the animation to be completed in that amount of scroll: let scrollHome = gsap.timeline({ scrollTrigger: { trigger: '#main', start: "top top", end: 'clamp(+=5000)', pin: true, markers: { startColor: 'green', endColor: 'red', }, scrub: 1 } }); You might want to have a look at this video @Cassie made on the subject: Hopefully this helps. Happy Tweening!
  8. Danclp

    ScrollTrigger Issue

    @mvaneijgen Thank you very much for the response. It seems like different people have got their references. Nonetheless, there is no right or wrong. However, I am more towards your direction on day one, too. After studying through your refined codes and cleaning up mine, the visual final shows. However, I have another question. If you look at my JS lines 32 and 33, we previously used. It no longer works after I inserted more lines (refer to JS lines 55 to 61). So, I used the "clamp" to solve the issue. Do you have any idea, and can you enlighten me why? https://codepen.io/danclp/pen/oNOPEWm
  9. Hey! I'm working on a mouse follower using React + TypeScript, following the new useGSAP package recommendations. I'm trying to use quickTo with the rotational direction plugin, but it would only work with degrees in number (also will throw a TS error if using TypeScript). Is this indeed a limitation, or am I missing something here? Created a demo really quick to showcase the scenario. As pointed out in line 48, using the ${rotation}_short syntax for the rotation property won't work along with a quickTo. Sample here: https://codepen.io/joyboyar/pen/WNWRQgw Also, if not this way, what would you recommend to achieve the same "lerp" effect with the rotation while doing the same as "_short" does? Thanks in advance 🫡
  10. OK yes, using Clamp is making it great I want to enhance this experience and set the scroller to snap to each of the boxes while scrolling - would it be possible and how to achieve that ?
  11. I'm not sure what you mean. Are you talking about the first one? That one is probably already half way through the progress of the of it's start and end markers, so that one is already at 100, but that is only for the first one right? You could use a clamp() around your start triggers to make it only play fully no matter what screen size. Otherwise could you be more specific what the blocks are doing now and what you want them to happen?
  12. Hi @DaphneX and welcome to the GSAP Forums! What's causing this is the snap functionality baked into that particular demo, when you add a footer the max height of the scroller is no longer tied to the amount of panels so you have to consider that into the math of the snap logic. This seems to work the way you intend: ScrollTrigger.create({ snap: { snapTo: (progress, self) => { let panelStarts = tops.map(st => st.start), snapScroll = gsap.utils.snap(panelStarts, self.scroll()); // If the current scroll is past the last panel don't snap if (self.scroll() > panelStarts[panels.length - 1]) { return false; } return gsap.utils.normalize(0, ScrollTrigger.maxScroll(window), snapScroll); }, duration: 0.5 } }); Here is a fork of your demo: https://codepen.io/GreenSock/pen/zYXBVGW Hopefully this helps. Happy Tweening!
  13. Yeah, the "target" is telling it which element's scroll to normalize. Typically that's the document.scrollingElement (body or html). So yeah, if you target a sub-element, it just normalizes that. Yes, that was intentional because I honestly didn't think anyone would ever need this feature but I baked it in anyway just in case, but I didn't document it because I wanted to see if anyone would ever even need it. If enough time went by and nobody did, we could consider safely removing it. 🙂 Glad it's fixed now!
  14. Hi @Rodrigo, I hope you're having a great day! Thanks for sharing this, I've tried to apply information i got from the blog you shared in many differnet ways but now i am out of ideas i really don't know what special i should do to make them pin and fade away on scroll!! I hope you've seen the sandbox link for understanding about the collision between horizontal scroll functionality that i have and scrolltrigger function import { useMediaQuery, useRect } from '@studio-freight/hamo' import cn from 'clsx' import gsap from 'gsap' import ScrollTrigger from 'gsap/ScrollTrigger' import { useScroll } from '@/hooks/use-scroll' import { clamp, mapRange } from '@/lib/maths' import { useEffect, useRef, useState } from 'react' import { useWindowSize } from 'react-use' import s from './Horizontal.module.scss' gsap.registerPlugin(ScrollTrigger) export const HorizontalSlides = ({ children }: { children: React.ReactNode }) => { const elementRef = useRef<HTMLDivElement | null>(null); const isMobile = useMediaQuery('(max-width: 800px)') const [wrapperRectRef, wrapperRect] = useRect() const [elementRectRef, elementRect] = useRect() const { height: windowHeight } = useWindowSize() const [windowWidth, setWindowWidth] = useState<number>(0); useScroll(({ scroll }: { scroll: number }) => { setWindowWidth(window.innerWidth); if (!elementRect || !elementRef.current) return const start = wrapperRect.top - windowHeight const end = wrapperRect.top + wrapperRect.height - windowHeight let progress = mapRange(start, end, scroll, 0, 1) progress = clamp(0, progress, 1) const x = progress * (elementRect.width - windowWidth) const cards = Array.from(elementRef.current.children) gsap.to(cards, { x: -x, stagger: 0.033, ease: 'none', duration: 0, }) }) useEffect(() => { if (!elementRef.current) return; const onResize = () => { setWindowWidth(Math.min(window.innerWidth, document.documentElement.offsetWidth)); }; window.addEventListener('resize', onResize, false); onResize(); Array.from(elementRef.current.children).forEach((card, index) => { let tl = gsap.timeline({ scrollTrigger: { trigger: card, start: "left center-=500", end: "right center+=500", scrub: true, markers: true, horizontal: true, pin: true, } }); tl.to(card, {opacity: 0, duration: 1}, 0); }); return () => { window.removeEventListener('resize', onResize, false); ScrollTrigger.getAll().forEach(st => st.kill()); }; }, [windowWidth]); return ( <> <div className={s.wrapper} ref={wrapperRectRef} style={ elementRect && isMobile === false ? { height: elementRect.width + 'px' } : {} } > <div className={s.inner}> {/* {isMobile === false ? ( */} <div ref={(node) => { elementRef.current = node elementRectRef(node) }} className={cn(s.overflow, 'hide-on-mobile')} > {children} </div> {/* ) : ( */} <div className={cn(s.cards, 'hide-on-desktop')}>{children}</div> {/* )} */} </div> </div> </> ) }
  15. I'm not completely sure what it is you're asking, but are you looking for clamp? https://codepen.io/mvaneijgen/pen/abxOGPj?editors=0010
  16. Hi, The issue here is related to the start point of your ScrollTrigger instance as shown in the image: That is without scrolling yet. As you can see the start point has already been passed. This can be solved with ScrollTrigger's clamp feature: ScrollTrigger.create({ trigger: ".dotme-widgets-container", pin: true, start: "clamp(top 20%)", ... }); Here is a fork of your demo: https://codepen.io/GreenSock/pen/eYoYmzr Hopefully this helps. Happy Tweening!
  17. Hi, Sorry about the delay in answering 🙏 This boils down mostly to overcomplicating this quite a bit IMHO, the logic you're using right now is probably creating conflicting tweens and/or ScrollTrigger instances. This can be done far simpler as far as I can tell: const sections = gsap.utils.toArray(".section"); const titles = gsap.utils.toArray(".title-wrapper"); // Initial position for all but the first title gsap.set(titles, { yPercent: (i) => i ? 100 : 0, }); const tl = gsap.timeline({ repeat: -1, }); titles.forEach((title, i) => { if (i) { const section = sections[i - 1]; console.log("not first & not last", i); gsap.timeline({ scrollTrigger: { trigger: section, start: "clamp(bottom center)", end: "bottom top", scrub: true, markers: { indent: 150 * i }, id: i + 1, } }) .to(titles[i - 1], { yPercent: -100 }) .to(title, { yPercent: 0 }, "+=0.5"); } }); Here is a fork of your demo: https://codepen.io/GreenSock/pen/yLrBzwY Hopefully this helps. Happy Tweening!
  18. You have to make sure that everything you want to pin is inside a container that you use as the pin container. Then all your code works as expected. (I've also set clamp() around your start, so that it only starts when the visitor starts scrolling. Hope it helps and happy tweening! https://codepen.io/mvaneijgen/pen/GReaQNL
  19. Your thought process is not wrong, but I think you have a logic issue here. You have a timeline with ScrollTrigger and are adding that to a master timeline which also includes another timeline, when should that later timeline start animating? I know you want to animate when the ScrollTrigger is done, but that would not work like this. I've removed your master timeline (btw I would not use TimelineMax that is from an old version of GSAP you can now just directly call gsap.timeline()). I've also removed the function of your ScrollTrigger timeline and have it do it's thing on page load, then I've added an onLeave call back to you ScrollTrigger that fires when you leave the ScrollTrigger eg when it is done animating and then I call your function bobInfinite(). I've also add a clamp to your ScrollTrigger, now it will only start animating when the visitor has really scrolled. Hope it helps and happy tweening! https://codepen.io/mvaneijgen/pen/RwdOgwa?editors=0011 If you want to know why the calculations where all off, this is because GSAP records all the values on page load an then when it needs to animate it just does that, so in your demo on page load it would see where all the dots are and record there positions, but then when everything was done all the positioned changed and all the calculations it did where off. Right now the onLeave ensures that the moment GSAP does it's calculations the elements are at their final position and thus all the calculations are correct
  20. I would set a scale on the image (maybe calculate how much you need the scale to be based ont the window.hight and the image height). Also set the image to object fit cover and add a clamp to the ScrollTrigger, so that it always starts from a point even if it already should be playing. Check out for an explanation. I've modified your pen a bit, to visually see where the image is and the red border shows where it's clipping it off. Hope it helps and happy tweening! https://codepen.io/mvaneijgen/pen/gOEyLLO
  21. Invert the wheelSpeed to a negative value then. And for bounds, you will need to apply JavaScript logic to calculate those and clamp the numbers in the callback.
  22. In case it's useful, I put together a helper function that'll normalize all the values inside a path so that they're between 0 and 1: function normalizePath(path) { path = gsap.utils.toArray(path); if (!path[0].hasAttribute("d")) { path = gsap.utils.toArray(path[0].children); } if (path.length > 1) { path.forEach(normalizePath); return path; } let _svgPathExp = /[achlmqstvz]|(-?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/ig, _scientific = /[\+\-]?\d*\.?\d+e[\+\-]?\d+/ig, d = path[0].getAttribute("d"), a = d.replace(_scientific, m => { let n = +m; return (n < 0.0001 && n > -0.0001) ? 0 : n; }).match(_svgPathExp), nums = a.filter(n => !isNaN(n)).map(n => +n), normalize = gsap.utils.normalize(Math.min(...nums), Math.max(...nums)), finals = a.map(val => isNaN(val) ? val : normalize(+val)), s = "", prevWasCommand; finals.forEach((value, i) => { let isCommand = isNaN(value) s += (isCommand && i ? " " : prevWasCommand || !i ? "" : ",") + value; prevWasCommand = isCommand; }); path[0].setAttribute("d", s); return path; } Usage: normalizePath("#mask") So that'll make a path like this: <path d="M3903,6453.410182017132 L300,1.542786465904 L-10000,1481.542786465904 L-10000,6453.410182017132 Z"></path> Into this: <path d="M0.8449920014268762,1 L0.6260100420554431,0.6078705068325081 L0,0.6978214643317369 L0,1 Z"></path> I hope that helps somebody.
  23. @mvaneijgen Thank you so much for this! So your approach DID work, but for some reason, it made everything so glitchy and slow. however, it did maintain the header/footer of the browser to remain all the time, oh and I cannot PULL TO REFRESH using this approach , maybe I'm doing something wrong? So I tried " ScrollTrigger.config({ ignoreMobileResize: true}) " which I got from the document you provided, and it worked even better. Normalize Scroll Approach: https://candid-churros-7c0625.netlify.app/index2.html Ignore Resize approach: https://candid-churros-7c0625.netlify.app/ Thank you for pointing me in the right direction much appreciated.
  24. Hello im trying to achieve this effect with locomotive scroll Graphic hunters and here is the link to my code on GitHub and here it is live. I tried adding this javascript for scroll trigger and I also added the locomotive scroll for some reason it seems locomotive is maybe making it not work. gsap.registerPlugin(ScrollTrigger); // Call this function when the DOM content has loaded document.addEventListener("DOMContentLoaded", function() { // Initialize other functions like initLoaderHome(), initTimeZone() as needed initLoaderHome(); initMagneticButtons(); initTimeZone(); initBasicFunctions(); initScrolltriggerCheckScroll(); initScroll(); initScrolltriggerAnimations(); }); function initScroll() { let scroll = new LocomotiveScroll({ el: document.querySelector("[data-scroll-container]"), smooth: true, lerp: 0.075, }); scroll.on("scroll", ScrollTrigger.update); ScrollTrigger.scrollerProxy("[data-scroll-container]", { scrollTop(value) { return arguments.length ? scroll.scrollTo(value, 0, 0) : scroll.scroll.instance.scroll.y; }, getBoundingClientRect() { return { top: 0, left: 0, width: window.innerWidth, height: window.innerHeight }; }, pinType: document.querySelector("[data-scroll-container]").style.transform ? "transform" : "fixed", }); window.addEventListener('resize', () => { scroll.update(); ScrollTrigger.refresh(); }); ScrollTrigger.addEventListener("refresh", () => scroll.update()); ScrollTrigger.refresh(); } /** * Scrolltrigger Animations Desktop + Mobile */ function initScrolltriggerAnimations() { // Disable GSAP on Mobile // Source: https://greensock.com/forums/topic/26325-disabling-scrolltrigger-on-mobile-with-mediamatch/ ScrollTrigger.matchMedia({ // Desktop Only Scrolltrigger "(min-width: 1025px)": function() { if (document.querySelector(".bg-img")) { // Scrolltrigger Animation : Example $(".bg-img").each(function(index) { let triggerElement = $(this); let targetElement = $(this); let tl = gsap.timeline({ scrollTrigger: { trigger: triggerElement, start: "100% 100%", end: "150% 0%", scrub: 0, } }); tl.to(targetElement, { opacity: 0, ease: "Power3.easeOut" }); }); } }, // End Desktop Only Scrolltrigger // Mobile Only Scrolltrigger "(max-width: 1024px)": function() { if (document.querySelector(".example")) { // Scrolltrigger Animation : Example $(".example").each(function(index) { let triggerElement = $(this); let targetElement = $(".example"); let tl = gsap.timeline({ scrollTrigger: { trigger: triggerElement, start: "0% 100%", end: "100% 0%", scrub: 0 } }); tl.to(targetElement, { rotate: 90, ease: "none" }); }); } } // End Mobile Only Scrolltrigger }); // End GSAP Matchmedia } but it wont work for some reason, when I apply markers: true it shows fade working but it doesnt work when no markers. I also not my locomotive code is causing that javascript I provide to not work. thats why it wont fade. I have no idea why it would do that.
  25. Hi everyone! The error i stated above shows on my website: "Oops! Trial version of SplitText deployed". It's the GSAP redirect, but i am not using SplitText. I am only using Observer. Below is the code: <!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <title>LuksCommerce | Dein kaffee freund</title> <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.css'><link rel="stylesheet" href="./style.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> </head> <body> <!-- partial:index.partial.html --> <body> <div class="topnav" id="myTopnav" style="z-index:100000;position: absolute;"> <a href="index.html" class="active">Home</a> <a href="uberuns.html">Über uns</a> <a href="produkte.html"> Produkte</a> <a href="kontakt.html">Kontakt</a> <a href="javascript:void(0);" class="icon" onclick="myFunction()"> <i class="fa fa-bars"></i> </a> </div> <section> <div class="outer"> <div class="inner"> <div class="bg home"> <div class="scroll"> <p>Wir sind LuksCommerce</p> <p>Dein Kaffeefreund</p> </div> <img src="main.png" alt="" /> <div class="home-content"> <h1> Schön, dich kennenzulernen! </h1> <p> Wir sind LuksCommerce, der Kumpel, den jede Tasse Kaffee braucht!</br></br> Wir sind seit 2023 auf die Bereitstellung der besten Lösungen für Kaffee- und Heißgetränkezusätze spezialisiert und streben danach, jeden Tag besser zu werden! </br> </br> Unsere Mission ist es, Ihre tägliche Tasse Kaffee und Tee zu einem unvergesslichen Moment zu machen! </p> <ul class="links"> <li> <a href="#" ><ion-icon class="icon" name="logo-apple"></ion-icon ></a> </li> <li> <a href="#" ><ion-icon class="icon" name="logo-google"></ion-icon ></a> </li> <li> <a href="#" ><ion-icon class="icon" name="logo-youtube"></ion-icon ></a> </li> <li> <a href="#" ><ion-icon class="icon" name="logo-instagram"></ion-icon ></a> </li> </ul> </div> </div> </div> </div> <img class="mouse-move" src="https://github.com/ecemgo/mini-samples-great-tricks/assets/13468728/28313e5d-95f1-4e38-ac49-16b4cf006014" alt="" /> </section> <section> <div class="outer"> <div class="inner"> <div class="bg content"> <div class="swiper"> <h2 style= "text-align:center;align-items:center;font-size:30px;font-family:sans-serif;font-weight:100;"> Unsere Partner</h2></br> <div class="swiper-wrapper"> <div class="swiper-slide"> <img src="barbera.png" alt="Barbera" /> <div class="title"> <h2>Caffe Barbera</h2> <p>Beste Kaffeebohnen</p> </div> </div> <div class="swiper-slide"> <img src="theus.png" alt="Theus" /> <div class="title"> <h2>Theus</h2> <p>Herzhafter, duftend Tee</p> </div> </div> <div class="swiper-slide"> <img src="dells.jpg" alt="dells" /> <div class="title"> <h2>Dell's Lemonades</h2> <p>geschmackvolle Toppings</p> </div> </div> <div class="swiper-slide"> <img src="flair.png" alt="FLAIR" /> <div class="title"> <h2>FLAIR</h2> <p>Reines Teekonzentrat</p> </div> </div> </div> </div> </div> <div class="swiper-pagination"></div> </div> </div> </div> </div> </section> <section> <div class="outer"> <div class="inner"> <div class="bg info"> <video id="coffeeVideo" autoplay loop muted> <source src="coffee.mp4" type="video/mp4"> Your browser does not support the video tag. </video> <div class="info-content"> <h1 style="color: rgba(187, 168, 76, 0.87);">Warum LuksCommerce?</h1> <p id="typedText"> </p> <!--<div class="tag-container"> <span>Timeless Hits</span> <span>Selected Playlists</span> <span>Remember & Discover</span> <span>Offline Enjoyment</span> <span>Ad-Free Nostalgia</span> </div>--> </div> </div> </div> </div> </section> <section> <div class="outer"> <div class="inner"> <div class="bg content"> <div class="swiper"> <h2 style= "text-align:center;align-items:center;font-size:30px;font-family:Nunito, sans-serif;font-weight:450; display:block; width: 70%; margin-left: 15%;"> Möchten Sie mit uns zusammenarbeiten? <b>Kontaktiere uns jetzt!</b></h2> <h3 style="font-family:nunito, sans serif; font-weight: 800; font-size: 25px; color:#292f36; display:block; width: 68%;margin-left: 16%; align-items: center; text-align: center; margin-top: 30px;"> Email uns an</br> <b style="font-weight: 300;"><a href="#" style="text-decoration:none;color:#292f36;">kontakt@lukscommerce.at</a></b> </h3> </br> <hr style="width:80%;margin-left: 10%;"> <div class="logolinksss" style="display:block; width: 100%; align-items: center; justify-content: center; text-align:center;"> <ul class="f-links" style="justify-content:center;align-items:center;"> <li> <a href="#"style="height: 30px; width: 30px;" ><ion-icon class="icon" name="logo-google"></ion-icon ></a> </li> <li> <a href="#" ><ion-icon class="icon" name="logo-youtube"></ion-icon ></a> </li> <li> <a href="#"style="height: 25px; width: 25px;" ><ion-icon class="icon" name="logo-instagram"></ion-icon ></a> </li> </ul> </div> <div class="swiper-wrapper"> </div> </div> </div> <div class="swiper-pagination"></div> </div> </div> </div> </div> </section> </body> <!-- partial --> <script src='https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.js'></script> <script src='https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.esm.js'></script> <script src='https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.js'></script> <script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js'></script> <script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/Observer.min.js'></script> <script src="./script.js"></script> <script> function myFunction() { var x = document.getElementById("myTopnav"); if (x.className === "topnav") { x.className += " responsive"; } else { x.className = "topnav"; } } document.getElementById('coffeeVideo').addEventListener('click', function() { if (this.muted) { this.muted = false; } else { this.muted = true; } }); const text = "Wenn Sie eine gute Tasse belebenden Kaffee lieben oder gerne an einer heißen Tasse Tee nippen, wissen Sie, wie wichtig die kleinen Momente im Leben sind.Deshalb sind wir hier, um diese kleinen Momente unvergesslich zu machen!Mit einer großen Auswahl von über 100 Produkten und einer lebenslangen Zusammenarbeit mit großen Marken in der HoReCa-Branche bieten wir sowohl dem Normalverbraucher als auch den großen Unternehmen eine Lösung! \n\n Trinken Sie so gut Sie können, genießen Sie jeden Schluck!"; const typedTextElement = document.getElementById('typedText'); let index = 0; function type() { typedTextElement.textContent += text[index]; index++; if (index < text.length) { setTimeout(type, 30); // Adjust the delay (in milliseconds) for typing speed } } type(); </script> </body> </html> // GSAP gsap.registerPlugin(Observer); console.clear(); let sections = document.querySelectorAll("section"), background = document.querySelectorAll(".bg"), outerWrappers = gsap.utils.toArray(".outer"), innerWrappers = gsap.utils.toArray(".inner"), currentIndex = -1, wrap = gsap.utils.wrap(0, sections.length - 1), animating; let clamp = gsap.utils.clamp(0, sections.length - 1); gsap.set(outerWrappers, { yPercent: 100 }); gsap.set(innerWrappers, { yPercent: -100 }); function gotoSection(index, direction) { index = clamp(index); // make sure it's valid // If they are the same, it's either the first or last slide if (index === currentIndex) { return; } animating = true; let fromTop = direction === -1, dFactor = fromTop ? -1 : 1, tl = gsap.timeline({ defaults: { duration: 1.25, ease: "power1.inOut" }, onComplete: () => (animating = false), }); if (currentIndex >= 0) { // The first time this function runs, current is -1 gsap.set(sections[currentIndex], { zIndex: 0 }); tl.to(background[currentIndex], { yPercent: -15 * dFactor }).set( sections[currentIndex], { autoAlpha: 0 } ); } gsap.set(sections[index], { autoAlpha: 1, zIndex: 1 }); tl.fromTo( [outerWrappers[index], innerWrappers[index]], { yPercent: (i) => (i ? -100 * dFactor : 100 * dFactor) }, { yPercent: 0 }, 0 ).fromTo(background[index], { yPercent: 15 * dFactor }, { yPercent: 0 }, 0); currentIndex = index; return tl; } Observer.create({ type: "wheel, pointer", wheelSpeed: -1, onDown: () => { !animating && gotoSection(currentIndex - 1, -1); }, onUp: () => { !animating && gotoSection(currentIndex + 1, 1); }, tolerance: 200, allowClicks: true, preventDefault: true, }); gotoSection(0, 1).progress(1); // SWIPER var swiper = new Swiper(".swiper", { effect: "coverflow", grabCursor: true, centeredSlides: true, initialSlide: 1, slidesPerView: "auto", coverflowEffect: { rotate: 50, stretch: 0, depth: 100, modifier: 1, slideShadows: false, }, pagination: { el: ".swiper-pagination", }, });
×
×
  • Create New...