aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/trails/PresBox.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/trails/PresBox.tsx')
-rw-r--r--src/client/views/nodes/trails/PresBox.tsx173
1 files changed, 171 insertions, 2 deletions
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index d330c8157..deb59d03f 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -46,6 +46,7 @@ import { DictationManager } from '../../../util/DictationManager';
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';
export interface pinDataTypes {
scrollable?: boolean;
@@ -74,6 +75,23 @@ 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',
@@ -116,6 +134,59 @@ const effectItems = Object.values(PresEffect)
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) {
@@ -1689,6 +1760,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@undoBatch
updateEffect = (effect: PresEffect, bullet: boolean, all?: boolean) => (all ? this.childDocs : this.selectedArray).forEach(doc => (bullet ? (doc.presBulletEffect = effect) : (doc.presentation_effect = effect)));
+ @undoBatch
+ updateEffectTiming = (activeItem: Doc, timing: SpringSettings) => {
+ activeItem.presEffectTiming = JSON.stringify(timing);
+ this.selectedArray.forEach(doc => (doc.presEffectTiming = activeItem.presEffectTiming));
+ };
+
static _sliderBatch: any;
static endBatch = () => {
PresBox._sliderBatch.end();
@@ -1935,6 +2012,25 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@computed get transitionDropdown() {
const activeItem = this.activeItem;
+ // Retrieving spring timing properties
+ let timing = StrCast(activeItem.presEffectTiming);
+ let timingConfig: SpringSettings | undefined;
+ if (timing) {
+ timingConfig = JSON.parse(timing);
+ }
+
+ if (!timingConfig) {
+ timingConfig = {
+ type: SpringType.DEFAULT,
+ // stiffness: 300,
+ // damping: 12,
+ // mass: 2,
+ stiffness: 600,
+ damping: 15,
+ mass: 1,
+ };
+ }
+
const preseEffect = (effect: PresEffect) => (
<div
className={`presBox-dropdownOption ${activeItem.presentation_effect === effect || (effect === PresEffect.None && !activeItem.presentation_effect) ? 'active' : ''}`}
@@ -2105,7 +2201,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
<div className="slider-text">Slow</div>
</div>
{/* Easing function */}
- <div className="presBox-option-block presBox-option-cente">
+ <div className="presBox-option-block presBox-option-center">
<Dropdown
color={StrCast(Doc.UserDoc().userColor)}
formLabel={'Easing Function'}
@@ -2129,7 +2225,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
<CubicBezierEditor setFunc={this.setBezierControlPoints} currPoints={this.currCPoints} easeFunc={StrCast(this.activeItem.presEaseFunc)} />
</div>
</div>
- <div className="presBox-option-block">
+ <div className="presBox-option-block" style={{ padding: '16px' }}>
Effects
<Toggle
formLabel={'Play Audio Annotation'}
@@ -2258,6 +2354,79 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
{presDirection(PresEffectDirection.Center, '', 2, 2, { width: 10, height: 10, alignSelf: 'center' })}
</div> */}
{/* Effect spring settings */}
+ <Dropdown
+ color={StrCast(Doc.UserDoc().userColor)}
+ formLabel={'Effect Timing'}
+ closeOnSelect={true}
+ items={effectTimings}
+ selectedVal={timingConfig.type}
+ setSelectedVal={val => {
+ console.log('effect timing', val);
+ this.updateEffectTiming(activeItem, {
+ type: val as SpringType,
+ ...springMappings[val],
+ });
+ }}
+ dropdownType={DropdownType.SELECT}
+ type={Type.TERT}
+ />
+ <div>Tension</div>
+ <div
+ onPointerDown={e => {
+ e.stopPropagation();
+ }}>
+ <Slider
+ min={1}
+ max={1000}
+ step={5}
+ size="small"
+ value={timingConfig.stiffness}
+ onChange={(e, val) => {
+ if (!timingConfig) return;
+ this.updateEffectTiming(activeItem, { ...timingConfig, stiffness: val as number });
+ }}
+ valueLabelDisplay="auto"
+ />
+ </div>
+ <div>Damping</div>
+ <div
+ onPointerDown={e => {
+ e.stopPropagation();
+ }}>
+ <Slider
+ min={1}
+ max={100}
+ step={1}
+ size="small"
+ value={timingConfig.damping}
+ onChange={(e, val) => {
+ if (!timingConfig) return;
+ this.updateEffectTiming(activeItem, { ...timingConfig, damping: val as number });
+ }}
+ valueLabelDisplay="auto"
+ />
+ </div>
+ <div>Mass</div>
+ <div
+ onPointerDown={e => {
+ e.stopPropagation();
+ }}>
+ <Slider
+ min={1}
+ max={10}
+ step={1}
+ size="small"
+ value={timingConfig.mass}
+ onChange={(e, val) => {
+ if (!timingConfig) return;
+ this.updateEffectTiming(activeItem, { ...timingConfig, mass: val as number });
+ }}
+ valueLabelDisplay="auto"
+ />
+ </div>
+ <SpringAnimationPreview tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass}>
+ <div style={{ width: '40px', height: '40px', backgroundColor: '#2e96ff', borderRadius: '4px' }}></div>
+ </SpringAnimationPreview>
</div>
<div className="ribbon-final-box">
<div className="ribbon-final-button-hidden" onClick={() => this.applyTo(this.childDocs)}>