aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSophie Zhang <sophie_zhang@brown.edu>2024-04-11 11:11:58 -0400
committerSophie Zhang <sophie_zhang@brown.edu>2024-04-11 11:11:58 -0400
commitcd3176b1712ae23e41b2b428e23b39e6a4b32861 (patch)
treee38caee51678d2582a688b82965259520e3f590f /src
parent64dbcf06fdae7e5d0c8b69210e7b0e8ef169282d (diff)
fix: start effect when doc is in viewport
Diffstat (limited to 'src')
-rw-r--r--src/client/views/nodes/DocumentView.tsx16
-rw-r--r--src/client/views/nodes/trails/PresBox.tsx8
-rw-r--r--src/client/views/nodes/trails/SlideEffect.scss8
-rw-r--r--src/client/views/nodes/trails/SlideEffect.tsx44
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>;
}