diff options
author | Sophie Zhang <sophie_zhang@brown.edu> | 2024-04-04 11:21:28 -0400 |
---|---|---|
committer | Sophie Zhang <sophie_zhang@brown.edu> | 2024-04-04 11:21:28 -0400 |
commit | d8863c3188cf0c4647b70d3dc9ec5f2fffe5525c (patch) | |
tree | bd55bbec719fe1ccc79fbb8b32f95a912e0c2e6d | |
parent | 8ccc55cfdd4ffc868ccf8f8f92fea67697bcaf78 (diff) |
zoom fade rotate
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 9 | ||||
-rw-r--r-- | src/client/views/nodes/trails/PresBox.tsx | 122 | ||||
-rw-r--r-- | src/client/views/nodes/trails/SlideEffect.tsx | 81 | ||||
-rw-r--r-- | src/client/views/nodes/trails/SpringUtils.ts | 111 |
4 files changed, 176 insertions, 147 deletions
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 92f66f2cd..17ebc5b5e 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -47,8 +47,9 @@ import { FieldViewProps, FieldViewSharedProps } from './FieldView'; import { KeyValueBox } from './KeyValueBox'; import { LinkAnchorBox } from './LinkAnchorBox'; import { FormattedTextBox } from './formattedText/FormattedTextBox'; -import { PresEffect, PresEffectDirection, SpringSettings, SpringType } from './trails'; +import { PresEffect, PresEffectDirection } from './trails'; import SlideEffect, { EffectType } from './trails/SlideEffect'; +import { SpringSettings, SpringType } from './trails/SpringUtils'; interface Window { MediaRecorder: MediaRecorder; } @@ -996,7 +997,6 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document */ public static AnimationEffect(renderDoc: JSX.Element, presEffectDoc: Opt<Doc>, root: Doc) { const dir = presEffectDoc?.presentation_effectDirection ?? presEffectDoc?.followLinkAnimDirection; - console.log(dir); const effectProps = { left: dir === PresEffectDirection.Left, right: dir === PresEffectDirection.Right, @@ -1028,9 +1028,10 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document // package used: react-awesome-reveal case PresEffect.None: return renderDoc; case PresEffect.Zoom: return <SlideEffect dir={dir as PresEffectDirection} effectType={EffectType.ZOOM} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SlideEffect> - case PresEffect.Fade: return <Fade {...effectProps}>{renderDoc}</Fade>; + case PresEffect.Fade: return <SlideEffect dir={dir as PresEffectDirection} effectType={EffectType.FADE} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SlideEffect> case PresEffect.Flip: return <Flip {...effectProps}>{renderDoc}</Flip>; - case PresEffect.Rotate: return <Rotate {...effectProps}>{renderDoc}</Rotate>; + case PresEffect.Rotate: return <SlideEffect dir={dir as PresEffectDirection} effectType={EffectType.ROTATE} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SlideEffect> + // Changed to move in since anything can be "bouncy" case PresEffect.Bounce: return <SlideEffect dir={dir as PresEffectDirection} effectType={EffectType.BOUNCE} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>{renderDoc}</SlideEffect> case PresEffect.Roll: return <Roll {...effectProps}>{renderDoc}</Roll>; case PresEffect.Lightspeed: return <JackInTheBox {...effectProps}>{renderDoc}</JackInTheBox>; diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index deb59d03f..8745bf1a4 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -28,7 +28,7 @@ import { CollectionFreeFormView, MarqueeViewBounds } from '../../collections/col import { CollectionStackedTimeline } from '../../collections/CollectionStackedTimeline'; import { CollectionView } from '../../collections/CollectionView'; import { TreeView } from '../../collections/TreeView'; -import { ViewBoxBaseComponent } from '../../DocComponent'; +import { ViewBoxBaseComponent, ViewBoxInterface } from '../../DocComponent'; import { Colors } from '../../global/globalEnums'; import { LightboxView } from '../../LightboxView'; import { DocumentView, OpenWhere, OpenWhereMod } from '../DocumentView'; @@ -47,6 +47,7 @@ import CubicBezierEditor, { TIMING_DEFAULT_MAPPINGS } from './CubicBezierEditor' import Slider from '@mui/material/Slider'; import { FaArrowDown, FaArrowLeft, FaArrowRight, FaArrowUp, FaCompressArrowsAlt } from 'react-icons/fa'; import SpringAnimationPreview from './SlideEffectPreview'; +import { effectTimings, SpringType, springMappings, effectItems, easeItems, movementItems, SpringSettings } from './SpringUtils'; export interface pinDataTypes { scrollable?: boolean; @@ -75,118 +76,6 @@ export interface PinProps { pinData?: pinDataTypes; } -// the type of slide effect timing (spring-driven) -export enum SpringType { - DEFAULT = 'default', - GENTLE = 'gentle', - BOUNCY = 'bouncy', - CUSTOM = 'custom', - QUICK = 'quick', -} - -// settings that control slide effect spring settings -export interface SpringSettings { - type: SpringType; - stiffness: number; - damping: number; - mass: number; -} - -const easeItems = [ - { - text: 'Ease', - val: 'ease', - }, - { - text: 'Ease In', - val: 'ease-in', - }, - { - text: 'Ease Out', - val: 'ease-out', - }, - { - text: 'Ease In Out', - val: 'ease-in-out', - }, - { - text: 'Linear', - val: 'linear', - }, - { - text: 'Custom', - val: 'custom', - }, -]; - -const movementItems = [ - { text: 'None', val: PresMovement.None }, - { text: 'Center', val: PresMovement.Center }, - { text: 'Zoom', val: PresMovement.Zoom }, - { text: 'Pan', val: PresMovement.Pan }, - { text: 'Jump', val: PresMovement.Jump }, -]; - -const effectItems = Object.values(PresEffect) - .filter(v => isNaN(Number(v))) - .map(effect => ({ - text: effect, - val: effect, - })); - -const effectTimings = [ - { text: 'Default', val: SpringType.DEFAULT }, - { - text: 'Gentle', - val: SpringType.GENTLE, - }, - { - text: 'Quick', - val: SpringType.QUICK, - }, - { - text: 'Bouncy', - val: SpringType.BOUNCY, - }, - { - text: 'Custom', - val: SpringType.CUSTOM, - }, -]; - -const springMappings: { - [key: string]: { stiffness: number; damping: number; mass: number }; -} = { - default: { - // stiffness: 300, - // damping: 12, - // mass: 2, - stiffness: 600, - damping: 15, - mass: 1, - }, - gentle: { - stiffness: 100, - damping: 15, - mass: 1, - }, - quick: { - stiffness: 300, - damping: 20, - mass: 1, - }, - bouncy: { - stiffness: 600, - damping: 15, - mass: 1, - }, - custom: { - stiffness: 100, - damping: 10, - mass: 1, - }, -}; - @observer export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { public static LayoutString(fieldKey: string) { @@ -268,7 +157,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { @computed get currCPoints() { - console.log('getting curr c points'); let strPoints = this.activeItem.presEaseFunc ? StrCast(this.activeItem.presEaseFunc) : 'ease'; if (!strPoints.startsWith('cubic')) { switch (StrCast(this.activeItem.presEaseFunc)) { @@ -291,13 +179,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { strPoints = 'cubic-bezier(0.25, 0.1, 0.25, 1.0)'; } } - console.log('str points', strPoints); const components = strPoints .split('(')[1] .split(')')[0] .split(',') .map(elem => parseFloat(elem)); - console.log('bezier components', components); return { p1: [components[0], components[1]], p2: [components[2], components[3]], @@ -386,7 +272,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { }, { fireImmediately: true } ); - this._props.setContentViewBox?.(this); + // Casted to viewboxinterface + this._props.setContentViewBox?.(this as ViewBoxInterface); this._unmounting = false; this.turnOffEdit(true); this._disposers.selection = reaction( @@ -1856,7 +1743,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { Hide </div> </Tooltip> - <Tooltip title={<div className="dash-tooltip">{'Hide after presented'}</div>}> <div className={`ribbon-toggle ${activeItem.presentation_hideAfter ? 'active' : ''}`} diff --git a/src/client/views/nodes/trails/SlideEffect.tsx b/src/client/views/nodes/trails/SlideEffect.tsx index ae25bfb90..af0e7461b 100644 --- a/src/client/views/nodes/trails/SlideEffect.tsx +++ b/src/client/views/nodes/trails/SlideEffect.tsx @@ -1,5 +1,5 @@ import { Button } from '@mui/material'; -import { useSpring, animated, easings } from '@react-spring/web'; +import { useSpring, animated, easings, to } from '@react-spring/web'; import React, { useEffect, useState } from 'react'; import { PresEffectDirection } from './PresEnums'; @@ -7,6 +7,7 @@ export enum EffectType { ZOOM = 'zoom', FADE = 'fade', BOUNCE = 'bounce', + ROTATE = 'rotate', } interface Props { @@ -47,16 +48,52 @@ export default function SpringAnimation({ dir, friction, tension, mass, effectTy const zoomConfig = { from: { + scale: 0, x: 0, y: 0, - opacity: 0, - scale: 0, + opacity: 1, + // opacity: 0, }, to: { + scale: 1, x: 0, y: 0, opacity: 1, + // opacity: 1, + config: { + tension: tension, + friction: friction, + mass: mass, + }, + }, + }; + + 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, + }, + }, + }; + + const rotateConfig = { + from: { + x: 0, + }, + to: { + x: 360, config: { tension: tension, friction: friction, @@ -131,6 +168,10 @@ export default function SpringAnimation({ dir, friction, tension, mass, effectTy api.start(bounceConfig); } else if (effectType === EffectType.ZOOM) { api.start(zoomConfig); + } else if (effectType === EffectType.ROTATE) { + api.start(rotateConfig); + } else if (effectType === EffectType.FADE) { + api.start(fadeConfig); } }; @@ -147,28 +188,18 @@ export default function SpringAnimation({ dir, friction, tension, mass, effectTy // handleClick(); // }} > - {/* style={{ - width: "50px", - height: "50px", - backgroundColor: "#ff6d6d", - borderRadius: "4px", - ...springs, - }} */} - <animated.div - style={{ - // display: 'inline-block', - // transform: 'translate(50px, 50px)', - ...springs, - }}> - {children} - </animated.div> - {/* <Button - onClick={handleClick} - sx={{ marginTop: "100px" }} - variant="contained" - > - Animate - </Button> */} + {effectType !== EffectType.ROTATE ? ( + <animated.div + style={{ + // display: 'inline-block', + // transform: 'translate(50px, 50px)', + ...springs, + }}> + {children} + </animated.div> + ) : ( + <animated.div style={{ transform: to(springs.x, val => `rotate(${val}deg)`) }}>{children}</animated.div> + )} </div> ); } diff --git a/src/client/views/nodes/trails/SpringUtils.ts b/src/client/views/nodes/trails/SpringUtils.ts new file mode 100644 index 000000000..5feb1628a --- /dev/null +++ b/src/client/views/nodes/trails/SpringUtils.ts @@ -0,0 +1,111 @@ +import { PresEffect, PresMovement } from './PresEnums'; + +// the type of slide effect timing (spring-driven) +export enum SpringType { + DEFAULT = 'default', + GENTLE = 'gentle', + BOUNCY = 'bouncy', + CUSTOM = 'custom', + QUICK = 'quick', +} + +// settings that control slide effect spring settings +export interface SpringSettings { + type: SpringType; + stiffness: number; + damping: number; + mass: number; +} + +export const easeItems = [ + { + text: 'Ease', + val: 'ease', + }, + { + text: 'Ease In', + val: 'ease-in', + }, + { + text: 'Ease Out', + val: 'ease-out', + }, + { + text: 'Ease In Out', + val: 'ease-in-out', + }, + { + text: 'Linear', + val: 'linear', + }, + { + text: 'Custom', + val: 'custom', + }, +]; + +export const movementItems = [ + { text: 'None', val: PresMovement.None }, + { text: 'Center', val: PresMovement.Center }, + { text: 'Zoom', val: PresMovement.Zoom }, + { text: 'Pan', val: PresMovement.Pan }, + { text: 'Jump', val: PresMovement.Jump }, +]; + +export const effectItems = Object.values(PresEffect) + .filter(v => isNaN(Number(v))) + .map(effect => ({ + text: effect, + val: effect, + })); + +export const effectTimings = [ + { text: 'Default', val: SpringType.DEFAULT }, + { + text: 'Gentle', + val: SpringType.GENTLE, + }, + { + text: 'Quick', + val: SpringType.QUICK, + }, + { + text: 'Bouncy', + val: SpringType.BOUNCY, + }, + { + text: 'Custom', + val: SpringType.CUSTOM, + }, +]; + +// Maps spring names to spring parameters +export const springMappings: { + [key: string]: { stiffness: number; damping: number; mass: number }; +} = { + default: { + stiffness: 600, + damping: 15, + mass: 1, + }, + gentle: { + stiffness: 100, + damping: 15, + mass: 1, + }, + quick: { + stiffness: 300, + damping: 20, + mass: 1, + }, + bouncy: { + stiffness: 600, + damping: 15, + mass: 1, + }, + custom: { + stiffness: 100, + damping: 10, + mass: 1, + }, +}; |