aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kim <andrewdkim@users.noreply.github.com>2019-08-19 00:25:14 -0400
committerAndrew Kim <andrewdkim@users.noreply.github.com>2019-08-19 00:25:14 -0400
commit1b7e8873ead3cc15349bd4c9e669f3b1edcbbc2b (patch)
tree6b511a58ac3a8f36603e649d9d09442196b6ed34 /src
parent8ab017ac1928db4a9a9f8eb6b579245814cde725 (diff)
updates
Diffstat (limited to 'src')
-rw-r--r--src/client/views/MainView.tsx6
-rw-r--r--src/client/views/animationtimeline/Keyframe.tsx59
-rw-r--r--src/client/views/animationtimeline/Timeline.tsx51
-rw-r--r--src/client/views/animationtimeline/TimelineMenu.tsx20
-rw-r--r--src/client/views/animationtimeline/Track.tsx40
5 files changed, 87 insertions, 89 deletions
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index d5482bc12..126760234 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -206,9 +206,9 @@ export class MainView extends React.Component {
if (targets && targets.length && targets[0].className.toString().indexOf("contextMenu") === -1) {
ContextMenu.Instance.closeMenu();
}
- // if (targets && targets.length && targets[0].className.toString().indexOf("timeline-menu-container") === -1) {
- // TimelineMenu.Instance.closeMenu();
- // }
+ if (targets && targets.length && targets[0].className.toString().indexOf("timeline-menu-desc") === -1 || targets[0].className.toString().indexOf("timeline-menu-item") === -1 || targets[0].className.toString().indexOf("timeline-menu-item") === -1 || targets[0].className.toString().indexOf("timeline-menu-input") === -1){
+ TimelineMenu.Instance.closeMenu();
+ }
});
globalPointerUp = () => this.isPointerDown = false;
diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx
index b02d89bf0..2f0a968b9 100644
--- a/src/client/views/animationtimeline/Keyframe.tsx
+++ b/src/client/views/animationtimeline/Keyframe.tsx
@@ -28,7 +28,7 @@ export namespace KeyframeFunc {
let leftMost: (RegionData | undefined) = undefined;
let rightMost: (RegionData | undefined) = undefined;
DocListCast(regions).forEach(region => {
- let neighbor = RegionData(region as Doc);
+ let neighbor = RegionData(region);
if (currentRegion.position! > neighbor.position) {
if (!leftMost || neighbor.position > leftMost.position) {
leftMost = neighbor;
@@ -230,7 +230,6 @@ export class Keyframe extends React.Component<IProps> {
let doclist = (await DocListCastAsync(this.regiondata.keyframes))!;
let existingkf: (Doc | undefined) = undefined;
doclist.forEach(TK => {
- TK = TK as Doc;
if (TK.time === kfpos) existingkf = TK;
});
if (existingkf) return existingkf;
@@ -299,8 +298,8 @@ export class Keyframe extends React.Component<IProps> {
this.regiondata.position = 0;
} else if ((left && left.position + left.duration >= futureX)) {
this.regiondata.position = left.position + left.duration;
- } else if ((right && right.position <= futureX + this.pixelDuration)) {
- this.regiondata.position = right.position - this.pixelDuration;
+ } else if ((right && right.position <= futureX + this.regiondata.duration)) {
+ this.regiondata.position = right.position - this.regiondata.duration;
} else {
this.regiondata.position = futureX;
}
@@ -353,7 +352,8 @@ export class Keyframe extends React.Component<IProps> {
this.regiondata.duration -= offset;
this.regiondata.position += offset;
}
-
+ this.keyframes[0].time = this.regiondata.position;
+ this.keyframes[1].time = this.regiondata.position + this.regiondata.fadeIn;
}
@@ -375,6 +375,8 @@ export class Keyframe extends React.Component<IProps> {
} else {
this.regiondata.duration += offset;
}
+ this.keyframes[this.keyframes.length - 2].time = this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut;
+ this.keyframes[this.keyframes.length - 1].time = this.regiondata.position + this.regiondata.duration;
}
@@ -408,24 +410,36 @@ export class Keyframe extends React.Component<IProps> {
@action
makeKeyframeMenu = (kf :Doc, e:MouseEvent) => {
- let items = [
- TimelineMenu.Instance.addItem("button", "Show Data", () => {
- runInAction(() => {let kvp = Docs.Create.KVPDocument(Cast(kf.key, Doc) as Doc, { width: 300, height: 300 });
+
+ TimelineMenu.Instance.addItem("button", "Show Data", () => {
+ runInAction(() => {let kvp = Docs.Create.KVPDocument(Cast(kf.key, Doc) as Doc, { width: 300, height: 300 });
CollectionDockingView.Instance.AddRightSplit(kvp, (kf.key as Doc).data as Doc); });
- }),
- TimelineMenu.Instance.addItem("button", "Delete", () => {}),
- TimelineMenu.Instance.addItem("input", "Move", (val) => {kf.time = parseInt(val, 10);})
- ];
- TimelineMenu.Instance.addMenu("Keyframe", items);
+ }),
+ TimelineMenu.Instance.addItem("button", "Delete", () => {}),
+ TimelineMenu.Instance.addItem("input", "Move", (val) => {kf.time = parseInt(val, 10);});
+
+ TimelineMenu.Instance.addMenu("Keyframe");
TimelineMenu.Instance.openMenu(e.clientX, e.clientY);
-}
+ }
+
+ @action
+ makeRegionMenu = (kf: Doc, e: MouseEvent) => {
+ TimelineMenu.Instance.addItem("button", "Add Ease", () => {this.onContainerDown(kf, "interpolate");}),
+ TimelineMenu.Instance.addItem("button", "Add Path", () => {this.onContainerDown(kf, "path");}),
+ TimelineMenu.Instance.addItem("input", "fadeIn", (val) => {this.regiondata.fadeIn = parseInt(val, 10);}),
+ TimelineMenu.Instance.addItem("input", "fadeOut", (val) => {this.regiondata.fadeOut = parseInt(val, 10);}),
+ TimelineMenu.Instance.addItem("input", "position", (val) => {this.regiondata.position = parseInt(val, 10);}),
+ TimelineMenu.Instance.addItem("input", "duration", (val) => {this.regiondata.duration = parseInt(val, 10);}),
+ TimelineMenu.Instance.addMenu("Region");
+ TimelineMenu.Instance.openMenu(e.clientX, e.clientY);
+ }
@action
private createKeyframeJSX = (kf: Doc, type = KeyframeFunc.KeyframeType.default) => {
if (type === KeyframeFunc.KeyframeType.default) {
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" onPointerDown={(e) => { this.moveKeyframe(e, kf as Doc); }} onContextMenu={(e: React.MouseEvent) => {
+ <div className="keyframeCircle" onPointerDown={(e) => { this.moveKeyframe(e, kf); }} onContextMenu={(e: React.MouseEvent) => {
e.preventDefault();
e.stopPropagation();
this.makeKeyframeMenu(kf, e.nativeEvent);
@@ -546,7 +560,9 @@ export class Keyframe extends React.Component<IProps> {
onPointerDown={this.onBarPointerDown}>
<div className="leftResize" onPointerDown={this.onResizeLeft} ></div>
<div className="rightResize" onPointerDown={this.onResizeRight}></div>
- {this.keyframes.map(kf => { this.createKeyframeJSX(kf, kf.type as KeyframeFunc.KeyframeType); })}
+ {this.keyframes.map(kf => {
+ return this.createKeyframeJSX(kf, kf.type as KeyframeFunc.KeyframeType);
+ })}
{this.keyframes.map( kf => {
if(this.keyframes.indexOf(kf ) !== this.keyframes.length - 1) {
let left = this.keyframes[this.keyframes.indexOf(kf) + 1];
@@ -561,16 +577,7 @@ export class Keyframe extends React.Component<IProps> {
e.preventDefault();
e.stopPropagation();
this._mouseToggled = true;
- let items = [
- TimelineMenu.Instance.addItem("button", "Add Ease", () => {this.onContainerDown(kf, "interpolate");}),
- TimelineMenu.Instance.addItem("button", "Add Path", () => {this.onContainerDown(kf, "path");}),
- TimelineMenu.Instance.addItem("input", "fadeIn", (val) => {this.regiondata.fadeIn = parseInt(val, 10);}),
- TimelineMenu.Instance.addItem("input", "fadeOut", (val) => {this.regiondata.fadeOut = parseInt(val, 10);}),
- TimelineMenu.Instance.addItem("input", "position", (val) => {this.regiondata.position = parseInt(val, 10);}),
- TimelineMenu.Instance.addItem("input", "duration", (val) => {this.regiondata.duration = parseInt(val, 10);}),
- ];
- TimelineMenu.Instance.addMenu("Region", items);
- TimelineMenu.Instance.openMenu(e.clientX, e.clientY);
+ this.makeRegionMenu(kf, e.nativeEvent);
}}>
</div>
);
diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx
index 036c3ad9b..4eb5958b5 100644
--- a/src/client/views/animationtimeline/Timeline.tsx
+++ b/src/client/views/animationtimeline/Timeline.tsx
@@ -1,7 +1,6 @@
import * as React from "react";
import "./Timeline.scss";
-import { CollectionSubView } from "../collections/CollectionSubView";
-import { Document, listSpec } from "../../../new_fields/Schema";
+import { listSpec } from "../../../new_fields/Schema";
import { observer } from "mobx-react";
import { Track } from "./Track";
import { observable, reaction, action, IReactionDisposer, computed, runInAction, observe } from "mobx";
@@ -13,8 +12,8 @@ import { faPlayCircle, faBackward, faForward, faGripLines, faArrowUp, faArrowDow
import { ContextMenuProps } from "../ContextMenuItem";
import { ContextMenu } from "../ContextMenu";
import { TimelineOverview } from "./TimelineOverview";
-import { playcustomapp } from "googleapis/build/src/apis/playcustomapp";
-import { FieldView, FieldViewProps } from "../nodes/FieldView";
+import { FieldViewProps } from "../nodes/FieldView";
+import { KeyframeFunc } from "./Keyframe";
@@ -62,6 +61,8 @@ export class Timeline extends React.Component<FieldViewProps> {
@observable private _timelineVisible = false;
@observable private _mouseToggled = false;
@observable private _doubleClickEnabled = false;
+ @observable private _mutationDisposer:MutationObserver[] = [];
+ @observable private _reactionDisposer:IReactionDisposer[] = [];
@computed
@@ -89,7 +90,7 @@ export class Timeline extends React.Component<FieldViewProps> {
console.log(this.props.Document.duration);
if (this.props.Document.duration) {
this._time = Math.round(NumCast(this.props.Document.duration)) * 1000;
- reaction(() => {
+ this._reactionDisposer.push(reaction(() => {
return NumCast(this.props.Document.curPage);
}, curPage => {
if (!this._isPlaying) {
@@ -97,12 +98,11 @@ export class Timeline extends React.Component<FieldViewProps> {
this.props.Document.curPage = this._currentBarX;
this.play();
}
-
- });
+ }));
}
}
runInAction(() => {
- reaction(() => {
+ this._reactionDisposer.push(reaction(() => {
return this._time;
}, () => {
this._ticks = [];
@@ -111,7 +111,7 @@ export class Timeline extends React.Component<FieldViewProps> {
i += 1000;
}
this._totalLength = this._tickSpacing * (this._time/ this._tickIncrement);
- }, {fireImmediately:true});
+ }, {fireImmediately:true}));
this._totalLength = this._tickSpacing * (this._ticks.length/ this._tickIncrement);
this._visibleLength = this._infoContainer.current!.getBoundingClientRect().width;
this._visibleStart = this._infoContainer.current!.scrollLeft;
@@ -321,7 +321,6 @@ export class Timeline extends React.Component<FieldViewProps> {
return `${min}:${sec}`;
}
-
timelineContextMenu = (e:MouseEvent): void => {
let subitems: ContextMenuProps[] = [];
let timelineContainer = this._timelineWrapper.current!;
@@ -354,31 +353,41 @@ export class Timeline extends React.Component<FieldViewProps> {
onWheelZoom = (e: React.WheelEvent) => {
e.preventDefault();
e.stopPropagation();
+ let offset = e.clientX - this._infoContainer.current!.getBoundingClientRect().left;
+ let prevTime = KeyframeFunc.convertPixelTime(this._visibleStart + offset, "mili", "time", this._tickSpacing, this._tickIncrement);
e.deltaY < 0 ? this.zoom(true) : this.zoom(false);
+ let currPixel = KeyframeFunc.convertPixelTime(prevTime, "mili", "pixel", this._tickSpacing, this._tickIncrement);
+ this._infoContainer.current!.scrollLeft = currPixel - offset;
+ this._visibleStart = currPixel - offset;
}
@action
zoom = (dir: boolean) => {
+ let spacingChange = this._tickSpacing;
+ let incrementChange = this._tickIncrement;
if (dir){
if (!(this._tickSpacing === 100 && this._tickIncrement === 1000)){
if (this._tickSpacing >= 100) {
- this._tickIncrement /= 2;
- this._tickSpacing = 50;
+ incrementChange /= 2;
+ spacingChange = 50;
} else {
- this._tickSpacing += 10;
+ spacingChange += 5;
}
}
} else {
- if (this._totalLength >= this._infoContainer.current!.getBoundingClientRect().width){
- if (this._tickSpacing <= 50) {
- this._tickSpacing = 100;
- this._tickIncrement *= 2;
- } else {
- this._tickSpacing -= 10;
- }
+ if (this._tickSpacing <= 50) {
+ spacingChange = 100;
+ incrementChange *= 2;
+ } else {
+ spacingChange -= 5;
}
}
- this._totalLength = this._tickSpacing * (this._time/ this._tickIncrement);
+ let finalLength = spacingChange * (this._time / incrementChange);
+ if (finalLength >= this._infoContainer.current!.getBoundingClientRect().width){
+ this._totalLength = finalLength;
+ this._tickSpacing = spacingChange;
+ this._tickIncrement = incrementChange;
+ }
}
private timelineToolBox = (scale:number) => {
diff --git a/src/client/views/animationtimeline/TimelineMenu.tsx b/src/client/views/animationtimeline/TimelineMenu.tsx
index 3e63eec61..572b35b90 100644
--- a/src/client/views/animationtimeline/TimelineMenu.tsx
+++ b/src/client/views/animationtimeline/TimelineMenu.tsx
@@ -31,31 +31,31 @@ export class TimelineMenu extends React.Component {
closeMenu = () => {
this._opacity = 0;
this._currentMenu = [];
+ this._x = -1000000;
+ this._y = -1000000;
}
+ @action
addItem = (type: "input" | "button", title: string, event: (e:any) => void) => {
if (type === "input"){
- let ref = React.createRef<HTMLInputElement>();
- return <div className="timeline-menu-item"><FontAwesomeIcon icon={faClipboard} size="lg"/><input className="timeline-menu-input" ref = {ref} placeholder={title} onChange={(e) => {
+ let inputRef = React.createRef<HTMLInputElement>();
+ this._currentMenu.push( <div className="timeline-menu-item"><FontAwesomeIcon icon={faClipboard} size="lg"/><input className="timeline-menu-input" ref = {inputRef} placeholder={title} onChange={(e) => {
let text = e.target.value;
document.addEventListener("keypress", (e:KeyboardEvent) => {
if (e.keyCode === 13) {
event(text);
}
});
- }}/></div>;
+ }}/></div>);
} else if (type === "button") {
- let ref = React.createRef<HTMLDivElement>();
- return <div className="timeline-menu-item"><FontAwesomeIcon icon={faChartLine}size="lg"/><p className="timeline-menu-desc" onClick={event}>{title}</p></div>;
+ let buttonRef = React.createRef<HTMLDivElement>();
+ this._currentMenu.push( <div className="timeline-menu-item"><FontAwesomeIcon icon={faChartLine}size="lg"/><p className="timeline-menu-desc" onClick={event}>{title}</p></div>);
}
- return <div></div>;
}
@action
- addMenu = (title:string, items: JSX.Element[]) => {
- items.unshift(<div className="timeline-menu-header"><p className="timeline-menu-header-desc">{title}</p></div>);
- this._currentMenu = items;
-
+ addMenu = (title:string) => {
+ this._currentMenu.unshift(<div className="timeline-menu-header"><p className="timeline-menu-header-desc">{title}</p></div>);
}
render() {
diff --git a/src/client/views/animationtimeline/Track.tsx b/src/client/views/animationtimeline/Track.tsx
index 5a43f5b2a..13fe55e80 100644
--- a/src/client/views/animationtimeline/Track.tsx
+++ b/src/client/views/animationtimeline/Track.tsx
@@ -1,16 +1,14 @@
import * as React from "react";
import { observer } from "mobx-react";
-import { observable, reaction, action, IReactionDisposer, observe, IObservableArray, computed, toJS, IObservableObject, runInAction, autorun } from "mobx";
+import { observable, reaction, action, IReactionDisposer, computed, runInAction, autorun } from "mobx";
import "./Track.scss";
import { Doc, DocListCastAsync, DocListCast, Field } from "../../../new_fields/Doc";
import { listSpec } from "../../../new_fields/Schema";
import { FieldValue, Cast, NumCast, BoolCast, StrCast } from "../../../new_fields/Types";
import { List } from "../../../new_fields/List";
import { Keyframe, KeyframeFunc, RegionData } from "./Keyframe";
-import { FlyoutProps } from "./Timeline";
import { Transform } from "../../util/Transform";
import { RichTextField } from "../../../new_fields/RichTextField";
-import { createObjectBindingPattern } from "typescript";
import { DateField } from "../../../new_fields/DateField";
interface IProps {
@@ -68,23 +66,7 @@ export class Track extends React.Component<IProps> {
if (kf.type === KeyframeFunc.KeyframeType.default) { // only save for non-fades
kf.key = Doc.MakeCopy(this.props.node, true);
let leftkf: (Doc | undefined) = await KeyframeFunc.calcMinLeft(regiondata!, KeyframeFunc.convertPixelTime(this.props.currentBarX, "mili", "time", this.props.tickSpacing, this.props.tickIncrement), kf); // lef keyframe, if it exists
- let rightkf: (Doc | undefined) = await KeyframeFunc.calcMinRight(regiondata!, KeyframeFunc.convertPixelTime(this.props.currentBarX, "mili", "time", this.props.tickSpacing, this.props.tickIncrement), kf); //right keyframe, if it exists
- // while (leftkf !== undefined) {
- // if (leftkf!.type === KeyframeFunc.KeyframeType.fade) {
- // let edge:(Doc | undefined) = await KeyframeFunc.calcMinLeft(regiondata!, KeyframeFunc.convertPixelTime(this.props.currentBarX, "mili", "time", this.props.tickSpacing, this.props.tickIncrement), leftkf!);
- // edge!.key = Doc.MakeCopy(kf.key as Doc, true);
- // leftkf!.key = Doc.MakeCopy(kf.key as Doc, true);
- // (Cast(edge!.key, Doc)! as Doc).opacity = 0.1;
- // (Cast(leftkf!.key, Doc)! as Doc).opacity = 1;
- // } else if (leftkf!.key ) {
- // leftkf!.key = Doc.MakeCopy(kf.key as Doc, true);
- // }
-
- // }
-
-
-
-
+ let rightkf: (Doc | undefined) = await KeyframeFunc.calcMinRight(regiondata!, KeyframeFunc.convertPixelTime(this.props.currentBarX, "mili", "time", this.props.tickSpacing, this.props.tickIncrement), kf); //right keyframe, if it exists
if (leftkf!.type === KeyframeFunc.KeyframeType.fade) { //replicating this keyframe to fades
let edge:(Doc | undefined) = await KeyframeFunc.calcMinLeft(regiondata!, KeyframeFunc.convertPixelTime(this.props.currentBarX, "mili", "time", this.props.tickSpacing, this.props.tickIncrement), leftkf!);
edge!.key = Doc.MakeCopy(kf.key as Doc, true);
@@ -160,7 +142,6 @@ export class Track extends React.Component<IProps> {
this.props.node[key] = new RichTextField(nodeData);
}
} else if (key === "creationDate") {
-
this.props.node[key] = new DateField();
} else {
this.props.node[key] = kfNode[key];
@@ -175,9 +156,9 @@ export class Track extends React.Component<IProps> {
@action
private filterKeys = (keys: string[]): string[] => {
return keys.reduce((acc: string[], key: string) => {
- if (key !== "regions" && key !== "cursors" && key !== "hidden" && key !== "nativeHeight" && key !== "nativeWidth" && key !== "schemaColumns") acc.push(key);
+ if (key !== "regions" && key !== "cursors" && key !== "hidden" && key !== "nativeHeight" && key !== "nativeWidth" && key !== "schemaColumns" && key !== "creationDate") acc.push(key);
return acc;
- }, []) as string[];
+ }, []);
}
@action
@@ -280,15 +261,16 @@ export class Track extends React.Component<IProps> {
createRegion = (position: number) => {
let regiondata = KeyframeFunc.defaultKeyframe();
regiondata.position = position;
- let leftRegion = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.left, regiondata, this.regions);
let rightRegion = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.right, regiondata, this.regions);
- if ((rightRegion && leftRegion && rightRegion.position - (leftRegion.position + leftRegion.duration) < NumCast(regiondata.fadeIn) + NumCast(regiondata.fadeOut)) || (rightRegion && rightRegion.position - regiondata.position < NumCast(regiondata.fadeIn) + NumCast(regiondata.fadeOut))) {
- return;
- } else if (rightRegion && rightRegion.position - regiondata.position >= NumCast(regiondata.fadeIn) + NumCast(regiondata.fadeOut)) {
+
+ if (rightRegion && rightRegion.position - regiondata.position <= 4000) {
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);
+ return regiondata;
}
- this.regions.push(regiondata);
- return regiondata;
+
}