aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/animationtimeline
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/animationtimeline')
-rw-r--r--src/client/views/animationtimeline/Region.tsx32
-rw-r--r--src/client/views/animationtimeline/Timeline.tsx56
-rw-r--r--src/client/views/animationtimeline/Track.tsx24
3 files changed, 55 insertions, 57 deletions
diff --git a/src/client/views/animationtimeline/Region.tsx b/src/client/views/animationtimeline/Region.tsx
index 99163f6c6..40fcb2bf6 100644
--- a/src/client/views/animationtimeline/Region.tsx
+++ b/src/client/views/animationtimeline/Region.tsx
@@ -12,6 +12,18 @@ import './Region.scss';
import './Timeline.scss';
import { TimelineMenu } from './TimelineMenu';
+export const RegionDataSchema = createSchema({
+ position: defaultSpec('number', 0),
+ duration: defaultSpec('number', 0),
+ keyframes: listSpec(Doc),
+ fadeIn: defaultSpec('number', 0),
+ fadeOut: defaultSpec('number', 0),
+ functions: listSpec(Doc),
+ hasData: defaultSpec('boolean', false),
+});
+export type RegionData = makeInterface<[typeof RegionDataSchema]>;
+export const RegionData = makeInterface(RegionDataSchema);
+
/**
* Useful static functions that you can use. Mostly for logic, but you can also add UI logic here also
*/
@@ -108,18 +120,6 @@ export namespace RegionHelpers {
};
}
-export const RegionDataSchema = createSchema({
- position: defaultSpec('number', 0),
- duration: defaultSpec('number', 0),
- keyframes: listSpec(Doc),
- fadeIn: defaultSpec('number', 0),
- fadeOut: defaultSpec('number', 0),
- functions: listSpec(Doc),
- hasData: defaultSpec('boolean', false),
-});
-export type RegionData = makeInterface<[typeof RegionDataSchema]>;
-export const RegionData = makeInterface(RegionDataSchema);
-
interface IProps {
animatedDoc: Doc;
RegionData: Doc;
@@ -184,7 +184,7 @@ export class Region extends ObservableReactComponent<IProps> {
return RegionHelpers.convertPixelTime(this.regiondata.fadeOut, 'mili', 'pixel', this._props.tickSpacing, this._props.tickIncrement);
}
- constructor(props: any) {
+ constructor(props: IProps) {
super(props);
makeObservable(this);
}
@@ -220,9 +220,7 @@ export class Region extends ObservableReactComponent<IProps> {
}, 200);
this._doubleClickEnabled = true;
document.addEventListener('pointermove', this.onBarPointerMove);
- document.addEventListener('pointerup', (e: PointerEvent) => {
- document.removeEventListener('pointermove', this.onBarPointerMove);
- });
+ document.addEventListener('pointerup', () => document.removeEventListener('pointermove', this.onBarPointerMove));
}
};
@@ -426,6 +424,7 @@ export class Region extends ObservableReactComponent<IProps> {
.map(region => ({ pos: NumCast(region.position), dur: NumCast(region.duration) }))
.forEach(({ pos, dur }) => {
if (pos !== this.regiondata.position) {
+ // eslint-disable-next-line no-param-reassign
val += this.regiondata.position;
if (val < 0 || (val > pos && val < pos + dur)) {
cannotMove = true;
@@ -483,7 +482,6 @@ export class Region extends ObservableReactComponent<IProps> {
* this probably needs biggest change, since everyone expected all keyframes to have a circle (and draggable)
*/
drawKeyframes = () => {
- const keyframeDivs: JSX.Element[] = [];
return DocListCast(this.regiondata.keyframes).map(kf => {
return (
<>
diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx
index 15683ebf2..814e9a7a0 100644
--- a/src/client/views/animationtimeline/Timeline.tsx
+++ b/src/client/views/animationtimeline/Timeline.tsx
@@ -46,7 +46,7 @@ import { Id } from '../../../fields/FieldSymbols';
*/
@observer
-export class Timeline extends ObservableReactComponent<FieldViewProps> {
+export class Timeline extends ObservableReactComponent<FieldViewProps & { Doc: Doc }> {
// readonly constants
private readonly DEFAULT_TICK_SPACING: number = 50;
private readonly MAX_TITLE_HEIGHT = 75;
@@ -57,7 +57,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
private DEFAULT_CONTAINER_HEIGHT: number = 330;
private MIN_CONTAINER_HEIGHT: number = 205;
- constructor(props: FieldViewProps) {
+ constructor(props: FieldViewProps & { Doc: Doc }) {
super(props);
makeObservable(this);
}
@@ -90,11 +90,11 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
*/
@computed
private get children(): Doc[] {
- const annotatedDoc = [DocumentType.IMG, DocumentType.VID, DocumentType.PDF, DocumentType.MAP].includes(StrCast(this._props.Document.type) as unknown as DocumentType);
+ const annotatedDoc = [DocumentType.IMG, DocumentType.VID, DocumentType.PDF, DocumentType.MAP].includes(StrCast(this._props.Doc.type) as unknown as DocumentType);
if (annotatedDoc) {
- return DocListCast(this._props.Document[Doc.LayoutFieldKey(this._props.Document) + '_annotations']);
+ return DocListCast(this._props.Doc[Doc.LayoutDataKey(this._props.Doc) + '_annotations']);
}
- return DocListCast(this._props.Document[this._props.fieldKey]);
+ return DocListCast(this._props.Doc[this._props.fieldKey]);
}
/// //////lifecycle functions////////////
@@ -104,21 +104,21 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
this._titleHeight = relativeHeight < this.MAX_TITLE_HEIGHT ? relativeHeight : this.MAX_TITLE_HEIGHT; // check if relHeight is less than Maxheight. Else, just set relheight to max
this.MIN_CONTAINER_HEIGHT = this._titleHeight + 130; // offset
this.DEFAULT_CONTAINER_HEIGHT = this._titleHeight * 2 + 130; // twice the titleheight + offset
- if (!this._props.Document.AnimationLength) {
+ if (!this._props.Doc.AnimationLength) {
// if animation length did not exist
- this._props.Document.AnimationLength = this._time; // set it to default time
+ this._props.Doc.AnimationLength = this._time; // set it to default time
} else {
- this._time = NumCast(this._props.Document.AnimationLength); // else, set time to animationlength stored from before
+ this._time = NumCast(this._props.Doc.AnimationLength); // else, set time to animationlength stored from before
}
this._totalLength = this._tickSpacing * (this._time / this._tickIncrement); // the entire length of the timeline div (actual div part itself)
this._visibleLength = this._infoContainer.current!.getBoundingClientRect().width; // the visible length of the timeline (the length that you current see)
this._visibleStart = this._infoContainer.current!.scrollLeft; // where the div starts
- this._props.Document.isATOn = !this._props.Document.isATOn; // turns the boolean on, saying AT (animation timeline) is on
+ this._props.Doc.isATOn = !this._props.Doc.isATOn; // turns the boolean on, saying AT (animation timeline) is on
this.toggleHandle();
}
componentWillUnmount() {
- this._props.Document.AnimationLength = this._time; // save animation length
+ this._props.Doc.AnimationLength = this._time; // save animation length
}
/// //////////////////////////////////////////////
@@ -224,7 +224,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
*/
@action
onPanDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, this.onPanMove, emptyFunction, e => this.changeCurrentBarX(this._trackbox.current!.scrollLeft + e.clientX - this._trackbox.current!.getBoundingClientRect().left));
+ setupMoveUpEvents(this, e, this.onPanMove, emptyFunction, movEv => this.changeCurrentBarX(this._trackbox.current!.scrollLeft + movEv.clientX - this._trackbox.current!.getBoundingClientRect().left));
};
/**
@@ -241,7 +241,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
this._visibleStart -= e.movementX;
this._totalLength -= e.movementX;
this._time -= RegionHelpers.convertPixelTime(e.movementX, 'mili', 'time', this._tickSpacing, this._tickIncrement);
- this._props.Document.AnimationLength = this._time;
+ this._props.Doc.AnimationLength = this._time;
}
return false;
};
@@ -259,8 +259,8 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
setupMoveUpEvents(
this,
e,
- action(e => {
- const offset = e.clientY - this._timelineContainer.current!.getBoundingClientRect().bottom;
+ action(movEv => {
+ const offset = movEv.clientY - this._timelineContainer.current!.getBoundingClientRect().bottom;
this._containerHeight = clamp(this.MIN_CONTAINER_HEIGHT, this._containerHeight + offset, this.MAX_CONTAINER_HEIGHT);
return false;
}),
@@ -358,7 +358,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
const size = 40 * scale; // 50 is default
const iconSize = 25;
const width: number = this._props.PanelWidth();
- const modeType = this._props.Document.isATOn ? 'Author' : 'Play';
+ const modeType = this._props.Doc.isATOn ? 'Author' : 'Play';
// decides if information should be omitted because the timeline is very small
// if its less than 950 pixels then it's going to be overlapping
@@ -397,7 +397,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
tickIncrement={this._tickIncrement}
time={this._time}
parent={this}
- isAuthoring={BoolCast(this._props.Document.isATOn)}
+ isAuthoring={BoolCast(this._props.Doc.isATOn)}
currentBarX={this._currentBarX}
totalLength={this._totalLength}
visibleLength={this._visibleLength}
@@ -418,10 +418,10 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
</div>
<div className="time-box overview-tool" style={{ display: 'flex' }}>
{this.timeIndicator(lengthString, totalTime)}
- <div className="resetView-tool" title="Return to Default View" onClick={() => this.resetView(this._props.Document)}>
+ <div className="resetView-tool" title="Return to Default View" onClick={() => this.resetView(this._props.Doc)}>
<FontAwesomeIcon icon="compress-arrows-alt" size="lg" />
</div>
- <div className="resetView-tool" style={{ display: this._props.Document.isATOn ? 'flex' : 'none' }} title="Set Default View" onClick={() => this.setView(this._props.Document)}>
+ <div className="resetView-tool" style={{ display: this._props.Doc.isATOn ? 'flex' : 'none' }} title="Set Default View" onClick={() => this.setView(this._props.Doc)}>
<FontAwesomeIcon icon="expand-arrows-alt" size="lg" />
</div>
</div>
@@ -431,17 +431,17 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
};
timeIndicator(lengthString: string, totalTime: number) {
- if (this._props.Document.isATOn) {
- return <div key="time-text" className="animation-text" style={{ visibility: this._props.Document.isATOn ? 'visible' : 'hidden', display: this._props.Document.isATOn ? 'flex' : 'none' }}>{`Total: ${this.toReadTime(totalTime)}`}</div>;
+ if (this._props.Doc.isATOn) {
+ return <div key="time-text" className="animation-text" style={{ visibility: this._props.Doc.isATOn ? 'visible' : 'hidden', display: this._props.Doc.isATOn ? 'flex' : 'none' }}>{`Total: ${this.toReadTime(totalTime)}`}</div>;
} else {
const ctime = `Current: ${this.getCurrentTime()}`;
const ttime = `Total: ${this.toReadTime(this._time)}`;
return (
<div style={{ flexDirection: 'column' }}>
- <div className="animation-text" style={{ fontSize: '10px', width: '100%', display: !this._props.Document.isATOn ? 'block' : 'none' }}>
+ <div className="animation-text" style={{ fontSize: '10px', width: '100%', display: !this._props.Doc.isATOn ? 'block' : 'none' }}>
{ctime}
</div>
- <div className="animation-text" style={{ fontSize: '10px', width: '100%', display: !this._props.Document.isATOn ? 'block' : 'none' }}>
+ <div className="animation-text" style={{ fontSize: '10px', width: '100%', display: !this._props.Doc.isATOn ? 'block' : 'none' }}>
{ttime}
</div>
</div>
@@ -467,8 +467,8 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
const roundToggleContainer = this._roundToggleContainerRef.current!;
const timelineContainer = this._timelineContainer.current!;
- this._props.Document.isATOn = !this._props.Document.isATOn;
- if (!BoolCast(this._props.Document.isATOn)) {
+ this._props.Doc.isATOn = !this._props.Doc.isATOn;
+ if (!BoolCast(this._props.Doc.isATOn)) {
// turning on playmode...
roundToggle.style.transform = 'translate(0px, 0px)';
roundToggle.style.animationName = 'turnoff';
@@ -543,7 +543,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
// change visible and total width
return (
<div style={{ visibility: 'visible' }}>
- <div key="timeline_wrapper" style={{ visibility: this._props.Document.isATOn ? 'visible' : 'hidden', left: '0px', top: '0px', position: 'absolute', width: '100%', transform: 'translate(0px, 0px)' }}>
+ <div key="timeline_wrapper" style={{ visibility: this._props.Doc.isATOn ? 'visible' : 'hidden', left: '0px', top: '0px', position: 'absolute', width: '100%', transform: 'translate(0px, 0px)' }}>
<div key="timeline_container" className="timeline-container" ref={this._timelineContainer} style={{ height: `${this._containerHeight}px`, top: `0px` }}>
<div key="timeline_info" className="info-container" onPointerDown={this.onPanDown} ref={this._infoContainer} onWheel={this.onWheelZoom}>
{this.drawTicks()}
@@ -551,7 +551,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
<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 => (
+ {[...this.children, this._props.Doc].map(doc => (
<Track
key={doc[Id]}
ref={ref => this.mapOfTracks.push(ref)}
@@ -563,7 +563,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
time={this._time}
tickSpacing={this._tickSpacing}
tickIncrement={this._tickIncrement}
- collection={this._props.Document}
+ collection={this._props.Doc}
timelineVisible={true}
/>
))}
@@ -571,7 +571,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
</div>
<div className="currentTime">Current: {this.getCurrentTime()}</div>
<div key="timeline_title" className="title-container" ref={this._titleContainer}>
- {[...this.children, this._props.Document].map(doc => (
+ {[...this.children, this._props.Doc].map(doc => (
<div key={doc[Id]} style={{ height: `${this._titleHeight}px` }} className="datapane" onPointerOver={() => Doc.BrushDoc(doc)} onPointerOut={() => Doc.UnBrushDoc(doc)}>
<p>{StrCast(doc.title)}</p>
</div>
diff --git a/src/client/views/animationtimeline/Track.tsx b/src/client/views/animationtimeline/Track.tsx
index 1e4ed74be..dea7b6aae 100644
--- a/src/client/views/animationtimeline/Track.tsx
+++ b/src/client/views/animationtimeline/Track.tsx
@@ -1,4 +1,4 @@
-import { action, computed, intercept, makeObservable, observable, reaction, runInAction } from 'mobx';
+import { action, computed, intercept, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc, DocListCast, DocListCastAsync, Opt } from '../../../fields/Doc';
@@ -6,7 +6,7 @@ import { Copy } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
import { ObjectField } from '../../../fields/ObjectField';
import { listSpec } from '../../../fields/Schema';
-import { Cast, NumCast } from '../../../fields/Types';
+import { Cast, DocCast, NumCast } from '../../../fields/Types';
import { Transform } from '../../util/Transform';
import { ObservableReactComponent } from '../ObservableReactComponent';
import { Region, RegionData, RegionHelpers } from './Region';
@@ -29,16 +29,16 @@ interface IProps {
@observer
export class Track extends ObservableReactComponent<IProps> {
@observable private _inner = React.createRef<HTMLDivElement>();
- @observable private _currentBarXReaction: any = undefined;
- @observable private _timelineVisibleReaction: any = undefined;
- @observable private _autoKfReaction: any = undefined;
+ @observable private _currentBarXReaction: IReactionDisposer | undefined = undefined;
+ @observable private _timelineVisibleReaction: IReactionDisposer | undefined = undefined;
+ @observable private _autoKfReaction: IReactionDisposer | undefined = undefined;
@observable private _newKeyframe: boolean = false;
private readonly MAX_TITLE_HEIGHT = 75;
@observable private _trackHeight = 0;
private primitiveWhitelist = ['x', 'y', '_freeform_panX', '_freeform_panY', '_width', '_height', '_rotation', 'opacity', '_layout_scrollTop'];
private objectWhitelist = ['data'];
- constructor(props: any) {
+ constructor(props: IProps) {
super(props);
makeObservable(this);
}
@@ -101,11 +101,11 @@ export class Track extends ObservableReactComponent<IProps> {
}
const keyframes = Cast(this.saveStateRegion.keyframes, listSpec(Doc)) as List<Doc>;
const kfIndex = keyframes.indexOf(this.saveStateKf);
- const kf = keyframes[kfIndex] as Doc; //index in the keyframe
+ const kf = DocCast(keyframes[kfIndex]); //index in the keyframe
if (this._newKeyframe) {
- DocListCast(this.saveStateRegion.keyframes).forEach((kf, index) => {
- this.copyDocDataToKeyFrame(kf);
- kf.opacity = index === 0 || index === 3 ? 0.1 : 1;
+ DocListCast(this.saveStateRegion.keyframes).forEach((keyF, index) => {
+ this.copyDocDataToKeyFrame(keyF);
+ keyF.opacity = index === 0 || index === 3 ? 0.1 : 1;
});
this._newKeyframe = false;
}
@@ -144,7 +144,7 @@ export class Track extends ObservableReactComponent<IProps> {
() => {
return [...this.primitiveWhitelist.map(key => this._props.animatedDoc[key]), ...objects];
},
- (changed, reaction) => {
+ (/* changed, reaction */) => {
//check for region
const region = this.findRegion(this.time);
if (region !== undefined) {
@@ -374,7 +374,7 @@ export class Track extends ObservableReactComponent<IProps> {
@action
copyDocDataToKeyFrame = (doc: Doc) => {
- var somethingChanged = false;
+ let somethingChanged = false;
this.primitiveWhitelist.map(key => {
const originalVal = this._props.animatedDoc[key];
somethingChanged = somethingChanged || originalVal !== doc[key];