aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorandrewdkim <adkim414@gmail.com>2019-11-12 19:01:42 -0500
committerandrewdkim <adkim414@gmail.com>2019-11-12 19:01:42 -0500
commitd7f772d93458e7669a1d2e954ad741e1c67318a5 (patch)
tree71dbdac98f1a0e0de38f3b7b76d9e543c2313bd8 /src
parent13de65ec4ca3fbeef4a687d079e7b480bd691764 (diff)
undo
Diffstat (limited to 'src')
-rw-r--r--src/client/views/animationtimeline/Keyframe.tsx456
-rw-r--r--src/new_fields/util.ts3
2 files changed, 240 insertions, 219 deletions
diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx
index 424f4ed8d..a2d0a644e 100644
--- a/src/client/views/animationtimeline/Keyframe.tsx
+++ b/src/client/views/animationtimeline/Keyframe.tsx
@@ -2,7 +2,7 @@ import * as React from "react";
import "./Keyframe.scss";
import "./Timeline.scss";
import "../globalCssVariables.scss";
-import { observer} from "mobx-react";
+import { observer } from "mobx-react";
import { observable, reaction, action, IReactionDisposer, observe, computed, runInAction } from "mobx";
import { Doc, DocListCast, DocListCastAsync } from "../../../new_fields/Doc";
import { Cast, NumCast } from "../../../new_fields/Types";
@@ -13,6 +13,7 @@ import { InkField, StrokeData } from "../../../new_fields/InkField";
import { TimelineMenu } from "./TimelineMenu";
import { Docs } from "../../documents/Documents";
import { CollectionDockingView } from "../collections/CollectionDockingView";
+import { undoBatch, UndoManager } from "../../util/UndoManager";
export namespace KeyframeFunc {
export enum KeyframeType {
@@ -86,23 +87,23 @@ export namespace KeyframeFunc {
regiondata.position = 0;
regiondata.fadeIn = 1000;
regiondata.fadeOut = 1000;
- regiondata.functions = new List<Doc>();
+ regiondata.functions = new List<Doc>();
return regiondata;
};
- export const convertPixelTime = (pos: number, unit: "mili" | "sec" | "min" | "hr", dir: "pixel" | "time", tickSpacing:number, tickIncrement:number) => {
- let time = dir === "pixel" ? (pos * tickSpacing) / tickIncrement : (pos / tickSpacing) * tickIncrement;
+ export const convertPixelTime = (pos: number, unit: "mili" | "sec" | "min" | "hr", dir: "pixel" | "time", tickSpacing: number, tickIncrement: number) => {
+ let time = dir === "pixel" ? (pos * tickSpacing) / tickIncrement : (pos / tickSpacing) * tickIncrement;
switch (unit) {
case "mili":
- return time;
+ return time;
case "sec":
- return dir === "pixel" ? time / 1000 : time * 1000;
+ return dir === "pixel" ? time / 1000 : time * 1000;
case "min":
- return dir === "pixel" ? time / 60000 : time * 60000;
+ return dir === "pixel" ? time / 60000 : time * 60000;
case "hr":
- return dir === "pixel" ? time / 3600000 : time * 3600000;
- default:
- return time;
+ return dir === "pixel" ? time / 3600000 : time * 3600000;
+ default:
+ return time;
}
};
}
@@ -113,7 +114,7 @@ export const RegionDataSchema = createSchema({
keyframes: listSpec(Doc),
fadeIn: defaultSpec("number", 0),
fadeOut: defaultSpec("number", 0),
- functions: listSpec(Doc)
+ functions: listSpec(Doc)
});
export type RegionData = makeInterface<[typeof RegionDataSchema]>;
export const RegionData = makeInterface(RegionDataSchema);
@@ -122,13 +123,13 @@ interface IProps {
node: Doc;
RegionData: Doc;
collection: Doc;
- tickSpacing: number;
- tickIncrement: number;
- time: number;
- check: string;
+ tickSpacing: number;
+ tickIncrement: number;
+ time: number;
+ check: string;
changeCurrentBarX: (x: number) => void;
transform: Transform;
- checkCallBack: (visible: boolean) => void;
+ checkCallBack: (visible: boolean) => void;
}
@observer
@@ -136,16 +137,16 @@ export class Keyframe extends React.Component<IProps> {
@observable private _bar = React.createRef<HTMLDivElement>();
@observable private _gain = 20; //default
- @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 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); }
+ @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 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); }
+ @computed private get pixelFadeOut() { return KeyframeFunc.convertPixelTime(this.regiondata.fadeOut, "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement); }
@computed
private get inks() {
if (this.props.collection.data_ext) {
@@ -168,12 +169,13 @@ export class Keyframe extends React.Component<IProps> {
(fadeOut.key! as Doc).opacity = 1;
(start.key! as Doc).opacity = 0.1;
(finish.key! as Doc).opacity = 0.1;
- this.forceUpdate();
- });
+ this.forceUpdate();
+ });
}
@action
makeKeyData = async (kfpos: number, type: KeyframeFunc.KeyframeType = KeyframeFunc.KeyframeType.default) => { //Kfpos is mouse offsetX, representing time
+ const batch = UndoManager.StartBatch("makeKeyData");
let doclist = (await DocListCastAsync(this.regiondata.keyframes))!;
let existingkf: (Doc | undefined) = undefined;
doclist.forEach(TK => {
@@ -183,45 +185,54 @@ export class Keyframe extends React.Component<IProps> {
let TK: Doc = new Doc();
TK.time = kfpos;
TK.key = Doc.MakeCopy(this.props.node, true);
- TK.type = type;
+ TK.type = type;
this.regiondata.keyframes!.push(TK);
- let interpolationFunctions = new Doc();
- interpolationFunctions.interpolationX = new List<number>([0, 1]);
- interpolationFunctions.interpolationY = new List<number>([0,100]);
- interpolationFunctions.pathX = new List<number>();
- interpolationFunctions.pathY = new List<number>();
+ // myObservable++;
+ // UndoManager.AddEvent({
+ // undo: action(() => myObservable--),
+ // redo: action(() => myObservable++)
+ // });
+
+ let interpolationFunctions = new Doc();
+ interpolationFunctions.interpolationX = new List<number>([0, 1]);
+ interpolationFunctions.interpolationY = new List<number>([0, 100]);
+ interpolationFunctions.pathX = new List<number>();
+ interpolationFunctions.pathY = new List<number>();
- this.regiondata.functions!.push(interpolationFunctions);
- let found:boolean = false;
+ this.regiondata.functions!.push(interpolationFunctions);
+ let found: boolean = false;
this.regiondata.keyframes!.forEach(compkf => {
- compkf = compkf as Doc;
+ compkf = compkf as Doc;
if (kfpos < NumCast(compkf.time) && !found) {
runInAction(() => {
this.regiondata.keyframes!.splice(doclist.indexOf(compkf as Doc), 0, TK);
- this.regiondata.keyframes!.pop();
- found = true;
- });
- return;
+ this.regiondata.keyframes!.pop();
+ found = true;
+ });
+ return;
}
});
+ batch.end();
return TK;
}
-
+
@action
onBarPointerDown = (e: React.PointerEvent) => {
e.preventDefault();
e.stopPropagation();
- let clientX = e.clientX;
- if (this._doubleClickEnabled){
- this.createKeyframe(clientX);
- this._doubleClickEnabled = false;
+ let clientX = e.clientX;
+ if (this._doubleClickEnabled) {
+ this.createKeyframe(clientX);
+ this._doubleClickEnabled = false;
} else {
- setTimeout(() => {if(!this._mouseToggled && this._doubleClickEnabled)this.props.changeCurrentBarX(this.pixelPosition + (clientX - this._bar.current!.getBoundingClientRect().left) * this.props.transform.Scale);
- this._mouseToggled = false;
- this._doubleClickEnabled = false; }, 200);
- this._doubleClickEnabled = true;
+ setTimeout(() => {
+ if (!this._mouseToggled && this._doubleClickEnabled) this.props.changeCurrentBarX(this.pixelPosition + (clientX - this._bar.current!.getBoundingClientRect().left) * this.props.transform.Scale);
+ this._mouseToggled = false;
+ this._doubleClickEnabled = false;
+ }, 200);
+ this._doubleClickEnabled = true;
document.addEventListener("pointermove", this.onBarPointerMove);
document.addEventListener("pointerup", (e: PointerEvent) => {
document.removeEventListener("pointermove", this.onBarPointerMove);
@@ -235,7 +246,7 @@ export class Keyframe extends React.Component<IProps> {
e.preventDefault();
e.stopPropagation();
if (e.movementX !== 0) {
- this._mouseToggled = true;
+ this._mouseToggled = true;
}
let left = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.left, this.regiondata, this.regions)!;
let right = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.right, this.regiondata, this.regions!);
@@ -249,10 +260,10 @@ export class Keyframe extends React.Component<IProps> {
this.regiondata.position = right.position - this.regiondata.duration;
} else {
this.regiondata.position = futureX;
- }
- let movement = this.regiondata.position - prevX;
+ }
+ let movement = this.regiondata.position - prevX;
this.keyframes.forEach(kf => {
- kf.time = NumCast(kf.time) + movement;
+ kf.time = NumCast(kf.time) + movement;
});
}
@@ -284,17 +295,17 @@ export class Keyframe extends React.Component<IProps> {
let offset = KeyframeFunc.convertPixelTime(Math.round((e.clientX - bar.getBoundingClientRect().left) * this.props.transform.Scale), "mili", "time", this.props.tickSpacing, this.props.tickIncrement);
let leftRegion = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.left, this.regiondata, this.regions);
if (leftRegion && this.regiondata.position + offset <= leftRegion.position + leftRegion.duration) {
- this.regiondata.position = leftRegion.position + leftRegion.duration;
- this.regiondata.duration = NumCast(this.keyframes[this.keyframes.length - 1].time) - (leftRegion.position + leftRegion.duration);
+ this.regiondata.position = leftRegion.position + leftRegion.duration;
+ this.regiondata.duration = NumCast(this.keyframes[this.keyframes.length - 1].time) - (leftRegion.position + leftRegion.duration);
} else if (NumCast(this.keyframes[1].time) + offset >= NumCast(this.keyframes[2].time)) {
- this.regiondata.position = NumCast(this.keyframes[2].time) - this.regiondata.fadeIn;
- this.regiondata.duration = NumCast(this.keyframes[this.keyframes.length - 1].time) - NumCast(this.keyframes[2].time) + this.regiondata.fadeIn;
+ this.regiondata.position = NumCast(this.keyframes[2].time) - this.regiondata.fadeIn;
+ this.regiondata.duration = NumCast(this.keyframes[this.keyframes.length - 1].time) - NumCast(this.keyframes[2].time) + this.regiondata.fadeIn;
} else {
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;
+ this.keyframes[0].time = this.regiondata.position;
+ this.keyframes[1].time = this.regiondata.position + this.regiondata.fadeIn;
}
@@ -305,22 +316,22 @@ export class Keyframe extends React.Component<IProps> {
let bar = this._bar.current!;
let offset = KeyframeFunc.convertPixelTime(Math.round((e.clientX - bar.getBoundingClientRect().right) * this.props.transform.Scale), "mili", "time", this.props.tickSpacing, this.props.tickIncrement);
let rightRegion = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.right, this.regiondata, this.regions);
- let fadeOutKeyframeTime = NumCast(this.keyframes[this.keyframes.length - 3].time);
+ let fadeOutKeyframeTime = NumCast(this.keyframes[this.keyframes.length - 3].time);
if (this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut + offset <= fadeOutKeyframeTime) { //case 1: when third to last keyframe is in the way
this.regiondata.duration = fadeOutKeyframeTime - this.regiondata.position + this.regiondata.fadeOut;
- } else if (rightRegion && (this.regiondata.position + this.regiondata.duration + offset >= rightRegion.position)){
- this.regiondata.duration = rightRegion.position - this.regiondata.position;
+ } else if (rightRegion && (this.regiondata.position + this.regiondata.duration + offset >= rightRegion.position)) {
+ this.regiondata.duration = rightRegion.position - this.regiondata.position;
} 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;
+ 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;
}
@action
- createKeyframe = async (clientX:number) => {
- this._mouseToggled = true;
+ createKeyframe = async (clientX: number) => {
+ this._mouseToggled = true;
let bar = this._bar.current!;
let offset = KeyframeFunc.convertPixelTime(Math.round((clientX - bar.getBoundingClientRect().left) * this.props.transform.Scale), "mili", "time", this.props.tickSpacing, this.props.tickIncrement);
if (offset > this.regiondata.fadeIn && offset < this.regiondata.duration - this.regiondata.fadeOut) { //make sure keyframe is not created inbetween fades and ends
@@ -330,7 +341,7 @@ export class Keyframe extends React.Component<IProps> {
}
}
-
+
@action
moveKeyframe = async (e: React.MouseEvent, kf: Doc) => {
e.preventDefault();
@@ -346,126 +357,134 @@ export class Keyframe extends React.Component<IProps> {
this.props.node.backgroundColor = "#000000";
}
- @action
- makeKeyframeMenu = (kf :Doc, e:MouseEvent) => {
+ @action
+ makeKeyframeMenu = (kf: Doc, e: MouseEvent) => {
TimelineMenu.Instance.addItem("button", "Show Data", () => {
- runInAction(() => {let kvp = Docs.Create.KVPDocument(Cast(kf.key, Doc) as Doc, { width: 300, height: 300 });
- CollectionDockingView.AddRightSplit(kvp, (kf.key as Doc).data as Doc); });
- }),
- TimelineMenu.Instance.addItem("button", "Delete", () => {
- runInAction(() => {
- (this.regiondata.keyframes as List<Doc>).splice(this.keyframes.indexOf(kf), 1);
- this.forceUpdate();
- });
- }),
- TimelineMenu.Instance.addItem("input", "Move", (val) => {
runInAction(() => {
- if (this.checkInput(val)){
- let cannotMove:boolean = false;
- let kfIndex:number = this.keyframes.indexOf(kf);
- if (val < 0 ||( val < NumCast(this.keyframes[kfIndex - 1].time) || val > NumCast(this.keyframes[kfIndex + 1].time)) ){
- cannotMove = true;
- }
- if (!cannotMove){
- this.keyframes[kfIndex].time = parseInt(val, 10);
- this.keyframes[1].time = this.regiondata.position + this.regiondata.fadeIn;
+ let kvp = Docs.Create.KVPDocument(Cast(kf.key, Doc) as Doc, { width: 300, height: 300 });
+ CollectionDockingView.AddRightSplit(kvp, (kf.key as Doc).data as Doc);
+ });
+ }),
+ TimelineMenu.Instance.addItem("button", "Delete", () => {
+ runInAction(() => {
+ (this.regiondata.keyframes as List<Doc>).splice(this.keyframes.indexOf(kf), 1);
+ this.forceUpdate();
+ });
+ }),
+ TimelineMenu.Instance.addItem("input", "Move", (val) => {
+ runInAction(() => {
+ if (this.checkInput(val)) {
+ let cannotMove: boolean = false;
+ let kfIndex: number = this.keyframes.indexOf(kf);
+ if (val < 0 || (val < NumCast(this.keyframes[kfIndex - 1].time) || val > NumCast(this.keyframes[kfIndex + 1].time))) {
+ cannotMove = true;
+ }
+ if (!cannotMove) {
+ this.keyframes[kfIndex].time = parseInt(val, 10);
+ this.keyframes[1].time = this.regiondata.position + this.regiondata.fadeIn;
+ }
}
- }
- });
+ });
});
- TimelineMenu.Instance.addMenu("Keyframe");
- TimelineMenu.Instance.openMenu(e.clientX, e.clientY);
+ TimelineMenu.Instance.addMenu("Keyframe");
+ TimelineMenu.Instance.openMenu(e.clientX, e.clientY);
}
- @action
+ @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("button", "Remove Region", ()=>{
- runInAction(() => {
- this.regions.splice(this.regions.indexOf(this.props.RegionData), 1);}
- );}),
- TimelineMenu.Instance.addItem("input", `fadeIn: ${this.regiondata.fadeIn}ms`, (val) => {
- runInAction(() => {
- if (this.checkInput(val)){
- let cannotMove:boolean = false;
- if (val < 0 || val > NumCast(this.keyframes[2].time) - this.regiondata.position){
- cannotMove = true;
- }
- if (!cannotMove){
- this.regiondata.fadeIn = parseInt(val, 10);
- this.keyframes[1].time = this.regiondata.position + this.regiondata.fadeIn;
- }
+ TimelineMenu.Instance.addItem("button", "Add Path", () => {
+ this.onContainerDown(kf, "path");
+ }),
+ TimelineMenu.Instance.addItem("button", "Remove Region", () => {
+ runInAction(() => {
+ this.regions.splice(this.regions.indexOf(this.props.RegionData), 1);
}
- });}),
- TimelineMenu.Instance.addItem("input", `fadeOut: ${this.regiondata.fadeOut}ms`, (val) => {
- runInAction(() => {
- if (this.checkInput(val)){
- let cannotMove:boolean = false;
- if (val < 0 || val > this.regiondata.position + this.regiondata.duration - NumCast(this.keyframes[this.keyframes.length - 3].time)){
- cannotMove = true;
- }
- if (!cannotMove){
- this.regiondata.fadeOut = parseInt(val, 10);
- this.keyframes[this.keyframes.length - 2].time = this.regiondata.position + this.regiondata.duration - val;
+ );
+ }),
+ TimelineMenu.Instance.addItem("input", `fadeIn: ${this.regiondata.fadeIn}ms`, (val) => {
+ runInAction(() => {
+ if (this.checkInput(val)) {
+ let cannotMove: boolean = false;
+ if (val < 0 || val > NumCast(this.keyframes[2].time) - this.regiondata.position) {
+ cannotMove = true;
+ }
+ if (!cannotMove) {
+ this.regiondata.fadeIn = parseInt(val, 10);
+ this.keyframes[1].time = this.regiondata.position + this.regiondata.fadeIn;
+ }
}
- }
- });}),
- TimelineMenu.Instance.addItem("input", `position: ${this.regiondata.position}ms`, (val) => {
- runInAction(() => {
- if (this.checkInput(val)){
- let prevPosition = this.regiondata.position;
- let cannotMove:boolean = false;
- DocListCast(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)))){
+ });
+ }),
+ TimelineMenu.Instance.addItem("input", `fadeOut: ${this.regiondata.fadeOut}ms`, (val) => {
+ runInAction(() => {
+ if (this.checkInput(val)) {
+ let cannotMove: boolean = false;
+ if (val < 0 || val > this.regiondata.position + this.regiondata.duration - NumCast(this.keyframes[this.keyframes.length - 3].time)) {
cannotMove = true;
}
+ if (!cannotMove) {
+ this.regiondata.fadeOut = parseInt(val, 10);
+ this.keyframes[this.keyframes.length - 2].time = this.regiondata.position + this.regiondata.duration - val;
+ }
}
});
- if (!cannotMove) {
- this.regiondata.position = parseInt(val, 10);
- this.updateKeyframes(this.regiondata.position - prevPosition );
- }
- }
- });}),
- TimelineMenu.Instance.addItem("input", `duration: ${this.regiondata.duration}ms`, (val) => {
- runInAction(() => {
- if (this.checkInput(val)){
- let cannotMove:boolean = false;
- DocListCast(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))){
- cannotMove = true;
+ }),
+ TimelineMenu.Instance.addItem("input", `position: ${this.regiondata.position}ms`, (val) => {
+ runInAction(() => {
+ if (this.checkInput(val)) {
+ let prevPosition = this.regiondata.position;
+ let cannotMove: boolean = false;
+ DocListCast(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;
+ }
}
+ });
+ if (!cannotMove) {
+ this.regiondata.position = parseInt(val, 10);
+ this.updateKeyframes(this.regiondata.position - prevPosition);
}
- });
- if (!cannotMove) {
- this.regiondata.duration = parseInt(val, 10);
- this.keyframes[this.keyframes.length - 1].time = this.regiondata.position + this.regiondata.duration;
- this.keyframes[this.keyframes.length - 2].time = this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut;
}
- }
- });}),
- TimelineMenu.Instance.addMenu("Region");
- TimelineMenu.Instance.openMenu(e.clientX, e.clientY);
+ });
+ }),
+ TimelineMenu.Instance.addItem("input", `duration: ${this.regiondata.duration}ms`, (val) => {
+ runInAction(() => {
+ if (this.checkInput(val)) {
+ let cannotMove: boolean = false;
+ DocListCast(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))) {
+ cannotMove = true;
+ }
+ }
+ });
+ if (!cannotMove) {
+ this.regiondata.duration = parseInt(val, 10);
+ this.keyframes[this.keyframes.length - 1].time = this.regiondata.position + this.regiondata.duration;
+ this.keyframes[this.keyframes.length - 2].time = this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut;
+ }
+ }
+ });
+ }),
+ TimelineMenu.Instance.addMenu("Region");
+ TimelineMenu.Instance.openMenu(e.clientX, e.clientY);
}
@action
checkInput = (val: any) => {
- return typeof(val === "number");
+ return typeof (val === "number");
}
@action
- updateKeyframes = (incr:number, filter:number[] = []) => {
+ updateKeyframes = (incr: number, filter: number[] = []) => {
this.keyframes.forEach(kf => {
- if (!filter.includes(this.keyframes.indexOf(kf))){
- kf.time = NumCast(kf.time) + incr;
+ if (!filter.includes(this.keyframes.indexOf(kf))) {
+ kf.time = NumCast(kf.time) + incr;
}
});
}
@@ -476,7 +495,7 @@ export class Keyframe extends React.Component<IProps> {
e.stopPropagation();
let div = ref.current!;
div.style.opacity = "1";
- Doc.BrushDoc(this.props.node);
+ Doc.BrushDoc(this.props.node);
}
@action
@@ -485,36 +504,36 @@ export class Keyframe extends React.Component<IProps> {
e.stopPropagation();
let div = ref.current!;
div.style.opacity = "0";
- Doc.UnBrushDoc(this.props.node);
+ Doc.UnBrushDoc(this.props.node);
}
private _reac: (undefined | IReactionDisposer) = undefined;
private _plotList: ([string, StrokeData] | undefined) = undefined;
- private _interpolationKeyframe: (Doc | undefined) = undefined;
- private _type: string = "";
-
+ private _interpolationKeyframe: (Doc | undefined) = undefined;
+ private _type: string = "";
+
@action
onContainerDown = (kf: Doc, type: string) => {
- let listenerCreated = false;
- this.props.checkCallBack(true);
- this._type = type;
+ let listenerCreated = false;
+ this.props.checkCallBack(true);
+ this._type = type;
this.props.collection.backgroundColor = "rgb(0,0,0)";
this._reac = reaction(() => {
return this.inks;
}, data => {
if (!listenerCreated) {
this._plotList = Array.from(data!)[data!.size - 1]!;
- this._interpolationKeyframe = kf;
- listenerCreated = true;
+ this._interpolationKeyframe = kf;
+ listenerCreated = true;
const reac = reaction(() => {
- return this.props.check;
- }, () => {
- if(this.props.check === "yes") this.onReactionListen();
- reac();
- this.props.checkCallBack(false);
- });
+ return this.props.check;
+ }, () => {
+ if (this.props.check === "yes") this.onReactionListen();
+ reac();
+ this.props.checkCallBack(false);
+ });
}
});
}
@@ -548,26 +567,26 @@ export class Keyframe extends React.Component<IProps> {
}
} else {
i++;
- }
+ }
}
- let index = this.keyframes.indexOf(this._interpolationKeyframe!);
- if (this._type === "interpolate"){
+ let index = this.keyframes.indexOf(this._interpolationKeyframe!);
+ if (this._type === "interpolate") {
(Cast(this.regiondata.functions![index], Doc) as Doc).interpolationX = xPlots;
(Cast(this.regiondata.functions![index], Doc) as Doc).interpolationY = yPlots;
} else if (this._type === "path") {
(Cast(this.regiondata.functions![index], Doc) as Doc).pathX = xPlots;
(Cast(this.regiondata.functions![index], Doc) as Doc).pathY = yPlots;
}
- this._reac = undefined;
- this._interpolationKeyframe = undefined;
- this._plotList = undefined;
+ this._reac = undefined;
+ this._interpolationKeyframe = undefined;
+ this._plotList = undefined;
}
}
@action
- drawKeyframes = () => {
- let keyframeDivs:JSX.Element[] = [];
- DocListCast(this.regiondata.keyframes).forEach( kf => {
+ drawKeyframes = () => {
+ let keyframeDivs: JSX.Element[] = [];
+ DocListCast(this.regiondata.keyframes).forEach(kf => {
if (kf.type as KeyframeFunc.KeyframeType === KeyframeFunc.KeyframeType.default) {
keyframeDivs.push(
<div className="keyframe" style={{ left: `${KeyframeFunc.convertPixelTime(NumCast(kf.time), "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement) - this.pixelPosition}px` }}>
@@ -575,8 +594,8 @@ export class Keyframe extends React.Component<IProps> {
<div className="keyframeCircle" 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>
+ this.makeKeyframeMenu(kf, e.nativeEvent);
+ }} onDoubleClick={(e) => { e.preventDefault(); e.stopPropagation(); }}></div>
</div>
);
}
@@ -588,47 +607,48 @@ export class Keyframe extends React.Component<IProps> {
);
}
});
- return keyframeDivs;
+ return keyframeDivs;
}
- @action
- drawKeyframeDividers = () => {
- let keyframeDividers:JSX.Element[] = [];
+ @action
+ drawKeyframeDividers = () => {
+ let keyframeDividers: JSX.Element[] = [];
DocListCast(this.regiondata.keyframes).forEach(kf => {
- let index = this.keyframes.indexOf(kf);
- if(index !== this.keyframes.length - 1 ) {
- let left = this.keyframes[this.keyframes.indexOf(kf) + 1];
- let bodyRef = React.createRef<HTMLDivElement>();
- let kfPos = KeyframeFunc.convertPixelTime(NumCast(kf.time), "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement);
- let leftPos = KeyframeFunc.convertPixelTime(NumCast(left!.time), "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement);
- keyframeDividers.push (
- <div ref={bodyRef}className="body-container" style={{left: `${kfPos - this.pixelPosition}px`, width:`${leftPos - kfPos}px`}}
- onPointerOver={(e) => { e.preventDefault(); e.stopPropagation(); this.onContainerOver(e, bodyRef); }}
- onPointerOut={(e) => { e.preventDefault(); e.stopPropagation(); this.onContainerOut(e, bodyRef); }}
- onContextMenu={(e) => {
- e.preventDefault();
- e.stopPropagation();
- if (index !== 0 || index !== this.keyframes.length - 2){
- this._mouseToggled = true;
- }
- this.makeRegionMenu(kf, e.nativeEvent);
- }}>
+ let index = this.keyframes.indexOf(kf);
+ if (index !== this.keyframes.length - 1) {
+ let left = this.keyframes[this.keyframes.indexOf(kf) + 1];
+ let bodyRef = React.createRef<HTMLDivElement>();
+ let kfPos = KeyframeFunc.convertPixelTime(NumCast(kf.time), "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement);
+ let leftPos = KeyframeFunc.convertPixelTime(NumCast(left!.time), "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement);
+ keyframeDividers.push(
+ <div ref={bodyRef} className="body-container" style={{ left: `${kfPos - this.pixelPosition}px`, width: `${leftPos - kfPos}px` }}
+ onPointerOver={(e) => { e.preventDefault(); e.stopPropagation(); this.onContainerOver(e, bodyRef); }}
+ onPointerOut={(e) => { e.preventDefault(); e.stopPropagation(); this.onContainerOut(e, bodyRef); }}
+ onContextMenu={(e) => {
+ e.preventDefault();
+ e.stopPropagation();
+ if (index !== 0 || index !== this.keyframes.length - 2) {
+ this._mouseToggled = true;
+ }
+ this.makeRegionMenu(kf, e.nativeEvent);
+ }}>
</div>
- );
- }
- });
- return keyframeDividers;
+ );
+ }
+ });
+ return keyframeDividers;
}
render() {
return (
<div>
- <div className="bar" ref={this._bar} style={{
- transform: `translate(${this.pixelPosition}px)`,
- width: `${this.pixelDuration}px`,
- background: `linear-gradient(90deg, rgba(77, 153, 0, 0) 0%, rgba(77, 153, 0, 1) ${this.pixelFadeIn / this.pixelDuration * 100}%, rgba(77, 153, 0, 1) ${(this.pixelDuration - this.pixelFadeOut) / this.pixelDuration * 100}%, rgba(77, 153, 0, 0) 100% )` }}
+ <div className="bar" ref={this._bar} style={{
+ transform: `translate(${this.pixelPosition}px)`,
+ width: `${this.pixelDuration}px`,
+ background: `linear-gradient(90deg, rgba(77, 153, 0, 0) 0%, rgba(77, 153, 0, 1) ${this.pixelFadeIn / this.pixelDuration * 100}%, rgba(77, 153, 0, 1) ${(this.pixelDuration - this.pixelFadeOut) / this.pixelDuration * 100}%, rgba(77, 153, 0, 0) 100% )`
+ }}
onPointerDown={this.onBarPointerDown
- }>
+ }>
<div className="leftResize" onPointerDown={this.onResizeLeft} ></div>
<div className="rightResize" onPointerDown={this.onResizeRight}></div>
{this.drawKeyframes()}
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index a92b1858d..92e3e3f6f 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -76,7 +76,8 @@ const _setterImpl = action(function (target: any, prop: string | symbol | number
} else {
DocServer.registerDocWithCachedUpdate(receiver, prop as string, curValue);
}
- UndoManager.AddEvent({
+ UndoManager.
+ AddEvent({
redo: () => receiver[prop] = value,
undo: () => receiver[prop] = curValue
});