From 2f09822358dba784ec26d5707423b4025096ee45 Mon Sep 17 00:00:00 2001 From: andrewdkim Date: Sun, 22 Sep 2019 17:24:05 -0400 Subject: fixed zooming and context menu - stable --- src/client/views/animationtimeline/Keyframe.tsx | 121 ++++++++++++++++----- .../views/animationtimeline/TimelineMenu.tsx | 22 ++-- src/client/views/animationtimeline/Track.tsx | 1 + 3 files changed, 109 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx index 20fc8470d..7197f4b49 100644 --- a/src/client/views/animationtimeline/Keyframe.tsx +++ b/src/client/views/animationtimeline/Keyframe.tsx @@ -416,48 +416,115 @@ export class Keyframe extends React.Component { }), TimelineMenu.Instance.addItem("button", "Delete", () => { runInAction(() => { - console.log(this.keyframes.indexOf(kf)); - this.keyframes.splice(this.keyframes.indexOf(kf), 1); + (this.regiondata.keyframes as List).splice(this.keyframes.indexOf(kf), 1); }); }), - TimelineMenu.Instance.addItem("input", "Move", (val) => {kf.time = parseInt(val, 10);}); + 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); } @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", "Add Ease", () => { + // this.onContainerDown(kf, "interpolate"); + }), + TimelineMenu.Instance.addItem("button", "Add Path", () => { + // this.onContainerDown(kf, "path"); + }), TimelineMenu.Instance.addItem("button", "Remove Region", ()=>{this.regions.splice(this.regions.indexOf(this.regiondata), 1);}), - TimelineMenu.Instance.addItem("input", `fadeIn: ${this.regiondata.fadeIn}ms`, (val) => {runInAction(() => { - this.regiondata.fadeIn = parseInt(val, 10); + 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", `fadeOut: ${this.regiondata.fadeOut}ms`, (val) => {runInAction(() => { - this.regiondata.fadeOut = parseInt(val, 10); + 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", `position: ${this.regiondata.position}ms`, (val) => {runInAction(() => { - if (this.checkInput(val)){ + 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 (region !== this.regiondata){ - if (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))){ - return undefined; + 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; } } }); - this.regiondata.position = val; + if (!cannotMove) { + this.regiondata.position = parseInt(val, 10); + this.updateKeyframes(this.regiondata.position - prevPosition ); + } } - this.regiondata.position = parseInt(val, 10); });}), - TimelineMenu.Instance.addItem("input", `duration: ${this.regiondata.duration}ms`, (val) => {runInAction(() => { - this.regiondata.duration = parseInt(val, 10); + 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); } checkInput = (val: any) => { - return typeof(val === "number") + return typeof(val === "number"); + } + + @action + updateKeyframes = (incr:number, filter:number[] = []) => { + this.keyframes.forEach(kf => { + if (!filter.includes(this.keyframes.indexOf(kf))){ + kf.time = NumCast(kf.time) + incr; + } + }); } onContainerOver = (e: React.PointerEvent, ref: React.RefObject) => { @@ -495,8 +562,6 @@ export class Keyframe extends React.Component { listenerCreated = true; } }); - - } @action @@ -558,6 +623,7 @@ export class Keyframe extends React.Component { } } render() { + console.log("RERENDERING"); return (
{
); } - return ( -
-
-
- ); + else { + return ( +
+
+
+ ); + } + })} {this.keyframes.map( kf => { if(this.keyframes.indexOf(kf ) !== this.keyframes.length - 1) { diff --git a/src/client/views/animationtimeline/TimelineMenu.tsx b/src/client/views/animationtimeline/TimelineMenu.tsx index 1fd97c6c1..f3b985297 100644 --- a/src/client/views/animationtimeline/TimelineMenu.tsx +++ b/src/client/views/animationtimeline/TimelineMenu.tsx @@ -36,21 +36,25 @@ export class TimelineMenu extends React.Component { } @action - addItem = (type: "input" | "button", title: string, event: (e:any) => void) => { + addItem = (type: "input" | "button", title: string, event: (e:any, ...args:any[]) => void) => { if (type === "input"){ let inputRef = React.createRef(); - this._currentMenu.push(
{ - let text = e.target.value; - document.addEventListener("keypress", (e:KeyboardEvent) => { - if (e.keyCode === 13) { - event(text); - this.closeMenu(); - } - }); + let text = ""; + this._currentMenu.push(
{ + e.stopPropagation(); + text = e.target.value; + }} onKeyDown={(e) => { + if (e.keyCode === 13) { + event(text); + this.closeMenu(); + e.stopPropagation(); + } }}/>
); } else if (type === "button") { let buttonRef = React.createRef(); this._currentMenu.push(

{ + e.preventDefault(); + e.stopPropagation(); event(e); this.closeMenu(); }}>{title}

); diff --git a/src/client/views/animationtimeline/Track.tsx b/src/client/views/animationtimeline/Track.tsx index 89533c4df..c68d9bb3a 100644 --- a/src/client/views/animationtimeline/Track.tsx +++ b/src/client/views/animationtimeline/Track.tsx @@ -69,6 +69,7 @@ export class Track extends React.Component { let keyframes: List = (Cast(regiondata.keyframes, listSpec(Doc)) as List); let kfIndex: number = keyframes.indexOf(ref); let kf = keyframes[kfIndex] as Doc; + if (!kf) return; 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 -- cgit v1.2.3-70-g09d2