From b25276d9442f5ae9196a72b4af05849b9e69ef2f Mon Sep 17 00:00:00 2001 From: Andrew Kim Date: Sat, 11 Jan 2020 15:42:58 +0900 Subject: phantom region fix, scrubber double click, fade kf --- src/client/views/animationtimeline/Keyframe.tsx | 104 +++++++---------------- src/client/views/animationtimeline/Timeline.scss | 2 + src/client/views/animationtimeline/Timeline.tsx | 4 +- src/client/views/animationtimeline/Track.tsx | 26 +++--- 4 files changed, 51 insertions(+), 85 deletions(-) (limited to 'src') diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx index c3c1f5f8c..62528483b 100644 --- a/src/client/views/animationtimeline/Keyframe.tsx +++ b/src/client/views/animationtimeline/Keyframe.tsx @@ -22,6 +22,7 @@ import { undoBatch, UndoManager } from "../../util/UndoManager"; */ export namespace KeyframeFunc { export enum KeyframeType { + end = "end", fade = "fade", default = "default", } @@ -194,8 +195,8 @@ export class Keyframe extends React.Component { if (!this.regiondata.keyframes) this.regiondata.keyframes = new List(); let fadeIn = await this.makeKeyData(this.regiondata.position + this.regiondata.fadeIn, KeyframeFunc.KeyframeType.fade)!; let fadeOut = await this.makeKeyData(this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut, KeyframeFunc.KeyframeType.fade)!; - let start = await this.makeKeyData(this.regiondata.position, KeyframeFunc.KeyframeType.fade)!; - let finish = await this.makeKeyData(this.regiondata.position + this.regiondata.duration, KeyframeFunc.KeyframeType.fade)!; + let start = await this.makeKeyData(this.regiondata.position, KeyframeFunc.KeyframeType.end)!; + let finish = await this.makeKeyData(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; @@ -206,7 +207,6 @@ export class Keyframe extends React.Component { @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 => { @@ -218,19 +218,11 @@ export class Keyframe extends React.Component { TK.key = Doc.MakeCopy(this.props.node, true); TK.type = type; this.regiondata.keyframes!.push(TK); - - // myObservable++; - // UndoManager.AddEvent({ - // undo: action(() => myObservable--), - // redo: action(() => myObservable++) - // }); - let interpolationFunctions = new Doc(); interpolationFunctions.interpolationX = new List([0, 1]); interpolationFunctions.interpolationY = new List([0, 100]); interpolationFunctions.pathX = new List(); interpolationFunctions.pathY = new List(); - this.regiondata.functions!.push(interpolationFunctions); let found: boolean = false; this.regiondata.keyframes!.forEach(compkf => { @@ -244,7 +236,6 @@ export class Keyframe extends React.Component { return; } }); - batch.end(); return TK; } @@ -384,15 +375,6 @@ export class Keyframe extends React.Component { this.props.changeCurrentBarX(KeyframeFunc.convertPixelTime(NumCast(kf.time!), "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement)); } - - @action - onKeyframeOver = (e: React.PointerEvent) => { - e.preventDefault(); - e.stopPropagation(); - this.props.node.backgroundColor = "#000000"; - } - - /** * custom keyframe context menu items (when clicking on the keyframe circle) */ @@ -412,7 +394,6 @@ export class Keyframe extends React.Component { }), 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))) { @@ -422,7 +403,6 @@ export class Keyframe extends React.Component { this.keyframes[kfIndex].time = parseInt(val, 10); this.keyframes[1].time = this.regiondata.position + this.regiondata.fadeIn; } - } }); }); TimelineMenu.Instance.addMenu("Keyframe"); @@ -448,7 +428,6 @@ export class Keyframe extends React.Component { }), 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; @@ -457,59 +436,52 @@ export class Keyframe extends React.Component { 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(() => { - 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; - } + 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)) { - 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; - } + 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.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; - } + 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; } + }); + 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; } }); }), @@ -517,15 +489,6 @@ export class Keyframe extends React.Component { TimelineMenu.Instance.openMenu(e.clientX, e.clientY); } - - /** - * checking if input is correct (might have to use external module) - */ - @action - checkInput = (val: any) => { - return typeof (val === "number"); - } - @action updateKeyframes = (incr: number, filter: number[] = []) => { this.keyframes.forEach(kf => { @@ -652,7 +615,7 @@ export class Keyframe extends React.Component { drawKeyframes = () => { let keyframeDivs: JSX.Element[] = []; DocListCast(this.regiondata.keyframes).forEach(kf => { - if (kf.type as KeyframeFunc.KeyframeType === KeyframeFunc.KeyframeType.default) { + if (kf.type as KeyframeFunc.KeyframeType !== KeyframeFunc.KeyframeType.end) { keyframeDivs.push(
@@ -663,8 +626,7 @@ export class Keyframe extends React.Component { }} onDoubleClick={(e) => { e.preventDefault(); e.stopPropagation(); }}>
); - } - else { + } else { keyframeDivs.push(
diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index 493b084a8..76c8475d1 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -109,6 +109,7 @@ position: absolute; z-index: 1001; background-color: black; + pointer-events: none; .scrubberhead { top: -30px; @@ -119,6 +120,7 @@ border: 5px solid black; left: -15px; position: absolute; + pointer-events: all; } } diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 9cf600b5f..df25f709a 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -504,8 +504,8 @@ export class Timeline extends React.Component {
{this.drawTicks()} -
-
+
+
{DocListCast(this.children).map(doc => )} diff --git a/src/client/views/animationtimeline/Track.tsx b/src/client/views/animationtimeline/Track.tsx index d9b8026c5..2ea3d168f 100644 --- a/src/client/views/animationtimeline/Track.tsx +++ b/src/client/views/animationtimeline/Track.tsx @@ -96,6 +96,7 @@ export class Track extends React.Component { /** * keyframe save logic. Needs to be changed so it's more efficient + * */ @action saveKeyframe = async (ref: Doc, regiondata: Doc) => { @@ -354,19 +355,20 @@ export class Track extends React.Component { /** * creates a region (KEYFRAME.TSX stuff). */ - createRegion = (position: number) => { - let regiondata = KeyframeFunc.defaultKeyframe(); - regiondata.position = position; - let rightRegion = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.right, regiondata, this.regions); - - 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; + 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); + + if (rightRegion && rightRegion.position - regiondata.position <= 4000) { //edge case when there is less than default 4000 duration space between this and right region + 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; + } } - } -- cgit v1.2.3-70-g09d2