Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...

Mila A

Members
  • Posts

    3
  • Joined

  • Last visited

Mila A's Achievements

  1. I am trying to create some animation overlays over the video and GSAP is so so helpful!😀
  2. Hi! Thank you so much for your reply! I've been browsing few more tutorials today, especially the official GSAP React tutorial, and I think the problem why everything withmy code was so laggy was that I was creating timeline ( gsap.timeline() ) in a state variable. I swicthed to creating it in the useEffect and also have updated few progress calculating algorithms and it seems to work: const RightTitle = React.memo( ({ videoRef, setStyle, range, name, currentTime, isPreview, type, isVisible, style, title, subtitle, }: RightTitleProps) => { const titleRef = React.useRef(); const tl = React.useRef(); const videoTl = React.useRef(); useEffect( () => { return () => { videoTl.current.kill(); tl.current.kill(); } // just clearing the animation out before next render }, [] ); useEffect( () => { if ( !videoTl.current || !tl.current ) { return; } videoTl.current.seek( currentTime - range.timeIntervals[ 0 ] ); tl.current.seek( currentTime - range.timeIntervals[ 0 ] ); }, [ currentTime ] ); useEffect( () => { videoTl.current = gsap.timeline( { paused : true } ) .fromTo( videoRef, { width : '100%', }, { width : '63%', duration : 1 } ) .to(videoRef, { width : '63%', duration : range.timeIntervals[ 1 ] - range.timeIntervals[ 0 ] - 1 - 1, }) .to(videoRef, { duration : 1, width : '100%', }); }, [ videoRef ] ); useEffect(() => { tl.current = gsap.timeline( { paused : true } ) .fromTo( titleRef.current, { x : name === 'Right Title' ? 150 : -150 }, { x : 0, duration : 1 } ) .to(titleRef.current, { x : 0, duration : range.timeIntervals[ 1 ] - range.timeIntervals[ 0 ] - 1 - 1, }) .to(titleRef.current, { duration : 1, x: name === 'Right Title' ? 150 : -150, }); console.log( 'title ref getting updated', ); }, [ titleRef.current ]); useEffect( () => { if ( !videoTl.current || !tl.current ) { return; } videoTl.current.duration( range.timeIntervals[ 1 ] - range.timeIntervals[ 0 ] ); tl.current.duration( range.timeIntervals[ 1 ] - range.timeIntervals[ 0 ] ); }, [ currentTime, range.timeIntervals ] ); const show = isVisible; if ( isPreview ) { return <div style={{ transform : `${ name === 'Right Title' ? 150 : -150 }px`, top: type === 'smaller' && 0, height: type === 'smaller' && '100%', ...style }} className={RightTitleStyles.aligningWrapper} > <div style={{ transform: isPreview && 'scale(0.55)' }}> <h1> {title} </h1> <p> {subtitle} </p>{' '} </div> </div> } return ( <div ref={ titleRef } style={{ transform : `translateX( ${ name === 'Right Title' ? 150 : -150 }px )`, top: type === 'smaller' && 0, height: type === 'smaller' && '100%', ...style }} className={RightTitleStyles.aligningWrapper} > <div style={{ transform: isPreview && 'scale(0.55)' }}> <h1> {title} </h1> <p> {subtitle} </p>{' '} </div> </div> ); } ); I am really happy! Cheers!
  3. I've been struggling with the issue for 3 days, rewriting, refactoring code few times. Please help me if possible, guys. I use ReactJS and GSAP to create different computed animations ( overlays over a video ). What happens is that when I seek to specific percentage completed, for example 0.19 out of 49s timeline total length, it does seek to the first 1s part of the animation timeline cycle, and doesn't show the animation at the stage expected based on the progress percentage. I couldn't upload project to codesandbox as 1) it is nda signed and 2) it says that it has exceeded the 500-module items limit; I'm really sorry for that. Could someone please help me? I can share the source code or give access to my github repository. Thanks in advance everyone! import gsap from 'gsap'; import RightTitleStyles from '../../../../styles/right-title.module.css'; import React from 'react'; interface RightTitleProps { range: Object; name: string; currentTime: number; isPreview: boolean; type: 'smaller' | 'bigger'; isVisible: boolean; style: any; subtitle: string; title: string; } const RightTitle = React.memo( ({ videoRef, setStyle, range, name, currentTime, isPreview, type, isVisible, style, title, subtitle, }: RightTitleProps) => { const titleRef = React.useRef(); const { current: tl } = React.useRef(gsap.timeline({ paused: true })); const [ rangeIntervals, setRangeIntervals ] = React.useState< Array< number > >( range.timeIntervals ); const connectTitleRef = ( el : HTMLElement ) => { if (titleRef.current || !el || !videoRef || isPreview ) { if ( isPreview || !el || rangeIntervals === range.timeIntervals ) { return; } else { tl.killAll(); // just clearing out some tweens for repeated recreation } } tl.progress(1 - (range.timeIntervals[1] - currentTime) / (range.timeIntervals[1] - range.timeIntervals[0])); titleRef.current = el; console.log( titleRef.current.id, videoRef, ); console.log('configuring...'); tl.fromTo(videoRef, { width: '100%' }, { duration: 1, width: '63%' }).to(videoRef, { duration: range.timeIntervals[1] - range.timeIntervals[0] - 1 - 1, width: '63%' }).to(videoRef, { duration: 1, width: '100%' }); console.log( 'video configured', ); tl.fromTo( el, { x: name === 'Right Title' ? 150 : -150 }, { duration: 1, x: 0 }, ) .to(el, { x: 0, duration: range.timeIntervals[1] - range.timeIntervals[0] - 1 - 1, }) .to(`#${ el.id }`, { duration: 1, x: name === 'Right Title' ? 150 : -150, }); console.log(range.timeIntervals[1] - range.timeIntervals[0] - 1 - 1); }; // console.log( style, ); React.useEffect(() => { if (!titleRef.current || isPreview) return; console.log( 'styles applied to titleRef', titleRef.current._gsTransform ); console.log( 'these are tweens', tl.getChildren().map( child => child.vars.x || child.vars.width ) ); console.log( 'these are tweens', tl.getChildren().map( child => child.vars ) ); if (!(range.timeIntervals[0] <= currentTime && currentTime <= range.timeIntervals[1])) { console.log( 'current timing doesn`t fit the intervals' ); setStyle({}); tl.progress(0); return; } setStyle({ marginLeft: name === 'Left Title' ? 'auto' : 'unset', marginRight: name === 'Right Title' ? 'auto' : 'unset', }); tl.progress(1 - (range.timeIntervals[1] - currentTime) / (range.timeIntervals[1] - range.timeIntervals[0])); console.log(range.timeIntervals[1] - range.timeIntervals[0] - 1 - 1) console.log( currentTime, range.timeIntervals, 1 - (range.timeIntervals[1] - currentTime) / (range.timeIntervals[1] - range.timeIntervals[0]), ); }, [range.timeIntervals, currentTime]); const show = isVisible; if ( isPreview ) { return <div style={{ top: type === 'smaller' && 0, height: type === 'smaller' && '100%', ...style }} className={RightTitleStyles.aligningWrapper} > <div style={{ transform: isPreview && 'scale(0.55)' }}> <h1> {title} </h1> <p> {subtitle} </p>{' '} </div> </div> } return ( <div ref={ connectTitleRef } id={`${isPreview ? 'previewMode' : 'notPreviewMode'}3${range.color.slice(1)}`} style={{ visibility : !( currentTime + 1 >= range.timeIntervals[0] && currentTime - 1 <= range.timeIntervals[1] ) ? 'hidden' : 'visible', top: type === 'smaller' && 0, height: type === 'smaller' && '100%', ...style }} className={RightTitleStyles.aligningWrapper} > <div style={{ transform: isPreview && 'scale(0.55)' }}> <h1> {title} </h1> <p> {subtitle} </p>{' '} </div> </div> ); } ); export default RightTitle; Title.tsx animation.tsx
×