aboutsummaryrefslogtreecommitdiff
path: root/src/client/views
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views')
-rw-r--r--src/client/views/PinFuncs.ts2
-rw-r--r--src/client/views/PropertiesView.tsx2
-rw-r--r--src/client/views/animationtimeline/Timeline.tsx2
-rw-r--r--src/client/views/nodes/DocumentView.tsx18
-rw-r--r--src/client/views/nodes/trails/PresBox.tsx50
-rw-r--r--src/client/views/nodes/trails/PresEnums.ts2
-rw-r--r--src/client/views/nodes/trails/SlideEffect.scss2
-rw-r--r--src/client/views/nodes/trails/SlideEffect.tsx402
-rw-r--r--src/client/views/nodes/trails/SpringUtils.ts2
9 files changed, 120 insertions, 362 deletions
diff --git a/src/client/views/PinFuncs.ts b/src/client/views/PinFuncs.ts
index 3d998ecaf..430455644 100644
--- a/src/client/views/PinFuncs.ts
+++ b/src/client/views/PinFuncs.ts
@@ -54,7 +54,7 @@ export function PinDocView(pinDocIn: Doc, pinProps: PinProps, targetDoc: Doc) {
pinDoc.config_width = NumCast(targetDoc.width);
pinDoc.config_height = NumCast(targetDoc.height);
}
- if (pinProps.pinAudioPlay) pinDoc.presPlayAudio = true;
+ if (pinProps.pinAudioPlay) pinDoc.presentation_playAudio = true;
if (pinProps.pinData) {
pinDoc.config_pinData =
pinProps.pinData.scrollable ||
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index df4ed98ac..024db82a4 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -1487,7 +1487,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
onChange={e => this.changeAnimationBehavior(e.currentTarget.value)}
value={StrCast(this.sourceAnchor?.followLinkAnimEffect, 'default')}>
<option value="default">Default</option>
- {[PresEffect.None, PresEffect.Zoom, PresEffect.Lightspeed, PresEffect.Fade, PresEffect.Flip, PresEffect.Rotate, PresEffect.Bounce, PresEffect.Roll].map(effect => (
+ {[PresEffect.None, PresEffect.Expand, PresEffect.Lightspeed, PresEffect.Fade, PresEffect.Flip, PresEffect.Rotate, PresEffect.Bounce, PresEffect.Roll].map(effect => (
<option key={effect.toString()} value={effect.toString()}>
{effect.toString()}
</option>
diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx
index c4d35330b..d9ff21035 100644
--- a/src/client/views/animationtimeline/Timeline.tsx
+++ b/src/client/views/animationtimeline/Timeline.tsx
@@ -547,7 +547,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
<div key="timeline_info" className="info-container" onPointerDown={this.onPanDown} ref={this._infoContainer} onWheel={this.onWheelZoom}>
{this.drawTicks()}
<div key="timeline_scrubber" className="scrubber" style={{ transform: `translate(${this._currentBarX}px)` }}>
- <div key="timeline_scrubberhead" className="scrubberhead" onPointerDown={this.onScrubberDown}></div>
+ <div key="timeline_scrubberhead" className="scrubberhead" onPointerDown={this.onScrubberDown} />
</div>
<div key="timeline_trackbox" className="trackbox" ref={this._trackbox} style={{ width: `${this._totalLength}px` }}>
{[...this.children, this._props.Document].map(doc => (
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 6f9e14c1b..c59cd0ee4 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -934,7 +934,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
borderRadius: this.borderRounding,
pointerEvents: this._pointerEvents === 'visiblePainted' ? 'none' : this._pointerEvents, // visible painted means that the underlying doc contents are irregular and will process their own pointer events (otherwise, the contents are expected to fill the entire doc view box so we can handle pointer events here)
}}>
- {this._componentView?.isUnstyledView?.() ? renderDoc : DocumentViewInternal.AnimationEffect(renderDoc, this.Document[Animation], this.Document)}
+ {this._componentView?.isUnstyledView?.() || this.Document.type === DocumentType.CONFIG ? renderDoc : DocumentViewInternal.AnimationEffect(renderDoc, this.Document[Animation], this.Document)}
{borderPath?.jsx}
</div>
);
@@ -958,7 +958,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
duration: Cast(presEffectDoc?.presentation_transition, 'number', Cast(presEffectDoc?.followLinkTransitionTime, 'number', null)),
};
- const timing = StrCast(presEffectDoc?.presEffectTiming);
+ const timing = StrCast(presEffectDoc?.presentation_effectTiming);
let timingConfig: SpringSettings | undefined;
if (timing) {
timingConfig = JSON.parse(timing);
@@ -976,13 +976,13 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
}
switch (StrCast(presEffectDoc?.presentation_effect, StrCast(presEffectDoc?.followLinkAnimEffect))) {
- case PresEffect.Zoom: return <SpringAnimation doc={root} dir={dir} presEffect={PresEffect.Zoom} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SpringAnimation>
- // case PresEffect.Fade: return <SlideEffect doc={root} dir={dir} presEffect={PresEffect.Fade} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SlideEffect>
+ case PresEffect.Expand: return <SpringAnimation doc={root} startOpacity={0} dir={dir} presEffect={PresEffect.Expand} springSettings={timingConfig}>{renderDoc}</SpringAnimation>
+ case PresEffect.Flip: return <SpringAnimation doc={root} startOpacity={0} dir={dir} presEffect={PresEffect.Flip} springSettings={timingConfig}>{renderDoc}</SpringAnimation>
+ case PresEffect.Rotate: return <SpringAnimation doc={root} startOpacity={0} dir={dir} presEffect={PresEffect.Rotate} springSettings={timingConfig}>{renderDoc}</SpringAnimation>
+ case PresEffect.Bounce: return <SpringAnimation doc={root} startOpacity={0} dir={dir} presEffect={PresEffect.Bounce} springSettings={timingConfig}>{renderDoc}</SpringAnimation>
+ case PresEffect.Roll: return <SpringAnimation doc={root} startOpacity={0} dir={dir} presEffect={PresEffect.Roll} springSettings={timingConfig}>{renderDoc}</SpringAnimation>
+ // case PresEffect.Fade: return <SlideEffect doc={root} dir={dir} presEffect={PresEffect.Fade} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SlideEffect>
case PresEffect.Fade: return <Fade {...effectProps}>{renderDoc}</Fade>
- case PresEffect.Flip: return <SpringAnimation doc={root} dir={dir} presEffect={PresEffect.Flip} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SpringAnimation>
- case PresEffect.Rotate: return <SpringAnimation doc={root} dir={dir} presEffect={PresEffect.Rotate} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SpringAnimation>
- case PresEffect.Bounce: return <SpringAnimation doc={root} dir={dir} presEffect={PresEffect.Bounce} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SpringAnimation>
- case PresEffect.Roll: return <SpringAnimation doc={root} dir={dir} presEffect={PresEffect.Roll} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SpringAnimation>
// keep as preset, doesn't really make sense with spring config
case PresEffect.Lightspeed: return <JackInTheBox {...effectProps}>{renderDoc}</JackInTheBox>;
case PresEffect.None:
@@ -1416,7 +1416,7 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
<div className="webBox-textHighlight">
<ObserverJsxParser autoCloseVoidElements key={42} onError={(e: any) => console.log('PARSE error', e)} renderInWrapper={false} jsx={StrCast(this._htmlOverlayText)} />
</div>,
- { ...(this._htmlOverlayEffect ?? {}), presentation_effect: effect ?? PresEffect.Zoom } as any as Doc,
+ { ...(this._htmlOverlayEffect ?? {}), presentation_effect: effect ?? PresEffect.Expand } as any as Doc,
this.Document
)}
</div>
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 69d03ac2e..101f28ae7 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -185,7 +185,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@computed
get currCPoints() {
- const strPoints = this.activeItem.presEaseFunc ? StrCast(this.activeItem.presEaseFunc) : 'ease';
+ const strPoints = this.activeItem.presentation_easeFunc ? StrCast(this.activeItem.presentation_easeFunc) : 'ease';
return EaseFuncToPoints(strPoints);
}
@@ -858,9 +858,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
effect: activeItem,
noSelect: true,
openLocation: targetDoc.type === DocumentType.PRES ? ((OpenWhere.replace + ':' + PresBox.PanelName) as OpenWhere) : OpenWhere.addLeft,
- easeFunc: StrCast(activeItem.presEaseFunc, 'ease') as any,
+ easeFunc: StrCast(activeItem.presentation_easeFunc, 'ease') as any,
zoomTextSelections: BoolCast(activeItem.presentation_zoomText),
- playAudio: BoolCast(activeItem.presPlayAudio),
+ playAudio: BoolCast(activeItem.presentation_playAudio),
playMedia: activeItem.presentation_mediaStart === 'auto',
};
if (activeItem.presentation_openInLightbox) {
@@ -1575,16 +1575,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@undoBatch
updateEaseFunc = (activeItem: Doc) => {
- activeItem.presEaseFunc = activeItem.presEaseFunc === 'linear' ? 'ease' : 'linear';
+ activeItem.presentation_easeFunc = activeItem.presentation_easeFunc === 'linear' ? 'ease' : 'linear';
this.selectedArray.forEach(doc => {
- doc.presEaseFunc = activeItem.presEaseFunc;
+ doc.presentation_easeFunc = activeItem.presentation_easeFunc;
});
};
setEaseFunc = (activeItem: Doc, easeFunc: string) => {
- activeItem.presEaseFunc = easeFunc;
+ activeItem.presentation_easeFunc = easeFunc;
this.selectedArray.forEach(doc => {
- doc.presEaseFunc = activeItem.presEaseFunc;
+ doc.presentation_easeFunc = activeItem.presentation_easeFunc;
});
};
@@ -1602,9 +1602,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@undoBatch
updateEffectTiming = (activeItem: Doc, timing: SpringSettings) => {
- activeItem.presEffectTiming = JSON.stringify(timing);
+ activeItem.presentation_effectTiming = JSON.stringify(timing);
this.selectedArray.forEach(doc => {
- doc.presEffectTiming = activeItem.presEffectTiming;
+ doc.presentation_effectTiming = activeItem.presentation_effectTiming;
});
};
@@ -1829,7 +1829,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@computed get transitionDropdown() {
const { activeItem } = this;
// Retrieving spring timing properties
- const timing = StrCast(activeItem.presEffectTiming);
+ const timing = StrCast(activeItem.presentation_effectTiming);
let timingConfig: SpringSettings | undefined;
if (timing) {
timingConfig = JSON.parse(timing);
@@ -1847,8 +1847,8 @@ 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 = StrCast(activeItem.presentation_effect) ? StrCast(activeItem.presentation_effect) : PresEffect.None;
- const direction = StrCast(activeItem.presentation_effectDirection);
+ const effect = StrCast(activeItem.presentation_effect) ? (StrCast(activeItem.presentation_effect) as any as PresEffect) : PresEffect.None;
+ const direction = StrCast(activeItem.presentation_effectDirection) as PresEffectDirection;
return (
<>
@@ -1876,7 +1876,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
/>
<IconButton
type={Type.TERT}
- color={this.isRecording ? '#2bcaff' : StrCast(Doc.UserDoc().userVariantColor)}
+ color={this.isRecording ? '#2bcaff' : SnappingManager.userVariantColor}
tooltip="Record"
icon={<BiMicrophone size="16px" />}
onClick={() => {
@@ -1894,7 +1894,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
type={Type.TERT}
icon={this.isLoading ? <ReactLoading type="spin" color="#ffffff" width={20} height={20} /> : <AiOutlineSend />}
iconPlacement="right"
- color={StrCast(Doc.UserDoc().userVariantColor)}
+ color={SnappingManager.userVariantColor}
onClick={() => {
this.stopDictation();
this.customizeWithGPT(this.chatInput);
@@ -1919,7 +1919,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
>
Movement
<Dropdown
- color={StrCast(Doc.UserDoc().userColor)}
+ color={SnappingManager.userColor}
formLabel="Movement"
closeOnSelect
items={movementItems}
@@ -1951,11 +1951,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
</div>
{/* Easing function */}
<Dropdown
- color={StrCast(Doc.UserDoc().userColor)}
+ color={SnappingManager.userColor}
formLabel="Easing Function"
closeOnSelect
items={easeItems}
- selectedVal={this.activeItem.presEaseFunc ? (StrCast(this.activeItem.presEaseFunc).startsWith('cubic') ? 'custom' : StrCast(this.activeItem.presEaseFunc)) : 'ease'}
+ selectedVal={this.activeItem.presentation_easeFunc ? (StrCast(this.activeItem.presentation_easeFunc).startsWith('cubic') ? 'custom' : StrCast(this.activeItem.presentation_easeFunc)) : 'ease'}
setSelectedVal={val => {
if (typeof val === 'string') {
if (val !== 'custom') {
@@ -2017,7 +2017,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
type={Type.TERT}
icon={this.isLoading ? <ReactLoading type="spin" color="#ffffff" width={20} height={20} /> : <AiOutlineSend />}
iconPlacement="right"
- color={StrCast(Doc.UserDoc().userVariantColor)}
+ color={SnappingManager.userVariantColor}
onClick={this.customizeAnimations}
/>
</div>
@@ -2053,7 +2053,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
mass: elem.mass,
});
}}>
- <SlideEffect dir={elem.direction as PresEffectDirection} presEffect={elem.effect as PresEffect} tension={elem.stiffness} friction={elem.damping} mass={elem.mass} infinite>
+ <SlideEffect dir={elem.direction} presEffect={elem.effect} springSettings={elem} infinite>
<div className="presBox-effect-demo-box" style={{ backgroundColor: springPreviewColors[i] }} />
</SlideEffect>
</div>
@@ -2062,7 +2062,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
</div>
{/* Effect dropdown */}
<Dropdown
- color={StrCast(Doc.UserDoc().userColor)}
+ color={SnappingManager.userColor}
formLabel="Slide Effect"
closeOnSelect
items={effectItems}
@@ -2126,7 +2126,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
{effect !== PresEffect.Lightspeed && (
<>
<Dropdown
- color={StrCast(Doc.UserDoc().userColor)}
+ color={SnappingManager.userColor}
formLabel="Effect Timing"
closeOnSelect
items={effectTimings}
@@ -2208,7 +2208,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
Preview Effect
<div className="presBox-option-block presBox-option-center">
<div className="presBox-effect-container">
- <SlideEffect dir={direction as PresEffectDirection} presEffect={effect as PresEffect} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass} infinite>
+ <SlideEffect dir={direction} presEffect={effect} springSettings={timingConfig} infinite>
<div className="presBox-effect-demo-box" style={{ backgroundColor: springPreviewColors[0] }} />
</SlideEffect>
</div>
@@ -2224,9 +2224,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
<Toggle
formLabel="Play Audio Annotation"
toggleType={ToggleType.SWITCH}
- toggleStatus={BoolCast(activeItem.presPlayAudio)}
+ toggleStatus={BoolCast(activeItem.presentation_playAudio)}
onClick={() => {
- activeItem.presPlayAudio = !BoolCast(activeItem.presPlayAudio);
+ activeItem.presentation_playAudio = !BoolCast(activeItem.presentation_playAudio);
}}
color={SnappingManager.userColor}
/>
@@ -2239,7 +2239,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}}
color={SnappingManager.userColor}
/>
- <Button text="Apply to all" type={Type.TERT} color={StrCast(Doc.UserDoc().userVariantColor)} onClick={() => this.applyTo(this.childDocs)} />
+ <Button text="Apply to all" type={Type.TERT} color={SnappingManager.userVariantColor} onClick={() => this.applyTo(this.childDocs)} />
</div>
</div>
</>
diff --git a/src/client/views/nodes/trails/PresEnums.ts b/src/client/views/nodes/trails/PresEnums.ts
index 564829d54..67cad9c5d 100644
--- a/src/client/views/nodes/trails/PresEnums.ts
+++ b/src/client/views/nodes/trails/PresEnums.ts
@@ -7,7 +7,7 @@ export enum PresMovement {
}
export enum PresEffect {
- Zoom = 'Zoom',
+ Expand = 'Expand',
Lightspeed = 'Lightspeed',
Fade = 'Fade in',
Flip = 'Flip',
diff --git a/src/client/views/nodes/trails/SlideEffect.scss b/src/client/views/nodes/trails/SlideEffect.scss
index cc851354e..aa2e5bbd9 100644
--- a/src/client/views/nodes/trails/SlideEffect.scss
+++ b/src/client/views/nodes/trails/SlideEffect.scss
@@ -8,7 +8,7 @@
.flip-side {
position: absolute;
will-change: transform, opacity;
- backface-visibility: hidden;
+ // backface-visibility: hidden;
}
.flip-front {
diff --git a/src/client/views/nodes/trails/SlideEffect.tsx b/src/client/views/nodes/trails/SlideEffect.tsx
index 03cd88f45..00039e3cb 100644
--- a/src/client/views/nodes/trails/SlideEffect.tsx
+++ b/src/client/views/nodes/trails/SlideEffect.tsx
@@ -5,358 +5,116 @@ import { Doc } from '../../../../fields/Doc';
import { NumCast } from '../../../../fields/Types';
import { PresEffect, PresEffectDirection } from './PresEnums';
import './SlideEffect.scss';
+import { emptyFunction } from '../../../../Utils';
interface SlideEffectProps {
- // pass in doc to extract width, height, bg
- doc?: Doc;
+ doc?: Doc; // pass in doc to extract width, height, bg
dir: PresEffectDirection;
presEffect: PresEffect;
- // stiffness (figma) = tension (react-spring)
- tension: number;
- // damping (figma) = friction (react-spring)
- friction: number;
- mass: number;
+ springSettings: {
+ stiffness: number;
+ damping: number;
+ mass: number;
+ };
children: React.ReactNode;
infinite?: boolean;
+ startOpacity?: number; // set to zero to linearly fade in while animating
}
const DEFAULT_WIDTH = 40;
const PREVIEW_OFFSET = 60;
const ACTUAL_OFFSET = 200;
-const infiniteOptions = {
- loop: true,
- delay: 500,
-};
/**
* This component wraps around the doc to create an effect animation, and also wraps the preview animations
* for the effects as well.
*/
-export default function SpringAnimation({ doc, dir, friction, tension, mass, presEffect, children, infinite }: SlideEffectProps) {
- const [springs, api] = useSpring(
- () => ({
- from: {
- x: 0,
- y: 0,
- opacity: 0,
- scale: 1,
- },
- config: {
- tension,
- friction,
- mass,
- },
- onStart: () => {},
- onRest: () => {},
- }),
- [tension, friction, mass]
- );
- const [ref, inView] = useInView({
- once: true,
- });
-
- const zoomConfig = {
- from: {
- scale: 0,
- x: 0,
- y: 0,
- opacity: 1,
- },
- to: {
- scale: 1,
- x: 0,
- y: 0,
- opacity: 1,
- config: {
- tension: tension,
- friction: friction,
- mass: mass,
- },
- },
+export default function SpringAnimation({ doc, dir, springSettings, presEffect, children, infinite, startOpacity }: SlideEffectProps) {
+ const expandConfig = {
+ to: { scale: 1, x: 0, y: 0 },
+ from: { scale: 0, x: 0, y: 0 },
};
-
const fadeConfig = {
- from: {
- opacity: 0,
- scale: 1,
- x: 0,
- y: 0,
- },
- to: {
- opacity: 1,
- scale: 1,
- x: 0,
- y: 0,
- config: {
- tension: tension,
- friction: friction,
- mass: mass,
- },
- },
+ to: { x: 0, y: 0 },
+ from: { x: 0, y: 0 },
};
-
const rotateConfig = {
- from: {
- x: 0,
- },
- to: {
- x: 360,
- config: {
- tension: tension,
- friction: friction,
- mass: mass,
- },
- },
+ to: { x: 360, y: 0 },
+ from: { x: 0, y: 0 },
};
-
- const getBounceConfigFrom = () => {
- switch (dir) {
- case PresEffectDirection.Left:
- return {
- from: {
- opacity: 0,
- x: infinite ? -PREVIEW_OFFSET : -ACTUAL_OFFSET,
- y: 0,
- },
- };
- case PresEffectDirection.Right:
- return {
- from: {
- opacity: 0,
- x: infinite ? PREVIEW_OFFSET : ACTUAL_OFFSET,
- y: 0,
- },
- };
- case PresEffectDirection.Top:
- return {
- from: {
- opacity: 0,
- x: 0,
- y: infinite ? -PREVIEW_OFFSET : -ACTUAL_OFFSET,
- },
- };
- case PresEffectDirection.Bottom:
- return {
- from: {
- opacity: 0,
- x: 0,
- y: infinite ? PREVIEW_OFFSET : ACTUAL_OFFSET,
- },
- };
- default:
- // no movement for center
- return {
- from: {
- opacity: 0,
- x: 0,
- y: 0,
- },
- };
- }
- };
-
- const bounceConfig = {
- ...getBounceConfigFrom(),
- to: [
- {
- opacity: 1,
- x: 0,
- y: 0,
- config: {
- tension: tension,
- friction: friction,
- mass: mass,
- },
- },
- ],
- };
-
const flipConfig = {
- from: {
- x: 0,
- },
- to: {
- x: 180,
- config: {
- tension: tension,
- friction: friction,
- mass: mass,
- },
- },
+ to: { x: 180, y: 0 },
+ from: { x: 0, y: 0 },
};
-
- // only left and right for now
- const getRollConfigFrom = () => {
- switch (dir) {
- case PresEffectDirection.Left:
- return {
- from: {
- opacity: 0,
- x: -100,
- y: -120,
- },
- };
- case PresEffectDirection.Right:
- return {
- from: {
- opacity: 0,
- x: 100,
- y: 120,
- },
- };
- case PresEffectDirection.Top:
- return {
- from: {
- opacity: 0,
- x: -100,
- y: -120,
- },
- };
- case PresEffectDirection.Bottom:
- return {
- from: {
- opacity: 0,
- x: -100,
- y: -120,
- },
- };
- default:
- // no movement for center
- return {
- from: {
- opacity: 0,
- x: 0,
- y: 0,
- },
- };
- }
+ const bounceConfig = {
+ to: { x: 0, y: 0 },
+ from: (() => {
+ const offset = infinite ? PREVIEW_OFFSET : ACTUAL_OFFSET;
+ switch (dir) {
+ case PresEffectDirection.Left: return { x: -offset, y: 0, };
+ case PresEffectDirection.Right: return { x: offset, y: 0, };
+ case PresEffectDirection.Top: return { x: 0, y: -offset, };
+ case PresEffectDirection.Bottom:return { x: 0, y: offset, };
+ default: return { x: 0, y: 0, }; // no movement for center
+ }})(), // prettier-ignore
};
-
const rollConfig = {
- ...getRollConfigFrom(),
- to: {
- opacity: 1,
- x: 0,
- y: 0,
- config: {
- tension: tension,
- friction: friction,
- mass: mass,
- },
- },
+ to: { x: 0, y: 0 },
+ from: (() => {
+ switch (dir) {
+ case PresEffectDirection.Left: return { x: -100, y: -120, };
+ case PresEffectDirection.Right: return { x: 100, y: 120, };
+ case PresEffectDirection.Top: return { x: -100, y: -120, };
+ case PresEffectDirection.Bottom: return { x: -100, y: -120, };
+ default: return { x: 0, y: 0, }; // no movement for center
+ }})(), // prettier-ignore
};
- // Switch animation depending on slide effect
- const startAnimation = () => {
- api.stop();
- let config: any = zoomConfig;
+ // prettier-ignore
+ const effectConfig = (() => {
switch (presEffect) {
- case PresEffect.Bounce:
- config = bounceConfig;
- break;
- case PresEffect.Zoom:
- config = zoomConfig;
- break;
- case PresEffect.Rotate:
- config = rotateConfig;
- break;
- case PresEffect.Fade:
- config = fadeConfig;
- break;
- case PresEffect.Flip:
- config = flipConfig;
- break;
- case PresEffect.Roll:
- config = rollConfig;
- break;
- case PresEffect.Lightspeed:
- break;
- default:
- break;
- }
-
- if (infinite) {
- config = { ...config, ...infiniteOptions };
- }
+ case PresEffect.Fade: return fadeConfig;
+ case PresEffect.Bounce: return bounceConfig;
+ case PresEffect.Rotate: return rotateConfig;
+ case PresEffect.Flip: return flipConfig;
+ case PresEffect.Roll: return rollConfig;
+ case PresEffect.Lightspeed: return { from: {}, to: {} };
+ case PresEffect.Expand:
+ default: return expandConfig;
+ } // prettier-ignore
+ })();
- api.start(config);
- };
-
- const getRenderDoc = () => {
- switch (presEffect) {
- case PresEffect.Rotate:
- 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" 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)`),
- width: doc ? NumCast(doc.width) : DEFAULT_WIDTH,
- height: doc ? NumCast(doc.height) : DEFAULT_WIDTH,
- backgroundColor: infinite ? '#a825ff' : 'rgb(223, 223, 223);',
- }}
- />
- <animated.div
- className="flip-side flip-front"
- style={{ transform: to(springs.x, val => `perspective(600px) rotateX(${val}deg)`), rotateX: '180deg', width: doc ? NumCast(doc.width) : DEFAULT_WIDTH, height: doc ? NumCast(doc.height) : DEFAULT_WIDTH }}>
- {children}
- </animated.div>
- </>
- ) : (
- <>
- <animated.div
- className="flip-side flip-back"
- style={{ transform: to(springs.x, val => `perspective(600px) rotateY(${val}deg)`), width: doc ? NumCast(doc.width) : DEFAULT_WIDTH, height: doc ? NumCast(doc.height) : DEFAULT_WIDTH }}
- />
- <animated.div
- className="flip-side flip-front"
- style={{ transform: to(springs.x, val => `perspective(600px) rotateY(${val}deg)`), rotateY: '180deg', width: doc ? NumCast(doc.width) : DEFAULT_WIDTH, height: doc ? NumCast(doc.height) : DEFAULT_WIDTH }}>
- {children}
- </animated.div>
- </>
- )}
- </div>
- );
- case PresEffect.Roll:
- return (
- <animated.div ref={ref} style={{ opacity: springs.opacity, transform: to([springs.x, springs.y], (val, val2) => `translate3d(${val}%, 0, 0) rotate3d(0, 0, 1, ${val2}deg)`) }}>
- {children}
- </animated.div>
- );
- default:
- return (
- <animated.div
- ref={ref}
- style={{
- ...springs,
- }}>
- {children}
- </animated.div>
- );
- }
- };
-
- useEffect(() => {
- if (infinite || !inView) return;
- setTimeout(() => {
- startAnimation();
- }, 100);
- }, [inView]);
+ const [springs, api] = useSpring(
+ () => ({
+ to: { ...effectConfig.to, opacity: 1 },
+ from: { ...effectConfig.from, opacity: startOpacity ?? 1 },
+ config: { tension: springSettings.stiffness, friction: springSettings.damping, mass: springSettings.mass },
+ onStart: emptyFunction,
+ onRest: emptyFunction,
+ }),
+ [springSettings]
+ );
+ const [ref, inView] = useInView({
+ once: true,
+ });
useEffect(() => {
- if (infinite) {
- startAnimation();
+ if (inView) {
+ api.start({ loop: infinite, delay: infinite ? 500 : 0 });
}
- }, [presEffect, tension, friction, mass]);
-
- return <div>{getRenderDoc()}</div>;
+ }, [inView]);
+ const animatedDiv = (style: any) => (
+ <animated.div ref={ref} style={{ ...style, opacity: to(springs.opacity, val => `${val}`) }}>
+ {children}
+ </animated.div>
+ );
+ const [width, height] = [NumCast(doc?.width, DEFAULT_WIDTH), NumCast(doc?.height, DEFAULT_WIDTH)];
+ const flipAxis = dir === PresEffectDirection.Bottom || dir === PresEffectDirection.Top ? 'X' : 'Y';
+ const [rotateX, rotateY] = flipAxis === 'X' ? ['180deg', undefined] : [undefined, '180deg'];
+ switch (presEffect) {
+ case PresEffect.Flip: return animatedDiv({ transform: to(springs.x, val => `perspective(600px) rotate${flipAxis}(${val}deg)`), width, height, rotateX, rotateY })
+ case PresEffect.Rotate:return animatedDiv({ transform: to(springs.x, val => `rotate(${val}deg)`) });
+ case PresEffect.Roll: return animatedDiv({ transform: to([springs.x, springs.y], (val, val2) => `translate3d(${val}%, 0, 0) rotate3d(0, 0, 1, ${val2}deg)`) });
+ default: return animatedDiv(springs);
+ } // prettier-ignore
}
diff --git a/src/client/views/nodes/trails/SpringUtils.ts b/src/client/views/nodes/trails/SpringUtils.ts
index bfb22c46a..73e1e14f1 100644
--- a/src/client/views/nodes/trails/SpringUtils.ts
+++ b/src/client/views/nodes/trails/SpringUtils.ts
@@ -80,7 +80,7 @@ export const effectItems = Object.values(PresEffect)
export const presEffectDefaultTimings: {
[key: string]: SpringSettings;
} = {
- Zoom: { type: SpringType.GENTLE, stiffness: 100, damping: 15, mass: 1 },
+ Expand: { type: SpringType.GENTLE, stiffness: 100, damping: 15, mass: 1 },
Bounce: {
type: SpringType.BOUNCY,
stiffness: 600,