aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/animationtimeline/Keyframe.tsx103
-rw-r--r--src/client/views/animationtimeline/Timeline.tsx16
-rw-r--r--src/client/views/animationtimeline/TimelineOverview.tsx8
-rw-r--r--src/client/views/animationtimeline/Track.tsx60
4 files changed, 92 insertions, 95 deletions
diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx
index bb557289e..76c3e63be 100644
--- a/src/client/views/animationtimeline/Keyframe.tsx
+++ b/src/client/views/animationtimeline/Keyframe.tsx
@@ -3,7 +3,7 @@ import "./Keyframe.scss";
import "./Timeline.scss";
import "../globalCssVariables.scss";
import { observer } from "mobx-react";
-import { observable, reaction, action, IReactionDisposer, observe, computed, runInAction } from "mobx";
+import { observable, reaction, action, IReactionDisposer, observe, computed, runInAction, trace } from "mobx";
import { Doc, DocListCast, DocListCastAsync } from "../../../new_fields/Doc";
import { Cast, NumCast } from "../../../new_fields/Types";
import { List } from "../../../new_fields/List";
@@ -13,6 +13,7 @@ import { TimelineMenu } from "./TimelineMenu";
import { Docs } from "../../documents/Documents";
import { CollectionDockingView } from "../collections/CollectionDockingView";
import { undoBatch, UndoManager } from "../../util/UndoManager";
+import { emptyPath } from "../../../Utils";
@@ -32,10 +33,10 @@ export namespace KeyframeFunc {
right = "right"
}
- export const findAdjacentRegion = (dir: KeyframeFunc.Direction, currentRegion: Doc, regions: List<Doc>): (RegionData | undefined) => {
+ export const findAdjacentRegion = (dir: KeyframeFunc.Direction, currentRegion: Doc, regions: Doc[]): (RegionData | undefined) => {
let leftMost: (RegionData | undefined) = undefined;
let rightMost: (RegionData | undefined) = undefined;
- DocListCast(regions).forEach(region => {
+ regions.forEach(region => {
const neighbor = RegionData(region);
if (currentRegion.position! > neighbor.position) {
if (!leftMost || neighbor.position > leftMost.position) {
@@ -135,7 +136,7 @@ interface IProps {
time: number;
changeCurrentBarX: (x: number) => void;
transform: Transform;
- makeKeyData: (region:RegionData, pos: number, kftype:KeyframeFunc.KeyframeType) => Doc;
+ makeKeyData: (region: RegionData, pos: number, kftype: KeyframeFunc.KeyframeType) => Doc;
}
@@ -169,21 +170,24 @@ export class Keyframe extends React.Component<IProps> {
@observable private _mouseToggled = false;
@observable private _doubleClickEnabled = false;
- @computed private get regiondata() { return RegionData(this.regions[this.regions.indexOf(this.props.RegionData)] as Doc); }
- @computed private get regions() { return Cast(this.props.node.regions, listSpec(Doc)) as List<Doc>; }
+ @computed private get regiondata() { return RegionData(this.props.RegionData); }
+ @computed private get regions() { return DocListCast(this.props.node.regions); }
@computed private get keyframes() { return DocListCast(this.regiondata.keyframes); }
@computed private get pixelPosition() { return KeyframeFunc.convertPixelTime(this.regiondata.position, "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement); }
@computed private get pixelDuration() { return KeyframeFunc.convertPixelTime(this.regiondata.duration, "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement); }
@computed private get pixelFadeIn() { return KeyframeFunc.convertPixelTime(this.regiondata.fadeIn, "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement); }
@computed private get pixelFadeOut() { return KeyframeFunc.convertPixelTime(this.regiondata.fadeOut, "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement); }
-
+
+ constructor(props: any) {
+ super(props);
+ }
componentDidMount() {
setTimeout(() => { //giving it a temporary 1sec delay...
- if (!this.regiondata.keyframes) this.regiondata.keyframes = new List<Doc>();
- const start = this.props.makeKeyData(this.regiondata, this.regiondata.position, KeyframeFunc.KeyframeType.end);
+ if (!this.regiondata.keyframes) this.regiondata.keyframes = new List<Doc>();
+ const start = this.props.makeKeyData(this.regiondata, this.regiondata.position, KeyframeFunc.KeyframeType.end);
const fadeIn = this.props.makeKeyData(this.regiondata, this.regiondata.position + this.regiondata.fadeIn, KeyframeFunc.KeyframeType.fade);
const fadeOut = this.props.makeKeyData(this.regiondata, this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut, KeyframeFunc.KeyframeType.fade);
- const finish = this.props.makeKeyData(this.regiondata, this.regiondata.position + this.regiondata.duration,KeyframeFunc.KeyframeType.end);
+ const finish = this.props.makeKeyData(this.regiondata, this.regiondata.position + this.regiondata.duration, KeyframeFunc.KeyframeType.end);
(fadeIn.key as Doc).opacity = 1;
(fadeOut.key as Doc).opacity = 1;
(start.key as Doc).opacity = 0.1;
@@ -192,9 +196,6 @@ export class Keyframe extends React.Component<IProps> {
}, 1000);
}
-
-
-
@action
onBarPointerDown = (e: React.PointerEvent) => {
e.preventDefault();
@@ -316,7 +317,7 @@ export class Keyframe extends React.Component<IProps> {
if (offset > this.regiondata.fadeIn && offset < this.regiondata.duration - this.regiondata.fadeOut) { //make sure keyframe is not created inbetween fades and ends
const position = this.regiondata.position;
this.props.makeKeyData(this.regiondata, Math.round(position + offset), KeyframeFunc.KeyframeType.default);
- this.regiondata.hasData = true;
+ this.regiondata.hasData = true;
this.props.changeCurrentBarX(KeyframeFunc.convertPixelTime(Math.round(position + offset), "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement)); //first move the keyframe to the correct location and make a copy so the correct file gets coppied
}
@@ -338,7 +339,7 @@ export class Keyframe extends React.Component<IProps> {
TimelineMenu.Instance.addItem("button", "Show Data", () => {
runInAction(() => {
const kvp = Docs.Create.KVPDocument(Cast(kf.key, Doc) as Doc, { _width: 300, _height: 300 });
- CollectionDockingView.AddRightSplit(kvp, (kf.key as Doc).data as Doc);
+ CollectionDockingView.AddRightSplit(kvp, emptyPath);
});
}),
TimelineMenu.Instance.addItem("button", "Delete", () => {
@@ -403,7 +404,7 @@ export class Keyframe extends React.Component<IProps> {
runInAction(() => {
const prevPosition = this.regiondata.position;
let cannotMove: boolean = false;
- DocListCast(this.regions).forEach(region => {
+ this.regions.forEach(region => {
if (NumCast(region.position) !== this.regiondata.position) {
if ((val < 0) || (val > NumCast(region.position) && val < NumCast(region.position) + NumCast(region.duration) || (this.regiondata.duration + val > NumCast(region.position) && this.regiondata.duration + val < NumCast(region.position) + NumCast(region.duration)))) {
cannotMove = true;
@@ -419,7 +420,7 @@ export class Keyframe extends React.Component<IProps> {
TimelineMenu.Instance.addItem("input", `duration: ${this.regiondata.duration}ms`, (val) => {
runInAction(() => {
let cannotMove: boolean = false;
- DocListCast(this.regions).forEach(region => {
+ this.regions.forEach(region => {
if (NumCast(region.position) !== this.regiondata.position) {
val += this.regiondata.position;
if ((val < 0) || (val > NumCast(region.position) && val < NumCast(region.position) + NumCast(region.duration))) {
@@ -479,34 +480,31 @@ export class Keyframe extends React.Component<IProps> {
* drawing keyframe. Handles both keyframe with a circle (one that you create by double clicking) and one without circle (fades)
* this probably needs biggest change, since everyone expected all keyframes to have a circle (and draggable)
*/
- @action
drawKeyframes = () => {
const keyframeDivs: JSX.Element[] = [];
- DocListCast(this.regiondata.keyframes).forEach(kf => {
+ return DocListCast(this.regiondata.keyframes).map(kf => {
if (kf.type as KeyframeFunc.KeyframeType !== KeyframeFunc.KeyframeType.end) {
- keyframeDivs.push(
- <><div className="keyframe" style={{ left: `${KeyframeFunc.convertPixelTime(NumCast(kf.time), "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement) - this.pixelPosition}px` }}>
- <div className="divider"></div>
- <div className="keyframeCircle keyframe-indicator" onPointerDown={(e) => { e.preventDefault(); e.stopPropagation(); this.moveKeyframe(e, kf); }} onContextMenu={(e: React.MouseEvent) => {
- e.preventDefault();
- e.stopPropagation();
- this.makeKeyframeMenu(kf, e.nativeEvent);
- }} onDoubleClick={(e) => { e.preventDefault(); e.stopPropagation(); }}></div>
-
- </div>
- <div className="keyframe-information"></div>
- </>
-
- );
- } else {
- keyframeDivs.push(
+ return <>
<div className="keyframe" style={{ left: `${KeyframeFunc.convertPixelTime(NumCast(kf.time), "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement) - this.pixelPosition}px` }}>
<div className="divider"></div>
+ <div className="keyframeCircle keyframe-indicator"
+ onPointerDown={(e) => { e.preventDefault(); e.stopPropagation(); this.moveKeyframe(e, kf); }}
+ onContextMenu={(e: React.MouseEvent) => {
+ e.preventDefault();
+ e.stopPropagation();
+ this.makeKeyframeMenu(kf, e.nativeEvent);
+ }}
+ onDoubleClick={(e) => { e.preventDefault(); e.stopPropagation(); }}>
+ </div>
</div>
- );
+ <div className="keyframe-information" />
+ </>;
+ } else {
+ return <div className="keyframe" style={{ left: `${KeyframeFunc.convertPixelTime(NumCast(kf.time), "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement) - this.pixelPosition}px` }}>
+ <div className="divider" />
+ </div>
}
});
- return keyframeDivs;
}
/**
@@ -546,22 +544,23 @@ export class Keyframe extends React.Component<IProps> {
*/
//154, 206, 223
render() {
+ trace();
+ console.log(this.props.RegionData.position);
+ console.log(this.regiondata.position);
+ console.log(this.pixelPosition);
return (
- <div>
- <div className="bar" ref={this._bar} style={{
- transform: `translate(${this.pixelPosition}px)`,
- width: `${this.pixelDuration}px`,
- background: `linear-gradient(90deg, rgba(154, 206, 223, 0) 0%, rgba(154, 206, 223, 1) ${this.pixelFadeIn / this.pixelDuration * 100}%, rgba(154, 206, 223, 1) ${(this.pixelDuration - this.pixelFadeOut) / this.pixelDuration * 100}%, rgba(154, 206, 223, 0) 100% )`
- }}
- onPointerDown={this.onBarPointerDown
- }>
- <div className="leftResize keyframe-indicator" onPointerDown={this.onResizeLeft} ></div>
- {/* <div className="keyframe-information"></div> */}
- <div className="rightResize keyframe-indicator" onPointerDown={this.onResizeRight}></div>
- {/* <div className="keyframe-information"></div> */}
- {this.drawKeyframes()}
- {this.drawKeyframeDividers()}
- </div>
+ <div className="bar" ref={this._bar} style={{
+ transform: `translate(${this.pixelPosition}px)`,
+ width: `${this.pixelDuration}px`,
+ background: `linear-gradient(90deg, rgba(154, 206, 223, 0) 0%, rgba(154, 206, 223, 1) ${this.pixelFadeIn / this.pixelDuration * 100}%, rgba(154, 206, 223, 1) ${(this.pixelDuration - this.pixelFadeOut) / this.pixelDuration * 100}%, rgba(154, 206, 223, 0) 100% )`
+ }}
+ onPointerDown={this.onBarPointerDown}>
+ <div className="leftResize keyframe-indicator" onPointerDown={this.onResizeLeft} ></div>
+ {/* <div className="keyframe-information"></div> */}
+ <div className="rightResize keyframe-indicator" onPointerDown={this.onResizeRight}></div>
+ {/* <div className="keyframe-information"></div> */}
+ {this.drawKeyframes()}
+ {this.drawKeyframeDividers()}
</div>
);
}
diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx
index e9caa2b2a..7d245ab6f 100644
--- a/src/client/views/animationtimeline/Timeline.tsx
+++ b/src/client/views/animationtimeline/Timeline.tsx
@@ -3,7 +3,7 @@ import "./Timeline.scss";
import { listSpec } from "../../../new_fields/Schema";
import { observer } from "mobx-react";
import { Track } from "./Track";
-import { observable, action, computed, runInAction, IReactionDisposer, reaction } from "mobx";
+import { observable, action, computed, runInAction, IReactionDisposer, reaction, trace } from "mobx";
import { Cast, NumCast, StrCast, BoolCast } from "../../../new_fields/Types";
import { List } from "../../../new_fields/List";
import { Doc, DocListCast } from "../../../new_fields/Doc";
@@ -14,8 +14,6 @@ import { TimelineOverview } from "./TimelineOverview";
import { FieldViewProps } from "../nodes/FieldView";
import { KeyframeFunc } from "./Keyframe";
import { Utils } from "../../../Utils";
-import { createPromiseCapability } from "../../../../deploy/assets/pdf.worker";
-
/**
* Timeline class controls most of timeline functions besides individual keyframe and track mechanism. Main functions are
@@ -80,7 +78,6 @@ export class Timeline extends React.Component<FieldViewProps> {
// so a reaction can be made
@observable public _isAuthoring = this.props.Document.isATOn;
- @observable private _panelWidth = 0;
/**
* collection get method. Basically defines what defines collection's children. These will be tracked in the timeline. Do not edit.
@@ -90,7 +87,7 @@ export class Timeline extends React.Component<FieldViewProps> {
const extendedDocument = ["image", "video", "pdf"].includes(StrCast(this.props.Document.type));
if (extendedDocument) {
if (this.props.Document.data_ext) {
- return Cast((Cast(this.props.Document.data_ext, Doc) as Doc).annotations, listSpec(Doc)) as List<Doc>;
+ return Cast((Cast(this.props.Document[Doc.LayoutFieldKey(this.props.Document) + "-annotations"], Doc) as Doc).annotations, listSpec(Doc)) as List<Doc>;
} else {
return new List<Doc>();
}
@@ -586,17 +583,14 @@ export class Timeline extends React.Component<FieldViewProps> {
* basically the only thing you need to edit besides render methods in track (individual track lines) and keyframe (green region)
*/
render() {
- runInAction(() => {
- this._panelWidth = this.props.PanelWidth();
+ setTimeout(() => {
this.changeLengths();
// this.toPlay();
-
-
// this._time = longestTime;
- });
+ }, 0);
const longestTime = this.findLongestTime();
-
+ trace();
// change visible and total width
return (
<div>
diff --git a/src/client/views/animationtimeline/TimelineOverview.tsx b/src/client/views/animationtimeline/TimelineOverview.tsx
index e3a276737..31e248823 100644
--- a/src/client/views/animationtimeline/TimelineOverview.tsx
+++ b/src/client/views/animationtimeline/TimelineOverview.tsx
@@ -156,16 +156,16 @@ export class TimelineOverview extends React.Component<TimelineOverviewProps>{
const timeline = this.props.isAuthoring ? [
<div key="timeline-overview-container" className="timeline-overview-container overviewBar" id="timelineOverview" ref={this.authoringContainer}>
- <div ref={this._visibleRef} key="timeline-overview-visible" className="timeline-overview-visible" style={{ left: `${barStart}px`, width: `${visibleBarWidth}px` }} onPointerDown={this.onPointerDown}></div>,
- <div ref={this._scrubberRef} key="timeline-overview-scrubber-container" className="timeline-overview-scrubber-container" style={{ left: `${scrubberStart}px` }} onPointerDown={this.onScrubberDown}>
+ <div ref={this._visibleRef} key="1" className="timeline-overview-visible" style={{ left: `${barStart}px`, width: `${visibleBarWidth}px` }} onPointerDown={this.onPointerDown}></div>,
+ <div ref={this._scrubberRef} key="2" className="timeline-overview-scrubber-container" style={{ left: `${scrubberStart}px` }} onPointerDown={this.onScrubberDown}>
<div key="timeline-overview-scrubber-head" className="timeline-overview-scrubber-head"></div>
</div>
</div>
] : [
- <div key="timeline-play-container" className="timeline-play-bar overviewBar" id="timelinePlay" ref={this.playbackContainer}>
+ <div key="1" className="timeline-play-bar overviewBar" id="timelinePlay" ref={this.playbackContainer}>
<div ref={this._scrubberRef} className="timeline-play-head" style={{ left: `${scrubberStart}px` }} onPointerDown={this.onScrubberDown}></div>
</div>,
- <div className="timeline-play-tail" style={{ width: `${playWidth}px` }}></div>
+ <div key="2" className="timeline-play-tail" style={{ width: `${playWidth}px` }}></div>
];
return (
<div className="timeline-flex">
diff --git a/src/client/views/animationtimeline/Track.tsx b/src/client/views/animationtimeline/Track.tsx
index 705cc33a2..0e3c209dc 100644
--- a/src/client/views/animationtimeline/Track.tsx
+++ b/src/client/views/animationtimeline/Track.tsx
@@ -29,7 +29,7 @@ export class Track extends React.Component<IProps> {
@observable private _currentBarXReaction: any;
@observable private _timelineVisibleReaction: any;
@observable private _autoKfReaction: any;
- @observable private _newKeyframe: boolean = false;
+ @observable private _newKeyframe: boolean = false;
private readonly MAX_TITLE_HEIGHT = 75;
private _trackHeight = 0;
private primitiveWhitelist = [
@@ -37,7 +37,7 @@ export class Track extends React.Component<IProps> {
"y",
"width",
"height",
- "opacity",
+ "opacity",
];
private objectWhitelist = [
"data"
@@ -81,17 +81,17 @@ export class Track extends React.Component<IProps> {
////////////////////////////////
- getLastRegionTime = () => {
- let lastTime:number = 0;
- let lastRegion:(Doc | undefined);
+ getLastRegionTime = () => {
+ let lastTime: number = 0;
+ let lastRegion: (Doc | undefined);
DocListCast(this.regions).forEach(region => {
- const time = NumCast(region.position);
+ const time = NumCast(region.position);
if (lastTime <= time) {
- lastTime = time;
- lastRegion = region;
+ lastTime = time;
+ lastRegion = region;
}
- });
- return lastRegion ? lastTime + NumCast(lastRegion.duration) : 0;
+ });
+ return lastRegion ? lastTime + NumCast(lastRegion.duration) : 0;
}
/**
@@ -106,16 +106,16 @@ export class Track extends React.Component<IProps> {
let kf = keyframes[kfIndex] as Doc; //index in the keyframe
if (this._newKeyframe) {
console.log("new keyframe registering");
- let kfList = DocListCast(this.saveStateRegion!.keyframes);
+ let kfList = DocListCast(this.saveStateRegion!.keyframes);
kfList.forEach(kf => {
- kf.key = this.makeCopy();
- if (kfList.indexOf(kf) === 0 || kfList.indexOf(kf) === 3){
- (kf.key as Doc).opacity = 0.1;
- } else{
- (kf.key as Doc).opacity = 1;
+ kf.key = this.makeCopy();
+ if (kfList.indexOf(kf) === 0 || kfList.indexOf(kf) === 3) {
+ (kf.key as Doc).opacity = 0.1;
+ } else {
+ (kf.key as Doc).opacity = 1;
}
});
- this._newKeyframe = false;
+ this._newKeyframe = false;
}
if (!kf) return;
if (kf.type === KeyframeFunc.KeyframeType.default) { // only save for non-fades
@@ -225,7 +225,7 @@ export class Track extends React.Component<IProps> {
}
});
} else {
- console.log("reverting state");
+ console.log("reverting state");
//this.revertState();
}
});
@@ -241,7 +241,7 @@ export class Track extends React.Component<IProps> {
timeChange = async () => {
if (this.saveStateKf !== undefined) {
await this.saveKeyframe();
- } else if (this._newKeyframe){
+ } else if (this._newKeyframe) {
await this.saveKeyframe();
}
let regiondata = await this.findRegion(Math.round(this.time)); //finds a region that the scrubber is on
@@ -250,7 +250,7 @@ export class Track extends React.Component<IProps> {
let rightkf: (Doc | undefined) = await KeyframeFunc.calcMinRight(regiondata, this.time); //right keyframe, if it exists
let currentkf: (Doc | undefined) = await this.calcCurrent(regiondata); //if the scrubber is on top of the keyframe
if (currentkf) {
- console.log("is current");
+ console.log("is current");
await this.applyKeys(currentkf);
this.saveStateKf = currentkf;
this.saveStateRegion = regiondata;
@@ -348,7 +348,7 @@ export class Track extends React.Component<IProps> {
createRegion = async (time: number) => {
if (await this.findRegion(time) === undefined) { //check if there is a region where double clicking (prevents phantom regions)
let regiondata = KeyframeFunc.defaultKeyframe(); //create keyframe data
-
+
regiondata.position = time; //set position
let rightRegion = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.right, regiondata, this.regions);
@@ -356,9 +356,9 @@ export class Track extends React.Component<IProps> {
regiondata.duration = rightRegion.position - regiondata.position;
}
if (this.regions.length === 0 || !rightRegion || (rightRegion && rightRegion.position - regiondata.position >= NumCast(regiondata.fadeIn) + NumCast(regiondata.fadeOut))) {
- this.regions.push(regiondata);
- this._newKeyframe = true;
- this.saveStateRegion = regiondata;
+ this.regions.push(regiondata);
+ this._newKeyframe = true;
+ this.saveStateRegion = regiondata;
return regiondata;
}
}
@@ -395,7 +395,7 @@ export class Track extends React.Component<IProps> {
let doc = new Doc();
this.primitiveWhitelist.forEach(key => {
let originalVal = this.props.node[key];
- if (key === "data"){
+ if (key === "data") {
console.log(originalVal);
}
doc[key] = originalVal instanceof ObjectField ? originalVal[Copy]() : this.props.node[key];
@@ -407,12 +407,16 @@ export class Track extends React.Component<IProps> {
* UI sstuff here. Not really much to change
*/
render() {
+ trace();
return (
<div className="track-container">
<div className="track">
- <div className="inner" ref={this._inner} onDoubleClick={this.onInnerDoubleClick} onPointerOver={() => { Doc.BrushDoc(this.props.node); }} onPointerOut={() => { Doc.UnBrushDoc(this.props.node); }} style={{ height: `${this._trackHeight}px` }}>
- {DocListCast(this.regions).map((region) => {
- return <Keyframe {...this.props} RegionData={region} makeKeyData={this.makeKeyData} />;
+ <div className="inner" ref={this._inner} style={{ height: `${this._trackHeight}px` }}
+ onDoubleClick={this.onInnerDoubleClick}
+ onPointerOver={() => Doc.BrushDoc(this.props.node)}
+ onPointerOut={() => Doc.UnBrushDoc(this.props.node)} >
+ {DocListCast(this.regions).map((region, i) => {
+ return <Keyframe key={`${i}`} {...this.props} RegionData={region} makeKeyData={this.makeKeyData} />;
})}
</div>
</div>