drop multitimeline support from gsap provider but keep scroller priority feature
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
import { Skeleton } from '~/components/ui/skeleton';
|
import { Skeleton } from '~/components/ui/skeleton';
|
||||||
import ChatModal from './_components/ChatModal'
|
import ChatModal from './_components/ChatModal'
|
||||||
import { trpc } from '~/app/_trpc/Client'
|
import { trpc } from '~/app/_trpc/Client'
|
||||||
|
import { useTimeLine } from '~/app/_providers/GsapProvicer';
|
||||||
|
|
||||||
export default function AssistantModalPage() {
|
export default function AssistantModalPage() {
|
||||||
const { data: session, error, isLoading } = trpc.chat.getSession.useQuery();
|
const { data: session, error, isLoading } = trpc.chat.getSession.useQuery();
|
||||||
|
|||||||
@@ -2,20 +2,20 @@
|
|||||||
import { useGSAP } from '@gsap/react'
|
import { useGSAP } from '@gsap/react'
|
||||||
import gsap from 'gsap'
|
import gsap from 'gsap'
|
||||||
import { SplitText } from 'gsap/SplitText'
|
import { SplitText } from 'gsap/SplitText'
|
||||||
import { ScrollTrigger } from 'gsap/all'
|
import { ScrollTrigger, GSDevTools } from 'gsap/all'
|
||||||
import { createContext, useCallback, useContext, useEffect, useLayoutEffect, useRef, type ReactNode } from 'react'
|
import { createContext, useCallback, useContext, useEffect, useRef, type ReactNode } from 'react'
|
||||||
|
|
||||||
gsap.registerPlugin(useGSAP)
|
gsap.registerPlugin(useGSAP)
|
||||||
gsap.registerPlugin(ScrollTrigger)
|
gsap.registerPlugin(ScrollTrigger)
|
||||||
gsap.registerPlugin(SplitText)
|
gsap.registerPlugin(SplitText)
|
||||||
|
gsap.registerPlugin(GSDevTools)
|
||||||
const GsapContext = createContext<{
|
const GsapContext = createContext<{
|
||||||
addAnimation: (
|
addAnimation: (
|
||||||
animation: gsap.core.TimelineChild,
|
animation: gsap.core.TimelineChild,
|
||||||
position: gsap.Position,
|
position: gsap.Position
|
||||||
tlId?:string
|
|
||||||
) => void,
|
) => void,
|
||||||
resetTimeline: (tlId?:string) => void,
|
resetTimeline: () => void,
|
||||||
resumeTimeline: (tlId?:string) => void,
|
resumeTimeline: () => void,
|
||||||
getScroller: () => Element | Window | null
|
getScroller: () => Element | Window | null
|
||||||
} | null>(null)
|
} | null>(null)
|
||||||
|
|
||||||
@@ -23,31 +23,29 @@ export function useGsapContext() {
|
|||||||
return useContext(GsapContext)
|
return useContext(GsapContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useTimeLine = (dep?:any,all?:boolean,tlId?:string,) => {
|
export const useTimeLine = (dep:any,all?:boolean) => {
|
||||||
console.log(tlId)
|
|
||||||
const gsapContext = useGsapContext()
|
const gsapContext = useGsapContext()
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (dep instanceof Array && all) {
|
if (dep instanceof Array && all) {
|
||||||
let acc = true;
|
let acc = true;
|
||||||
let allDepsSatisfied = dep.reduce((p,c) => c !== undefined && p ,acc )
|
let allDepsSatisfied = dep.reduce((p,c) => c !== undefined && p ,acc )
|
||||||
if (allDepsSatisfied) {
|
if (allDepsSatisfied) {
|
||||||
gsapContext?.resumeTimeline(tlId)
|
gsapContext?.resumeTimeline()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (dep) {
|
if (dep) {
|
||||||
gsapContext?.resumeTimeline(tlId)
|
gsapContext?.resumeTimeline()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},[dep])
|
},[dep])
|
||||||
useLayoutEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
gsapContext?.resetTimeline(tlId)
|
gsapContext?.resetTimeline()
|
||||||
}
|
}
|
||||||
},[])
|
},[])
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function GsapProvider({ children,timelines }: { children: ReactNode,timelines?:string[] }) {
|
export default function GsapProvider({ children }: { children: ReactNode }) {
|
||||||
const timeLines = useRef<Map<string,gsap.core.Timeline>|null>(null)
|
|
||||||
const tl = useRef<gsap.core.Timeline | null>(null)
|
const tl = useRef<gsap.core.Timeline | null>(null)
|
||||||
const scrollerRef = useRef<Element | Window | null>(null)
|
const scrollerRef = useRef<Element | Window | null>(null)
|
||||||
const getScroller = useCallback(() => {
|
const getScroller = useCallback(() => {
|
||||||
@@ -73,53 +71,28 @@ export default function GsapProvider({ children,timelines }: { children: ReactNo
|
|||||||
return scrollerRef.current
|
return scrollerRef.current
|
||||||
}, [])
|
}, [])
|
||||||
useGSAP(() => {
|
useGSAP(() => {
|
||||||
if (!timeLines.current && timelines) {
|
|
||||||
timeLines.current = new Map()
|
|
||||||
}
|
|
||||||
timelines?.forEach((tlId) => {
|
|
||||||
timeLines.current?.set(tlId,gsap.timeline({id:tlId,paused:true}))
|
|
||||||
})
|
|
||||||
if (!tl.current) {
|
if (!tl.current) {
|
||||||
tl.current = gsap.timeline({ paused: true })
|
tl.current = gsap.timeline({ paused: true, id:'mainTimeline', onComplete: ()=>{
|
||||||
|
console.log('timeline revert')
|
||||||
|
gsap.getById('mainTimeline')?.revert()
|
||||||
|
} })
|
||||||
}
|
}
|
||||||
return () => { console.log("gsap cleanup") }
|
return () => { console.log("gsap cleanup") }
|
||||||
})
|
})
|
||||||
|
|
||||||
const addAnimation = useCallback((animation: gsap.core.TimelineChild, position: gsap.Position,tlId?:string) => {
|
const addAnimation = useCallback((animation: gsap.core.TimelineChild, position: gsap.Position) => {
|
||||||
if(tlId) {
|
|
||||||
const selectedTimeLine = timeLines.current?.get(tlId)
|
|
||||||
console.log("add animation to:", position, selectedTimeLine !== undefined)
|
|
||||||
selectedTimeLine?.add(animation,position)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
console.log("add animation to:", position, tl.current !== undefined)
|
console.log("add animation to:", position, tl.current !== undefined)
|
||||||
tl.current?.add(animation, position);
|
tl.current?.add(animation, position);
|
||||||
},[])
|
},[])
|
||||||
const resetTimeline = useCallback((tlId?:string) => {
|
const resetTimeline = useCallback(() => {
|
||||||
console.log("resetting timeline",tlId)
|
|
||||||
if (tlId) {
|
|
||||||
let selectedTimeLine = timeLines.current?.get(tlId)
|
|
||||||
selectedTimeLine?.kill()
|
|
||||||
selectedTimeLine?.revert()
|
|
||||||
timeLines.current?.set(tlId,gsap.timeline({id:tlId,paused:true}))
|
|
||||||
} else {
|
|
||||||
tl.current?.kill()
|
tl.current?.kill()
|
||||||
tl.current?.revert()
|
tl.current?.revert()
|
||||||
|
ScrollTrigger.getAll().forEach(st => st.kill())
|
||||||
tl.current = gsap.timeline({paused:true})
|
tl.current = gsap.timeline({paused:true})
|
||||||
}
|
|
||||||
ScrollTrigger.getAll().forEach(st => {
|
|
||||||
st.kill()
|
|
||||||
})
|
|
||||||
},[])
|
},[])
|
||||||
const resumeTimeline = useCallback((tlId?:string) => {
|
const resumeTimeline = useCallback(() => {
|
||||||
if (tlId) {
|
console.log("resuming timeline:",tl.current)
|
||||||
console.log("trying to resume timeline",tlId)
|
|
||||||
let selectedTimeLine = timeLines.current?.get(tlId)
|
|
||||||
selectedTimeLine?.resume()
|
|
||||||
} else {
|
|
||||||
console.log("resuming default timeline")
|
|
||||||
tl.current?.resume()
|
tl.current?.resume()
|
||||||
}
|
|
||||||
},[])
|
},[])
|
||||||
return (
|
return (
|
||||||
<GsapContext.Provider value={{ addAnimation, resetTimeline, resumeTimeline, getScroller }}>
|
<GsapContext.Provider value={{ addAnimation, resetTimeline, resumeTimeline, getScroller }}>
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ export default async function RootLayout({
|
|||||||
return (
|
return (
|
||||||
<ClerkProvider>
|
<ClerkProvider>
|
||||||
<TrpcProvider>
|
<TrpcProvider>
|
||||||
<GsapProvider timelines={['chat']}>
|
<GsapProvider>
|
||||||
<html lang="en" className={cn(geist.variable, "font-sans", inter.variable)} suppressHydrationWarning>
|
<html lang="en" className={cn(geist.variable, "font-sans", inter.variable)} suppressHydrationWarning>
|
||||||
<head>
|
<head>
|
||||||
<CodeHighlightStyle />
|
<CodeHighlightStyle />
|
||||||
|
|||||||
Reference in New Issue
Block a user