diff options
author | Sophie Zhang <sophie_zhang@brown.edu> | 2024-04-11 11:11:58 -0400 |
---|---|---|
committer | Sophie Zhang <sophie_zhang@brown.edu> | 2024-04-11 11:11:58 -0400 |
commit | cd3176b1712ae23e41b2b428e23b39e6a4b32861 (patch) | |
tree | e38caee51678d2582a688b82965259520e3f590f /src | |
parent | 64dbcf06fdae7e5d0c8b69210e7b0e8ef169282d (diff) |
fix: start effect when doc is in viewport
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 16 | ||||
-rw-r--r-- | src/client/views/nodes/trails/PresBox.tsx | 8 | ||||
-rw-r--r-- | src/client/views/nodes/trails/SlideEffect.scss | 8 | ||||
-rw-r--r-- | src/client/views/nodes/trails/SlideEffect.tsx | 44 |
4 files changed, 51 insertions, 25 deletions
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index ede473078..eaa2c6abc 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1020,20 +1020,22 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document ...springMappings['gentle'], }; } + + const transitionTime = presEffectDoc?.presentation_transition ? NumCast(presEffectDoc?.presentation_transition) : 500; //prettier-ignore switch (StrCast(presEffectDoc?.presentation_effect, StrCast(presEffectDoc?.followLinkAnimEffect))) { default: // package used: react-awesome-reveal case PresEffect.None: return renderDoc; - case PresEffect.Zoom: return <SlideEffect dir={dir as PresEffectDirection} presEffect={PresEffect.Zoom} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SlideEffect> - case PresEffect.Fade: return <SlideEffect dir={dir as PresEffectDirection} presEffect={PresEffect.Fade} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SlideEffect> - case PresEffect.Flip: return <SlideEffect dir={dir as PresEffectDirection} presEffect={PresEffect.Flip} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SlideEffect> - case PresEffect.Rotate: return <SlideEffect dir={dir as PresEffectDirection} presEffect={PresEffect.Rotate} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SlideEffect> + case PresEffect.Zoom: return <SlideEffect doc={root} delay={transitionTime} dir={dir as PresEffectDirection} presEffect={PresEffect.Zoom} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SlideEffect> + case PresEffect.Fade: return <SlideEffect doc={root} delay={transitionTime} dir={dir as PresEffectDirection} presEffect={PresEffect.Fade} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SlideEffect> + case PresEffect.Flip: return <SlideEffect doc={root} delay={transitionTime} dir={dir as PresEffectDirection} presEffect={PresEffect.Flip} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SlideEffect> + case PresEffect.Rotate: return <SlideEffect doc={root} delay={transitionTime} dir={dir as PresEffectDirection} presEffect={PresEffect.Rotate} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SlideEffect> // Potential change to move in since anything can be "bouncy" - case PresEffect.Bounce: return <SlideEffect dir={dir as PresEffectDirection} presEffect={PresEffect.Bounce} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SlideEffect> - case PresEffect.Roll: return <SlideEffect dir={dir as PresEffectDirection} presEffect={PresEffect.Roll} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SlideEffect> - case PresEffect.Lightspeed: return <SlideEffect dir={dir as PresEffectDirection} presEffect={PresEffect.Lightspeed} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SlideEffect>; + case PresEffect.Bounce: return <SlideEffect doc={root} delay={transitionTime} dir={dir as PresEffectDirection} presEffect={PresEffect.Bounce} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SlideEffect> + case PresEffect.Roll: return <SlideEffect doc={root} delay={transitionTime} dir={dir as PresEffectDirection} presEffect={PresEffect.Roll} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SlideEffect> + case PresEffect.Lightspeed: return <SlideEffect doc={root} delay={transitionTime} dir={dir as PresEffectDirection} presEffect={PresEffect.Lightspeed} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SlideEffect>; } // switch (StrCast(presEffectDoc?.presentation_effect, StrCast(presEffectDoc?.followLinkAnimEffect))) { // default: diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 3b712a4af..3d13f0dde 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -1946,7 +1946,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { if (activeItem && this.targetDoc) { const transitionSpeed = activeItem.presentation_transition ? NumCast(activeItem.presentation_transition) / 1000 : 0.5; const zoom = NumCast(activeItem.config_zoom, 1) * 100; - const effect = activeItem.presentation_effect ? activeItem.presentation_effect : PresMovement.None; + const effect = activeItem.presentation_effect ? activeItem.presentation_effect : PresEffect.None; return ( <> @@ -2271,7 +2271,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { value={timingConfig.stiffness} onChange={(e, val) => { if (!timingConfig) return; - this.updateEffectTiming(activeItem, { ...timingConfig, stiffness: val as number }); + this.updateEffectTiming(activeItem, { ...timingConfig, type: SpringType.CUSTOM, stiffness: val as number }); }} valueLabelDisplay="auto" /> @@ -2289,7 +2289,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { value={timingConfig.damping} onChange={(e, val) => { if (!timingConfig) return; - this.updateEffectTiming(activeItem, { ...timingConfig, damping: val as number }); + this.updateEffectTiming(activeItem, { ...timingConfig, type: SpringType.CUSTOM, damping: val as number }); }} valueLabelDisplay="auto" /> @@ -2307,7 +2307,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { value={timingConfig.mass} onChange={(e, val) => { if (!timingConfig) return; - this.updateEffectTiming(activeItem, { ...timingConfig, mass: val as number }); + this.updateEffectTiming(activeItem, { ...timingConfig, type: SpringType.CUSTOM, mass: val as number }); }} valueLabelDisplay="auto" /> diff --git a/src/client/views/nodes/trails/SlideEffect.scss b/src/client/views/nodes/trails/SlideEffect.scss index 6a9e93028..144052c1f 100644 --- a/src/client/views/nodes/trails/SlideEffect.scss +++ b/src/client/views/nodes/trails/SlideEffect.scss @@ -7,10 +7,10 @@ .flip-side { position: absolute; - max-width: 500px; - max-height: 500px; - width: 350px; - height: 200px; + // max-width: 500px; + // max-height: 500px; + // width: 350px; + // height: 200px; will-change: transform, opacity; backface-visibility: hidden; } diff --git a/src/client/views/nodes/trails/SlideEffect.tsx b/src/client/views/nodes/trails/SlideEffect.tsx index 3e64cedd4..d4dfae059 100644 --- a/src/client/views/nodes/trails/SlideEffect.tsx +++ b/src/client/views/nodes/trails/SlideEffect.tsx @@ -1,9 +1,15 @@ -import { useSpring, animated, easings, to } from '@react-spring/web'; +import { useSpring, animated, easings, to, useInView } from '@react-spring/web'; import React, { useEffect, useState } from 'react'; import { PresEffect, PresEffectDirection } from './PresEnums'; import './SlideEffect.scss'; +import { Doc } from '../../../../fields/Doc'; +import { NumCast } from '../../../../fields/Types'; interface Props { + // pass in doc to extract width, height, bg + doc: Doc; + // wait for the transition movement to end before starting effect + delay: number; dir: PresEffectDirection; presEffect: PresEffect; friction: number; @@ -13,7 +19,8 @@ interface Props { } // TODO: add visibility detector when the slide comes into view -export default function SpringAnimation({ dir, friction, tension, mass, presEffect, children }: Props) { +export default function SpringAnimation({ doc, delay, dir, friction, tension, mass, presEffect, children }: Props) { + console.log('delay:', delay); const [springs, api] = useSpring( () => ({ from: { @@ -36,6 +43,9 @@ export default function SpringAnimation({ dir, friction, tension, mass, presEffe }), [tension, friction, mass] ); + const [ref, inView] = useInView({ + once: true, + }); // Whether the animation is currently playing const [animating, setAnimating] = useState(false); @@ -233,22 +243,26 @@ export default function SpringAnimation({ dir, friction, tension, mass, presEffe const getRenderDoc = () => { switch (presEffect) { case PresEffect.Rotate: - return <animated.div style={{ transform: to(springs.x, val => `rotate(${val}deg)`) }}>{children}</animated.div>; + return ( + <animated.div ref={ref} style={{ transform: to(springs.x, val => `rotate(${val}deg)`) }}> + {children} + </animated.div> + ); case PresEffect.Flip: return ( // Pass in doc dimensions - <div className="flip-container"> + <div className="flip-container" ref={ref}> {dir === PresEffectDirection.Bottom || dir === PresEffectDirection.Top ? ( <> - <animated.div className={'flip-side flip-back'} style={{ transform: to(springs.x, val => `perspective(600px) rotateX(${val}deg)`) }} /> - <animated.div className={'flip-side flip-front'} style={{ transform: to(springs.x, val => `perspective(600px) rotateX(${val}deg)`), rotateX: '180deg' }}> + <animated.div className={'flip-side flip-back'} style={{ transform: to(springs.x, val => `perspective(600px) rotateX(${val}deg)`), width: NumCast(doc.width), height: NumCast(doc.height) }} /> + <animated.div className={'flip-side flip-front'} style={{ transform: to(springs.x, val => `perspective(600px) rotateX(${val}deg)`), rotateX: '180deg', width: NumCast(doc.width), height: NumCast(doc.height) }}> {children} </animated.div> </> ) : ( <> - <animated.div className={'flip-side flip-back'} style={{ transform: to(springs.x, val => `perspective(600px) rotateY(${val}deg)`) }} /> - <animated.div className={'flip-side flip-front'} style={{ transform: to(springs.x, val => `perspective(600px) rotateY(${val}deg)`), rotateX: '180deg' }}> + <animated.div className={'flip-side flip-back'} style={{ transform: to(springs.x, val => `perspective(600px) rotateY(${val}deg)`), width: NumCast(doc.width), height: NumCast(doc.height) }} /> + <animated.div className={'flip-side flip-front'} style={{ transform: to(springs.x, val => `perspective(600px) rotateY(${val}deg)`), rotateY: '180deg', width: NumCast(doc.width), height: NumCast(doc.height) }}> {children} </animated.div> </> @@ -258,6 +272,7 @@ export default function SpringAnimation({ dir, friction, tension, mass, presEffe default: return ( <animated.div + ref={ref} style={{ ...springs, }}> @@ -267,12 +282,21 @@ export default function SpringAnimation({ dir, friction, tension, mass, presEffe } }; + // useEffect(() => { + // // TODO: Control start with slide visibility instead + // setTimeout(() => { + // startAnimation(); + // }, 200); + // }, []); + useEffect(() => { + if (!inView) return; + console.log('in view'); // TODO: Control start with slide visibility instead setTimeout(() => { startAnimation(); - }, 200); - }, []); + }, 100); + }, [inView]); return <div>{getRenderDoc()}</div>; } |