aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/animationtimeline/Keyframe.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/animationtimeline/Keyframe.tsx')
-rw-r--r--src/client/views/animationtimeline/Keyframe.tsx426
1 files changed, 240 insertions, 186 deletions
diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx
index 92d3e2bed..21a5af83f 100644
--- a/src/client/views/animationtimeline/Keyframe.tsx
+++ b/src/client/views/animationtimeline/Keyframe.tsx
@@ -1,38 +1,37 @@
-import { action, computed, observable, runInAction } from "mobx";
-import { observer } from "mobx-react";
-import * as React from "react";
-import { Doc, DocListCast, Opt } from "../../../fields/Doc";
-import { List } from "../../../fields/List";
-import { createSchema, defaultSpec, listSpec, makeInterface } from "../../../fields/Schema";
-import { Cast, NumCast } from "../../../fields/Types";
-import { Docs } from "../../documents/Documents";
-import { Transform } from "../../util/Transform";
-import { CollectionDockingView } from "../collections/CollectionDockingView";
-import "../global/globalCssVariables.scss";
-import "./Keyframe.scss";
-import "./Timeline.scss";
-import { TimelineMenu } from "./TimelineMenu";
-
+import { action, computed, observable, runInAction } from 'mobx';
+import { observer } from 'mobx-react';
+import * as React from 'react';
+import { Doc, DocListCast, Opt } from '../../../fields/Doc';
+import { List } from '../../../fields/List';
+import { createSchema, defaultSpec, listSpec, makeInterface } from '../../../fields/Schema';
+import { Cast, NumCast } from '../../../fields/Types';
+import { Docs } from '../../documents/Documents';
+import { Transform } from '../../util/Transform';
+import { CollectionDockingView } from '../collections/CollectionDockingView';
+import '../global/globalCssVariables.scss';
+import { OpenWhereMod } from '../nodes/DocumentView';
+import './Keyframe.scss';
+import './Timeline.scss';
+import { TimelineMenu } from './TimelineMenu';
/**
- * Useful static functions that you can use. Mostly for logic, but you can also add UI logic here also
+ * Useful static functions that you can use. Mostly for logic, but you can also add UI logic here also
*/
export namespace KeyframeFunc {
-
export enum KeyframeType {
- end = "end",
- fade = "fade",
- default = "default",
+ end = 'end',
+ fade = 'fade',
+ default = 'default',
}
export enum Direction {
- left = "left",
- right = "right"
+ left = 'left',
+ right = 'right',
}
- export const findAdjacentRegion = (dir: KeyframeFunc.Direction, currentRegion: Doc, regions: Doc[]): (RegionData | undefined) => {
- let leftMost: (RegionData | undefined) = undefined;
- let rightMost: (RegionData | undefined) = undefined;
+ export const findAdjacentRegion = (dir: KeyframeFunc.Direction, currentRegion: Doc, regions: Doc[]): RegionData | undefined => {
+ let leftMost: RegionData | undefined = undefined;
+ let rightMost: RegionData | undefined = undefined;
regions.forEach(region => {
const neighbor = RegionData(region);
if (currentRegion.position! > neighbor.position) {
@@ -52,11 +51,12 @@ export namespace KeyframeFunc {
}
};
- export const calcMinLeft = (region: Doc, currentBarX: number, ref?: Doc) => { //returns the time of the closet keyframe to the left
+ export const calcMinLeft = (region: Doc, currentBarX: number, ref?: Doc) => {
+ //returns the time of the closet keyframe to the left
let leftKf: Opt<Doc>;
let time: number = 0;
const keyframes = DocListCast(region.keyframes!);
- keyframes.map((kf) => {
+ keyframes.map(kf => {
let compTime = currentBarX;
if (ref) compTime = NumCast(ref.time);
if (NumCast(kf.time) < compTime && NumCast(kf.time) >= time) {
@@ -67,11 +67,11 @@ export namespace KeyframeFunc {
return leftKf;
};
-
- export const calcMinRight = (region: Doc, currentBarX: number, ref?: Doc) => { //returns the time of the closest keyframe to the right
+ export const calcMinRight = (region: Doc, currentBarX: number, ref?: Doc) => {
+ //returns the time of the closest keyframe to the right
let rightKf: Opt<Doc>;
let time: number = Infinity;
- DocListCast(region.keyframes!).forEach((kf) => {
+ DocListCast(region.keyframes!).forEach(kf => {
let compTime = currentBarX;
if (ref) compTime = NumCast(ref.time);
if (NumCast(kf.time) > compTime && NumCast(kf.time) <= NumCast(time)) {
@@ -93,27 +93,31 @@ export namespace KeyframeFunc {
return regiondata;
};
-
- export const convertPixelTime = (pos: number, unit: "mili" | "sec" | "min" | "hr", dir: "pixel" | "time", tickSpacing: number, tickIncrement: number) => {
- const 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) => {
+ const time = dir === 'pixel' ? (pos * tickSpacing) / tickIncrement : (pos / tickSpacing) * tickIncrement;
switch (unit) {
- case "mili": return time;
- case "sec": return dir === "pixel" ? time / 1000 : time * 1000;
- case "min": return dir === "pixel" ? time / 60000 : time * 60000;
- case "hr": return dir === "pixel" ? time / 3600000 : time * 3600000;
- default: return time;
+ case 'mili':
+ return time;
+ case 'sec':
+ return dir === 'pixel' ? time / 1000 : time * 1000;
+ case 'min':
+ return dir === 'pixel' ? time / 60000 : time * 60000;
+ case 'hr':
+ return dir === 'pixel' ? time / 3600000 : time * 3600000;
+ default:
+ return time;
}
};
}
export const RegionDataSchema = createSchema({
- position: defaultSpec("number", 0),
- duration: defaultSpec("number", 0),
+ position: defaultSpec('number', 0),
+ duration: defaultSpec('number', 0),
keyframes: listSpec(Doc),
- fadeIn: defaultSpec("number", 0),
- fadeOut: defaultSpec("number", 0),
+ fadeIn: defaultSpec('number', 0),
+ fadeOut: defaultSpec('number', 0),
functions: listSpec(Doc),
- hasData: defaultSpec("boolean", false)
+ hasData: defaultSpec('boolean', false),
});
export type RegionData = makeInterface<[typeof RegionDataSchema]>;
export const RegionData = makeInterface(RegionDataSchema);
@@ -130,50 +134,63 @@ interface IProps {
makeKeyData: (region: RegionData, pos: number, kftype: KeyframeFunc.KeyframeType) => Doc;
}
-
/**
- *
+ *
* This class handles the green region stuff
* Key facts:
- *
+ *
* Structure looks like this
- *
+ *
* region as a whole
* <------------------------------REGION------------------------------->
- *
- * region broken down
- *
+ *
+ * region broken down
+ *
* <|---------|############ MAIN CONTENT #################|-----------|> .....followed by void.........
* (start) (Fade 2)
* (fade 1) (finish)
- *
- *
- * As you can see, this is different from After Effect and Premiere Pro, but this is how TAG worked.
- * If you want to checkout TAG, it's in the lockers, and the password is the usual lab door password. It's the blue laptop.
- * If you want to know the exact location of the computer, message me.
- *
- * @author Andrew Kim
+ *
+ *
+ * As you can see, this is different from After Effect and Premiere Pro, but this is how TAG worked.
+ * If you want to checkout TAG, it's in the lockers, and the password is the usual lab door password. It's the blue laptop.
+ * If you want to know the exact location of the computer, message me.
+ *
+ * @author Andrew Kim
*/
@observer
export class Keyframe extends React.Component<IProps> {
-
@observable private _bar = React.createRef<HTMLDivElement>();
@observable private _mouseToggled = false;
@observable private _doubleClickEnabled = false;
- @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); }
+ @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...
+ 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);
const fadeIn = this.props.makeKeyData(this.regiondata, this.regiondata.position + this.regiondata.fadeIn, KeyframeFunc.KeyframeType.fade);
@@ -202,12 +219,12 @@ export class Keyframe extends React.Component<IProps> {
this._doubleClickEnabled = false;
}, 200);
this._doubleClickEnabled = true;
- document.addEventListener("pointermove", this.onBarPointerMove);
- document.addEventListener("pointerup", (e: PointerEvent) => {
- document.removeEventListener("pointermove", this.onBarPointerMove);
+ document.addEventListener('pointermove', this.onBarPointerMove);
+ document.addEventListener('pointerup', (e: PointerEvent) => {
+ document.removeEventListener('pointermove', this.onBarPointerMove);
});
}
- }
+ };
@action
onBarPointerMove = (e: PointerEvent) => {
@@ -219,46 +236,46 @@ export class Keyframe extends React.Component<IProps> {
const left = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.left, this.regiondata, this.regions)!;
const right = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.right, this.regiondata, this.regions)!;
const prevX = this.regiondata.position;
- const futureX = this.regiondata.position + KeyframeFunc.convertPixelTime(e.movementX, "mili", "time", this.props.tickSpacing, this.props.tickIncrement);
+ const futureX = this.regiondata.position + KeyframeFunc.convertPixelTime(e.movementX, 'mili', 'time', this.props.tickSpacing, this.props.tickIncrement);
if (futureX <= 0) {
this.regiondata.position = 0;
- } else if ((left && left.position + left.duration >= futureX)) {
+ } else if (left && left.position + left.duration >= futureX) {
this.regiondata.position = left.position + left.duration;
- } else if ((right && right.position <= futureX + this.regiondata.duration)) {
+ } else if (right && right.position <= futureX + this.regiondata.duration) {
this.regiondata.position = right.position - this.regiondata.duration;
} else {
this.regiondata.position = futureX;
}
const movement = this.regiondata.position - prevX;
- this.keyframes.forEach(kf => kf.time = NumCast(kf.time) + movement);
- }
+ this.keyframes.forEach(kf => (kf.time = NumCast(kf.time) + movement));
+ };
@action
onResizeLeft = (e: React.PointerEvent) => {
e.preventDefault();
e.stopPropagation();
- document.addEventListener("pointermove", this.onDragResizeLeft);
- document.addEventListener("pointerup", () => {
- document.removeEventListener("pointermove", this.onDragResizeLeft);
+ document.addEventListener('pointermove', this.onDragResizeLeft);
+ document.addEventListener('pointerup', () => {
+ document.removeEventListener('pointermove', this.onDragResizeLeft);
});
- }
+ };
@action
onResizeRight = (e: React.PointerEvent) => {
e.preventDefault();
e.stopPropagation();
- document.addEventListener("pointermove", this.onDragResizeRight);
- document.addEventListener("pointerup", () => {
- document.removeEventListener("pointermove", this.onDragResizeRight);
+ document.addEventListener('pointermove', this.onDragResizeRight);
+ document.addEventListener('pointerup', () => {
+ document.removeEventListener('pointermove', this.onDragResizeRight);
});
- }
+ };
@action
onDragResizeLeft = (e: PointerEvent) => {
e.preventDefault();
e.stopPropagation();
const bar = this._bar.current!;
- const offset = KeyframeFunc.convertPixelTime(Math.round((e.clientX - bar.getBoundingClientRect().left) * this.props.transform.Scale), "mili", "time", this.props.tickSpacing, this.props.tickIncrement);
+ const offset = KeyframeFunc.convertPixelTime(Math.round((e.clientX - bar.getBoundingClientRect().left) * this.props.transform.Scale), 'mili', 'time', this.props.tickSpacing, this.props.tickIncrement);
const 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;
@@ -275,90 +292,99 @@ export class Keyframe extends React.Component<IProps> {
}
this.keyframes[0].time = this.regiondata.position;
this.keyframes[1].time = this.regiondata.position + this.regiondata.fadeIn;
- }
-
+ };
@action
onDragResizeRight = (e: PointerEvent) => {
e.preventDefault();
e.stopPropagation();
const bar = this._bar.current!;
- const offset = KeyframeFunc.convertPixelTime(Math.round((e.clientX - bar.getBoundingClientRect().right) * this.props.transform.Scale), "mili", "time", this.props.tickSpacing, this.props.tickIncrement);
+ const offset = KeyframeFunc.convertPixelTime(Math.round((e.clientX - bar.getBoundingClientRect().right) * this.props.transform.Scale), 'mili', 'time', this.props.tickSpacing, this.props.tickIncrement);
const rightRegion = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.right, this.regiondata, this.regions);
const 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
+ 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)) {
+ } 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;
- }
-
+ };
@action
createKeyframe = async (clientX: number) => {
this._mouseToggled = true;
const bar = this._bar.current!;
- const 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
+ const 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
const position = this.regiondata.position;
this.props.makeKeyData(this.regiondata, Math.round(position + offset), KeyframeFunc.KeyframeType.default);
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
-
+ 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
}
- }
-
+ };
@action
moveKeyframe = async (e: React.MouseEvent, kf: Doc) => {
e.preventDefault();
e.stopPropagation();
- this.props.changeCurrentBarX(KeyframeFunc.convertPixelTime(NumCast(kf.time!), "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement));
- }
+ this.props.changeCurrentBarX(KeyframeFunc.convertPixelTime(NumCast(kf.time!), 'mili', 'pixel', this.props.tickSpacing, this.props.tickIncrement));
+ };
/**
* custom keyframe context menu items (when clicking on the keyframe circle)
*/
@action
makeKeyframeMenu = (kf: Doc, e: MouseEvent) => {
- TimelineMenu.Instance.addItem("button", "Toggle Fade Only", () => {
+ TimelineMenu.Instance.addItem('button', 'Toggle Fade Only', () => {
kf.type = kf.type === KeyframeFunc.KeyframeType.fade ? KeyframeFunc.KeyframeType.default : KeyframeFunc.KeyframeType.fade;
}),
- TimelineMenu.Instance.addItem("button", "Show Data", action(() => {
- const kvp = Docs.Create.KVPDocument(kf, { _width: 300, _height: 300 });
- CollectionDockingView.AddSplit(kvp, "right");
- })),
- TimelineMenu.Instance.addItem("button", "Delete", action(() => {
- (this.regiondata.keyframes as List<Doc>).splice(this.keyframes.indexOf(kf), 1);
- this.forceUpdate();
- })),
- TimelineMenu.Instance.addItem("input", "Move", action((val) => {
- let cannotMove: boolean = false;
- const 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.addItem(
+ 'button',
+ 'Show Data',
+ action(() => {
+ const kvp = Docs.Create.KVPDocument(kf, { _width: 300, _height: 300 });
+ CollectionDockingView.AddSplit(kvp, OpenWhereMod.right);
+ })
+ ),
+ TimelineMenu.Instance.addItem(
+ 'button',
+ 'Delete',
+ action(() => {
+ (this.regiondata.keyframes as List<Doc>).splice(this.keyframes.indexOf(kf), 1);
+ this.forceUpdate();
+ })
+ ),
+ TimelineMenu.Instance.addItem(
+ 'input',
+ 'Move',
+ action(val => {
+ let cannotMove: boolean = false;
+ const 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);
- }
+ };
/**
- * context menu for region (anywhere on the green region).
+ * context menu for region (anywhere on the green region).
*/
@action
makeRegionMenu = (kf: Doc, e: MouseEvent) => {
- TimelineMenu.Instance.addItem("button", "Remove Region", () =>
- Cast(this.props.node.regions, listSpec(Doc))?.splice(this.regions.indexOf(this.props.RegionData), 1)),
- TimelineMenu.Instance.addItem("input", `fadeIn: ${this.regiondata.fadeIn}ms`, (val) => {
+ TimelineMenu.Instance.addItem('button', 'Remove Region', () => Cast(this.props.node.regions, listSpec(Doc))?.splice(this.regions.indexOf(this.props.RegionData), 1)),
+ TimelineMenu.Instance.addItem('input', `fadeIn: ${this.regiondata.fadeIn}ms`, val => {
runInAction(() => {
let cannotMove: boolean = false;
if (val < 0 || val > NumCast(this.keyframes[2].time) - this.regiondata.position) {
@@ -370,7 +396,7 @@ export class Keyframe extends React.Component<IProps> {
}
});
}),
- TimelineMenu.Instance.addItem("input", `fadeOut: ${this.regiondata.fadeOut}ms`, (val) => {
+ TimelineMenu.Instance.addItem('input', `fadeOut: ${this.regiondata.fadeOut}ms`, val => {
runInAction(() => {
let cannotMove: boolean = false;
if (val < 0 || val > this.regiondata.position + this.regiondata.duration - NumCast(this.keyframes[this.keyframes.length - 3].time)) {
@@ -382,34 +408,38 @@ export class Keyframe extends React.Component<IProps> {
}
});
}),
- TimelineMenu.Instance.addItem("input", `position: ${this.regiondata.position}ms`, (val) => {
+ TimelineMenu.Instance.addItem('input', `position: ${this.regiondata.position}ms`, val => {
runInAction(() => {
const prevPosition = this.regiondata.position;
let cannotMove: boolean = false;
- this.regions.map(region => ({ pos: NumCast(region.position), dur: NumCast(region.duration) })).forEach(({ pos, dur }) => {
- if (pos !== this.regiondata.position) {
- if ((val < 0) || (val > pos && val < pos + dur || (this.regiondata.duration + val > pos && this.regiondata.duration + val < pos + dur))) {
- cannotMove = true;
+ this.regions
+ .map(region => ({ pos: NumCast(region.position), dur: NumCast(region.duration) }))
+ .forEach(({ pos, dur }) => {
+ if (pos !== this.regiondata.position) {
+ if (val < 0 || (val > pos && val < pos + dur) || (this.regiondata.duration + val > pos && this.regiondata.duration + val < pos + dur)) {
+ cannotMove = true;
+ }
}
- }
- });
+ });
if (!cannotMove) {
this.regiondata.position = parseInt(val, 10);
this.updateKeyframes(this.regiondata.position - prevPosition);
}
});
}),
- TimelineMenu.Instance.addItem("input", `duration: ${this.regiondata.duration}ms`, (val) => {
+ TimelineMenu.Instance.addItem('input', `duration: ${this.regiondata.duration}ms`, val => {
runInAction(() => {
let cannotMove: boolean = false;
- this.regions.map(region => ({ pos: NumCast(region.position), dur: NumCast(region.duration) })).forEach(({ pos, dur }) => {
- if (pos !== this.regiondata.position) {
- val += this.regiondata.position;
- if ((val < 0) || (val > pos && val < pos + dur)) {
- cannotMove = true;
+ this.regions
+ .map(region => ({ pos: NumCast(region.position), dur: NumCast(region.duration) }))
+ .forEach(({ pos, dur }) => {
+ if (pos !== this.regiondata.position) {
+ val += this.regiondata.position;
+ if (val < 0 || (val > pos && val < pos + dur)) {
+ cannotMove = true;
+ }
}
- }
- });
+ });
if (!cannotMove) {
this.regiondata.duration = parseInt(val, 10);
this.keyframes[this.keyframes.length - 1].time = this.regiondata.position + this.regiondata.duration;
@@ -417,9 +447,9 @@ export class Keyframe extends React.Component<IProps> {
}
});
}),
- TimelineMenu.Instance.addMenu("Region");
+ TimelineMenu.Instance.addMenu('Region');
TimelineMenu.Instance.openMenu(e.clientX, e.clientY);
- }
+ };
@action
updateKeyframes = (incr: number, filter: number[] = []) => {
@@ -428,7 +458,7 @@ export class Keyframe extends React.Component<IProps> {
kf.time = NumCast(kf.time) + incr;
}
});
- }
+ };
/**
* hovering effect when hovered (hidden div darkens)
@@ -438,9 +468,9 @@ export class Keyframe extends React.Component<IProps> {
e.preventDefault();
e.stopPropagation();
const div = ref.current!;
- div.style.opacity = "1";
+ div.style.opacity = '1';
Doc.BrushDoc(this.props.node);
- }
+ };
/**
* hovering effect when hovered out (hidden div becomes invisible)
@@ -450,14 +480,12 @@ export class Keyframe extends React.Component<IProps> {
e.preventDefault();
e.stopPropagation();
const div = ref.current!;
- div.style.opacity = "0";
+ div.style.opacity = '0';
Doc.UnBrushDoc(this.props.node);
- }
-
+ };
///////////////////////UI STUFF /////////////////////////
-
/**
* 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)
@@ -465,32 +493,43 @@ export class Keyframe extends React.Component<IProps> {
drawKeyframes = () => {
const keyframeDivs: JSX.Element[] = [];
return DocListCast(this.regiondata.keyframes).map(kf => {
- if (kf.type as KeyframeFunc.KeyframeType !== KeyframeFunc.KeyframeType.end) {
- 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(); }}>
+ if ((kf.type as KeyframeFunc.KeyframeType) !== KeyframeFunc.KeyframeType.end) {
+ 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>
- <div className="keyframe-information" />
- </>;
+ <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 (
+ <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>
+ );
}
});
- }
+ };
/**
- * drawing the hidden divs that partition different intervals within a region.
+ * drawing the hidden divs that partition different intervals within a region.
*/
@action
drawKeyframeDividers = () => {
@@ -500,26 +539,36 @@ export class Keyframe extends React.Component<IProps> {
if (index !== this.keyframes.length - 1) {
const right = this.keyframes[index + 1];
const bodyRef = React.createRef<HTMLDivElement>();
- const kfPos = KeyframeFunc.convertPixelTime(NumCast(kf.time), "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement);
- const rightPos = KeyframeFunc.convertPixelTime(NumCast(right.time), "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement);
+ const kfPos = KeyframeFunc.convertPixelTime(NumCast(kf.time), 'mili', 'pixel', this.props.tickSpacing, this.props.tickIncrement);
+ const rightPos = KeyframeFunc.convertPixelTime(NumCast(right.time), 'mili', 'pixel', this.props.tickSpacing, this.props.tickIncrement);
keyframeDividers.push(
- <div ref={bodyRef} className="body-container" style={{ left: `${kfPos - this.pixelPosition}px`, width: `${rightPos - kfPos}px` }}
- onPointerOver={(e) => { e.preventDefault(); e.stopPropagation(); this.onContainerOver(e, bodyRef); }}
- onPointerOut={(e) => { e.preventDefault(); e.stopPropagation(); this.onContainerOut(e, bodyRef); }}
- onContextMenu={(e) => {
+ <div
+ ref={bodyRef}
+ className="body-container"
+ style={{ left: `${kfPos - this.pixelPosition}px`, width: `${rightPos - 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>
+ }}></div>
);
}
});
return keyframeDividers;
- }
+ };
/**
* rendering that green region
@@ -527,13 +576,18 @@ export class Keyframe extends React.Component<IProps> {
//154, 206, 223
render() {
return (
- <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% )`
- }}
+ <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="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> */}
@@ -542,4 +596,4 @@ export class Keyframe extends React.Component<IProps> {
</div>
);
}
-} \ No newline at end of file
+}