Jump to content
Search Community

zank

Business
  • Posts

    11
  • Joined

  • Last visited

Community Answers

  1. zank's post in Gsap with astro view transitions integration was marked as the answer   
    Thanks,
     
    If others may need I m currently using
     
    import gsap from "gsap";   export class LifecycleManager {     public ctx: gsap.Context | null;       private boundAfterSwapHandler: () => void;     private boundPageLoadHandlers: Map<string, () => void>;       constructor() {         this.ctx = null;         this.boundAfterSwapHandler = this.onChangePage.bind(this);         this.boundPageLoadHandlers = new Map();         document.addEventListener("astro:after-swap", this.boundAfterSwapHandler);     }       /**      * Initialize the context      */     initializeContext(): void {         if (this.ctx === null) {             this.ctx = gsap.context(() => {});         }     }       /**      * Check if the component with the given ID exist in the DOM      * @param id id of the element      * @returns boolean      */     elementExists(id: string): boolean {         if (!id) throw new Error("ID cannot be null");         return document.getElementById(id) !== null;     }       /**      * Execute the callback when the page is loaded and the component is visible      * @param id id of the element      * @param callback callback function      */     onElementLoaded(id: string, callback: (ctx: gsap.Context | null) => void): void {         if (!this.boundPageLoadHandlers.has(id)) {             const handler = () => this.onPageLoad(id, callback);             this.boundPageLoadHandlers.set(id, handler);             document.addEventListener("astro:page-load", handler);         }     }       /**      * Callback for the page load event      * @param id id of the element      * @param callback      */     onPageLoad(id: string, callback: (ctx: gsap.Context | null) => void): void {         if (this.elementExists(id)) {             this.initializeContext();             callback(this.ctx);         }     }       /**      * Revert the context      */     revertContext() {         if (this.ctx !== null) {             this.ctx.revert();             this.ctx = null;         }     }       /**      * When changing page revert the context      *  and remove the event listeners      */     onChangePage(): void {         this.revertContext();     }       /**      * Cleanup all event listeners      */     cleanup(): void {         this.revertContext();         document.removeEventListener("astro:after-swap", this.boundAfterSwapHandler);         this.boundPageLoadHandlers.forEach((handler, id) => {             document.removeEventListener("astro:page-load", handler);         });         this.boundPageLoadHandlers.clear();     } }   export default LifecycleManager;  
    usage
     
      <script>     import gsap from "gsap";     import { ScrollTrigger } from "gsap/ScrollTrigger";     import { SplitText } from "gsap/SplitText";     import { LifecycleManager } from "@/services";       gsap.registerPlugin(ScrollTrigger, SplitText);       let manager = new LifecycleManager();       manager.executeWhenVisible("hero", () => {         manager.ctx?.add(() => {             const childSplit = new SplitText("[data-hero-text-reveal]", {                 type: "lines",                 linesClass: "split-child",             });             const parentSplit = new SplitText("[data-hero-text-reveal]", {                 // type: "lines",                 linesClass: "split-parent",             });               gsap.timeline()                 .set("[data-hero-text-reveal]", { opacity: 1 })                 .from(childSplit.lines, {                     yPercent: 300,                     skewY: 7,                     stagger: 0.2,                 })                 .to(                     "[data-hero-reveal]",                     {                         opacity: 1,                         stagger: 0.1,                     },                     "<=",                 );               const pathsToAnimate = document.querySelectorAll(                 '[wb-element="path-to-animate"]',             );               pathsToAnimate.forEach((path) => {                 const finalPath = path.getAttribute("wb-final-path");                   gsap.timeline({                     scrollTrigger: {                         trigger: path,                         start: "top bottom",                         end: "bottom top",                         scrub: 1,                     },                 }).to(path, {                     attr: { d: finalPath || "" },                     ease: "none",                 });             });         });     }); </script>  
     
×
×
  • Create New...