aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/nodes/Keyframe.tsx147
-rw-r--r--src/client/views/nodes/Timeline.scss9
-rw-r--r--src/client/views/nodes/Timeline.tsx140
-rw-r--r--src/client/views/nodes/Track.tsx91
4 files changed, 226 insertions, 161 deletions
diff --git a/src/client/views/nodes/Keyframe.tsx b/src/client/views/nodes/Keyframe.tsx
index 10ae2f427..4bccc6040 100644
--- a/src/client/views/nodes/Keyframe.tsx
+++ b/src/client/views/nodes/Keyframe.tsx
@@ -10,43 +10,68 @@ import { List } from "../../../new_fields/List";
import { createSchema, defaultSpec, makeInterface, listSpec } from "../../../new_fields/Schema";
import { any } from "bluebird";
import { FlyoutProps } from "./Timeline";
-
-enum Direction {
- left = "left",
- right = "right"
+import { number } from "prop-types";
+
+export namespace KeyframeFunc{
+ export enum Direction{
+ left = "left",
+ right = "right"
+ }
+ export const findAdjacentRegion = (dir: KeyframeFunc.Direction, currentRegion:Doc, regions:List<Doc>): (RegionData | undefined) => {
+ let leftMost: (RegionData | undefined) = undefined;
+ let rightMost: (RegionData | undefined) = undefined;
+ regions.forEach(region => {
+ let neighbor = RegionData(region as Doc);
+ if (currentRegion.position! > neighbor.position) {
+ if (!leftMost || neighbor.position > leftMost.position) {
+ leftMost = neighbor;
+ }
+ } else if (currentRegion.position! < neighbor.position) {
+ if (!rightMost || neighbor.position < rightMost.position) {
+ rightMost = neighbor;
+ }
+ }
+ });
+ if (dir === Direction.left) {
+ return leftMost;
+ } else if (dir === Direction.right) {
+ return rightMost;
+ }
+ };
}
-interface IProps {
- node: Doc;
- RegionData: Doc;
- setFlyout:(props:FlyoutProps) => any;
-}
const RegionDataSchema = createSchema({
position: defaultSpec("number", 0),
duration: defaultSpec("number", 0),
- keyframes: listSpec(Doc)
+ keyframes: listSpec(Doc),
+ fadeIn: defaultSpec("number", 0),
+ fadeOut: defaultSpec("number", 0)
});
type RegionData = makeInterface<[typeof RegionDataSchema]>;
-export const RegionData = makeInterface(RegionDataSchema);
+const RegionData = makeInterface(RegionDataSchema);
+interface IProps {
+ node: Doc;
+ RegionData: Doc;
+ changeCurrentBarX: (x: number) => void;
+ setFlyout:(props:FlyoutProps) => any;
+}
@observer
export class Keyframe extends React.Component<IProps> {
@observable private _bar = React.createRef<HTMLDivElement>();
- @observable private fadein: number = 0;
- @observable private fadeout: number = 0;
@action
- componentDidMount() {
- // need edge case here when keyframe data already exists when loading.....................;
+ componentWillMount() {
}
componentWillUnmount() {
}
+
@computed
private get regiondata() {
let index = this.regions.indexOf(this.props.RegionData);
@@ -78,29 +103,21 @@ export class Keyframe extends React.Component<IProps> {
@action
onBarPointerDown = (e: React.PointerEvent) => {
- let mouse = e.nativeEvent;
-
e.preventDefault();
e.stopPropagation();
- if (mouse.which === 1){
- document.addEventListener("pointermove", this.onBarPointerMove);
- document.addEventListener("pointerup", (e: PointerEvent) => {
- document.removeEventListener("pointermove", this.onBarPointerMove);
- });
- }// else if(mouse.which === 3) {
- // e.preventDefault();
- // e.stopPropagation();
- // let bar = this._bar.current!;
- // this.props.setFlyout({x:e.clientX, y: e.clientY,display:"block", time: this.regiondata.position, duration:this.regiondata.duration});
- // }
+ document.addEventListener("pointermove", this.onBarPointerMove);
+ document.addEventListener("pointerup", (e: PointerEvent) => {
+ document.removeEventListener("pointermove", this.onBarPointerMove);
+ });
}
+
@action
onBarPointerMove = (e: PointerEvent) => {
e.preventDefault();
e.stopPropagation();
- let left = this.findAdjacentRegion(Direction.left);
- let right = this.findAdjacentRegion(Direction.right);
+ let left = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.left, this.regiondata, this.regions)!;
+ let right = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.right, this.regiondata, this.regions!);
let bar = this._bar.current!;
let barX = bar.getBoundingClientRect().left;
let offset = e.clientX - barX;
@@ -116,29 +133,7 @@ export class Keyframe extends React.Component<IProps> {
}
}
- @action
- findAdjacentRegion = (dir: Direction): (RegionData | undefined) => {
- let leftMost: (RegionData | undefined) = undefined;
- let rightMost: (RegionData | undefined) = undefined;
- this.regions.forEach(region => {
- let neighbor = RegionData(region as Doc);
- if (this.regiondata.position > neighbor.position) {
- if (!leftMost || neighbor.position > leftMost.position) {
- leftMost = neighbor;
- }
- } else if (this.regiondata.position < neighbor.position) {
- if (!rightMost || neighbor.position < rightMost.position) {
- rightMost = neighbor;
- }
- }
- });
- if (dir === Direction.left) {
- return leftMost;
- } else if (dir === Direction.right) {
- return rightMost;
- }
- }
-
+
@action
onResizeLeft = (e: React.PointerEvent) => {
e.preventDefault();
@@ -166,8 +161,13 @@ export class Keyframe extends React.Component<IProps> {
let bar = this._bar.current!;
let barX = bar.getBoundingClientRect().left;
let offset = e.clientX - barX;
- this.regiondata.duration -= offset;
- this.regiondata.position += offset;
+ if (this.regiondata.duration - offset < this.regiondata.fadeIn + this.regiondata.fadeOut){
+ this.regiondata.position -= (this.regiondata.fadeIn + this.regiondata.fadeOut - this.regiondata.duration);
+ this.regiondata.duration = this.regiondata.fadeIn + this.regiondata.fadeOut;
+ } else {
+ this.regiondata.duration -= offset;
+ this.regiondata.position += offset;
+ }
}
@@ -178,10 +178,14 @@ export class Keyframe extends React.Component<IProps> {
let bar = this._bar.current!;
let barX = bar.getBoundingClientRect().right;
let offset = e.clientX - barX;
- this.regiondata.duration += offset;
+ if (this.regiondata.duration + offset < this.regiondata.fadeIn + this.regiondata.fadeOut){
+ this.regiondata.duration = this.regiondata.fadeIn + this.regiondata.fadeOut;
+ } else {
+ this.regiondata.duration += offset;
+ }
}
- createDivider = (type?: Direction): JSX.Element => {
+ createDivider = (type?: KeyframeFunc.Direction): JSX.Element => {
if (type === "left") {
return <div className="divider" style={{ right: "0px" }}></div>;
} else if (type === "right") {
@@ -197,14 +201,14 @@ export class Keyframe extends React.Component<IProps> {
let bar = this._bar.current!;
let offset = e.clientX - bar.getBoundingClientRect().left;
let position = NumCast(this.regiondata.position);
- this.makeKeyData(position + offset);
+ this.makeKeyData(Math.round(position + offset));
}
@action
- moveKeyframe = (e: React.MouseEvent) => {
+ moveKeyframe = (e: React.MouseEvent, kf:Doc) => {
e.preventDefault();
e.stopPropagation();
-
+ this.props.changeCurrentBarX(NumCast(kf.time!));
}
@@ -215,26 +219,25 @@ export class Keyframe extends React.Component<IProps> {
onPointerDown={this.onBarPointerDown}
onDoubleClick={this.createKeyframe}
onContextMenu={action((e:React.MouseEvent)=>{
- let mouse = e.nativeEvent;
- if (mouse.which === 3){
- this.props.setFlyout({x:e.clientX, y: e.clientY, display:"block"});
- } else {
- this.props.setFlyout({display:"block"});
- }
+ let offsetLeft = this._bar.current!.getBoundingClientRect().left - this._bar.current!.parentElement!.getBoundingClientRect().left;
+ let offsetTop = this._bar.current!.getBoundingClientRect().top; //+ this._bar.current!.parentElement!.getBoundingClientRect().top;
+ console.log(offsetLeft);
+ console.log(offsetTop);
+ this.props.setFlyout({x:offsetLeft, y: offsetTop, display:"block", regiondata:this.regiondata, regions:this.regions});
})}>
<div className="leftResize" onPointerDown={this.onResizeLeft} ></div>
<div className="rightResize" onPointerDown={this.onResizeRight}></div>
- <div className="fadeLeft" style={{ width: `${20}px` }}>{this.createDivider(Direction.left)}</div>
- <div className="fadeRight" style={{ width: `${20}px` }}>{this.createDivider(Direction.right)}</div>
+ <div className="fadeLeft" style={{ width: `${this.regiondata.fadeIn}px` }}>{this.createDivider(KeyframeFunc.Direction.left)}</div>
+ <div className="fadeRight" style={{ width: `${this.regiondata.fadeOut}px` }}>{this.createDivider(KeyframeFunc.Direction.right)}</div>
{this.regiondata.keyframes!.map(kf => {
kf = kf as Doc;
- return <div className="keyframe" style={{ left: `${NumCast(kf.time) - this.regiondata.position}px` }}>
+ return <div className="keyframe" style={{ left: `${NumCast(kf.time) - this.regiondata.position}px` }}>
{this.createDivider()}
- <div className="keyframeCircle" onPointerDown={this.moveKeyframe}></div>
+ <div className="keyframeCircle" onPointerDown={(e) => {this.moveKeyframe(e, kf as Doc);}}></div>
</div>;
})}
- {this.createDivider(Direction.left)}
- {this.createDivider(Direction.right)}
+ {this.createDivider(KeyframeFunc.Direction.left)}
+ {this.createDivider(KeyframeFunc.Direction.right)}
</div>
</div>
);
diff --git a/src/client/views/nodes/Timeline.scss b/src/client/views/nodes/Timeline.scss
index a416cbb1c..0a510ba6e 100644
--- a/src/client/views/nodes/Timeline.scss
+++ b/src/client/views/nodes/Timeline.scss
@@ -8,7 +8,8 @@
}
.flyout-container{
background-color: transparent;
- position:absolute;
+ position:absolute;
+
z-index:9999;
height: 150px;
width: 150px;
@@ -36,8 +37,6 @@
left:0px;
color:white
}
-
-
}
.timeline-container{
@@ -46,8 +45,8 @@
position:absolute;
background-color: $light-color-secondary;
box-shadow: 0px 10px 20px;
- transition: transform 1000ms ease-in-out;
-
+ //transition: transform 1000ms ease-in-out;
+
.toolbox{
position:absolute;
width: 100%;
diff --git a/src/client/views/nodes/Timeline.tsx b/src/client/views/nodes/Timeline.tsx
index fd235fad3..1c51dbcad 100644
--- a/src/client/views/nodes/Timeline.tsx
+++ b/src/client/views/nodes/Timeline.tsx
@@ -1,12 +1,11 @@
import * as React from "react";
-import * as ReactDOM from "react-dom";
import "./Timeline.scss";
import { CollectionSubView } from "../collections/CollectionSubView";
import { Document, listSpec, createSchema, makeInterface, defaultSpec } from "../../../new_fields/Schema";
import { observer } from "mobx-react";
import { Track } from "./Track";
import { observable, reaction, action, IReactionDisposer, observe, IObservableArray, computed, toJS, Reaction, IObservableObject } from "mobx";
-import { Cast } from "../../../new_fields/Types";
+import { Cast, NumCast } from "../../../new_fields/Types";
import { SelectionManager } from "../../util/SelectionManager";
import { List } from "../../../new_fields/List";
import { Self } from "../../../new_fields/FieldSymbols";
@@ -16,29 +15,39 @@ import { faCircle, faPlayCircle, faBackward, faForward, faGripLines } from "@for
import { DocumentContentsView } from "./DocumentContentsView";
import { ContextMenuProps } from "../ContextMenuItem";
import { ContextMenu } from "../ContextMenu";
+import { string } from "prop-types";
export interface FlyoutProps {
x?: number;
y?: number;
display?: string;
- time?: number;
- duration?: number;
+ regiondata?:Doc;
+ regions?:List<Doc>;
}
@observer
export class Timeline extends CollectionSubView(Document) {
private readonly DEFAULT_CONTAINER_HEIGHT: number = 300;
+ private readonly DEFAULT_TICK_SPACING:number = 50;
private readonly MIN_CONTAINER_HEIGHT: number = 205;
private readonly MAX_CONTAINER_HEIGHT: number = 800;
-
- @observable private _tickSpacing = 50;
+
+ @observable private _isMinimized = false;
+ @observable private _tickSpacing = this.DEFAULT_TICK_SPACING;
@observable private _scrubberbox = React.createRef<HTMLDivElement>();
+ @observable private _scrubber = React.createRef<HTMLDivElement>();
@observable private _trackbox = React.createRef<HTMLDivElement>();
@observable private _titleContainer = React.createRef<HTMLDivElement>();
@observable private _timelineContainer = React.createRef<HTMLDivElement>();
+ @observable private _timeInput = React.createRef<HTMLInputElement>();
+ @observable private _durationInput = React.createRef<HTMLInputElement>();
+ @observable private _fadeInInput = React.createRef<HTMLInputElement>();
+ @observable private _fadeOutInput = React.createRef<HTMLInputElement>();
+
+
@observable private _currentBarX: number = 0;
@observable private _windSpeed: number = 1;
@observable private _isPlaying: boolean = false;
@@ -50,7 +59,7 @@ export class Timeline extends CollectionSubView(Document) {
@observable private _infoContainer = React.createRef<HTMLDivElement>();
@observable private _ticks: number[] = [];
- @observable private flyoutInfo: FlyoutProps = { x: 0, y: 0, display: "none" };
+ @observable private flyoutInfo: FlyoutProps = { x: 0, y: 0, display: "none", regiondata: new Doc(), regions: new List<Doc>()};
private block = false;
@@ -80,6 +89,10 @@ export class Timeline extends CollectionSubView(Document) {
document.addEventListener("pointerdown", this.closeFlyout);
}
+ @action
+ changeCurrentBarX = (x: number) => {
+ this._currentBarX = x;
+ }
@action
onFlyoutDown = (e: React.PointerEvent) => {
this.flyoutInfo.display = "block";
@@ -169,19 +182,7 @@ export class Timeline extends CollectionSubView(Document) {
this._currentBarX = offset;
}
- @action
- toTime = (time: number): string => {
- const inSeconds = time / 1000;
- let min: (string | number) = Math.floor(inSeconds / 60);
- let sec: (string | number) = inSeconds % 60;
-
- if (Math.floor(sec / 10) === 0) {
- sec = "0" + sec;
- }
- return `${min}:${sec}`;
-
- }
-
+
@action
onPanDown = (e: React.PointerEvent) => {
@@ -205,8 +206,6 @@ export class Timeline extends CollectionSubView(Document) {
titleContainer.scrollTop = titleContainer.scrollTop - e.movementY;
}
-
-
@action
onResizeDown = (e: React.PointerEvent) => {
e.preventDefault();
@@ -231,7 +230,24 @@ export class Timeline extends CollectionSubView(Document) {
}
}
- @observable private _isMinimized = false;
+ @action
+ onTimelineDown = (e:React.PointerEvent) => {
+ e.preventDefault();
+ e.stopPropagation();
+ document.addEventListener("pointermove", this.onTimelineMove);
+ document.addEventListener("pointerup", () => {document.removeEventListener("pointermove", this.onTimelineMove);});
+ }
+
+ @action
+ onTimelineMove = (e:PointerEvent) => {
+ e.preventDefault();
+ e.stopPropagation();
+ let timelineContainer = this._timelineContainer.current!;
+ timelineContainer.style.transform = `translate(${timelineContainer.getBoundingClientRect().left + 1}px, ${timelineContainer.getBoundingClientRect().top + 1}px)`;
+ console.log("mouse move!");
+ timelineContainer.style.width = "500px";
+ }
+
@action
minimize = (e: React.MouseEvent) => {
e.preventDefault();
@@ -246,6 +262,17 @@ export class Timeline extends CollectionSubView(Document) {
}
}
+ @action
+ toTime = (time: number): string => {
+ const inSeconds = time / 1000;
+ let min: (string | number) = Math.floor(inSeconds / 60);
+ let sec: (string | number) = inSeconds % 60;
+
+ if (Math.floor(sec / 10) === 0) {
+ sec = "0" + sec;
+ }
+ return `${min}:${sec}`;
+ }
@action
getFlyout = (props: FlyoutProps) => {
@@ -265,15 +292,63 @@ export class Timeline extends CollectionSubView(Document) {
}), icon: "pinterest"
});
ContextMenu.Instance.addItem({ description: "Timeline Funcs...", subitems: subitems });
+
+ }
+
+ @action
+ changeTime = (e: React.KeyboardEvent) => {
+ let time = this._timeInput.current!;
+ if (e.keyCode === 13){
+ if (!Number.isNaN(Number(time.value))){
+ this.flyoutInfo.regiondata!.position = Number(time.value) / 1000 * this._tickSpacing;
+ time.placeholder = time.value +"ms";
+ time.value = "";
+ }
+ }
+ }
+
+
+ @action
+ changeDuration = (e:React.KeyboardEvent) => {
+ let duration = this._durationInput.current!;
+ if (e.keyCode === 13){
+ if (!Number.isNaN(Number(duration.value))){
+ this.flyoutInfo.regiondata!.duration = Number(duration.value) / 1000 * this._tickSpacing;
+ duration.placeholder = duration.value +"ms";
+ duration.value = "";
+ }
+ }
+ }
+
+ @action
+ changeFadeIn = (e:React.KeyboardEvent) => {
+ let fadeIn = this._fadeInInput.current!;
+ if (e.keyCode === 13){
+ if (!Number.isNaN(Number(fadeIn.value))){
+ this.flyoutInfo.regiondata!.fadeIn = Number(fadeIn.value);
+ fadeIn.placeholder = fadeIn.value +"ms";
+ fadeIn.value = "";
+ }
+ }
}
+ @action
+ changeFadeOut = (e:React.KeyboardEvent) => {
+ let fadeOut = this._fadeOutInput.current!;
+ if (e.keyCode === 13){
+ if (!Number.isNaN(Number(fadeOut.value))){
+ this.flyoutInfo.regiondata!.fadeOut = Number(fadeOut.value);
+ fadeOut.placeholder = fadeOut.value +"ms";
+ fadeOut.value = "";
+ }
+ }
+ }
render() {
return (
<div>
<button className="minimize" onClick={this.minimize}>Minimize</button>
- <div className="timeline-container" style={{ height: `${this._containerHeight}px` }} ref={this._timelineContainer} onContextMenu={this.timelineContextMenu}>
- <div className="flyout-container" style={{ transform: `translate(${this.flyoutInfo.x}px, ${this.flyoutInfo.y}px)`, display: this.flyoutInfo.display }} onPointerDown={this.onFlyoutDown}>
+ <div className="flyout-container" style={{left:`${this.flyoutInfo.x}px`, top:`${this.flyoutInfo.y}px`, display: `${this.flyoutInfo.display!}` }} onPointerDown={this.onFlyoutDown}>
<FontAwesomeIcon className="flyout" icon="comment-alt" color="grey" />
<div className="text-container">
<p>Time:</p>
@@ -282,12 +357,15 @@ export class Timeline extends CollectionSubView(Document) {
<p>Fade-out</p>
</div>
<div className="input-container">
- <input type="text" placeholder={`${Math.round(this.flyoutInfo.time! / this._tickSpacing * 1000)}ms`} />
- <input type="text" placeholder={`${Math.round(this.flyoutInfo.duration! / this._tickSpacing * 1000)}ms`} />
- <input type="text" placeholder={`${Math.round(this.flyoutInfo.time! / this._tickSpacing * 1000)}ms`} />
- <input type="text" placeholder={`${Math.round(this.flyoutInfo.duration! / this._tickSpacing * 1000)}ms`} />
+ <input ref = {this._timeInput} type="text" placeholder={`${Math.round(NumCast(this.flyoutInfo.regiondata!.position)/ this._tickSpacing * 1000)}ms`} onKeyDown={this.changeTime} />
+ <input ref = {this._durationInput} type="text" placeholder={`${Math.round(NumCast(this.flyoutInfo.regiondata!.duration) / this._tickSpacing * 1000)}ms`} onKeyDown={this.changeDuration}/>
+ <input ref = {this._fadeInInput} type="text" placeholder={`${Math.round(NumCast(this.flyoutInfo.regiondata!.fadeIn))}ms`} onKeyDown={this.changeFadeIn}/>
+ <input ref = {this._fadeOutInput} type="text" placeholder={`${Math.round(NumCast(this.flyoutInfo.regiondata!.fadeOut))}ms`} onKeyDown={this.changeFadeOut}/>
+
</div>
+ <button onClick={action((e:React.MouseEvent)=>{this.flyoutInfo.regions!.splice(this.flyoutInfo.regions!.indexOf(this.flyoutInfo.regiondata!), 1); this.flyoutInfo.display = "none";})}>delete</button>
</div>
+ <div className="timeline-container" style={{ height: `${this._containerHeight}px` }} ref={this._timelineContainer} onContextMenu={this.timelineContextMenu} >
<div className="toolbox">
<div onClick={this.windBackward}> <FontAwesomeIcon icon={faBackward} size="2x" /> </div>
<div onClick={this.onPlay}> <FontAwesomeIcon icon={faPlayCircle} size="2x" /> </div>
@@ -304,12 +382,12 @@ export class Timeline extends CollectionSubView(Document) {
return <div className="tick" style={{ transform: `translate(${element / 1000 * this._tickSpacing}px)`, position: "absolute", pointerEvents: "none" }}> <p>{this.toTime(element)}</p></div>;
})}
</div>
- <div className="scrubber" onPointerDown={this.onScrubberDown} style={{ transform: `translate(${this._currentBarX}px)` }}>
+ <div className="scrubber" ref={this._scrubber} onPointerDown={this.onScrubberDown} style={{ transform: `translate(${this._currentBarX}px)` }}>
<div className="scrubberhead"></div>
</div>
<div className="trackbox" ref={this._trackbox} onPointerDown={this.onPanDown}>
{this._nodes.map(doc => {
- return <Track node={(doc as any).value() as Doc} currentBarX={this._currentBarX} setFlyout={this.getFlyout} />;
+ return <Track node={(doc as any).value() as Doc} currentBarX={this._currentBarX} changeCurrentBarX = {this.changeCurrentBarX} setFlyout={this.getFlyout} />;
})}
</div>
</div>
diff --git a/src/client/views/nodes/Track.tsx b/src/client/views/nodes/Track.tsx
index cf613a827..f3b92f20c 100644
--- a/src/client/views/nodes/Track.tsx
+++ b/src/client/views/nodes/Track.tsx
@@ -6,29 +6,32 @@ import { Doc, DocListCastAsync, DocListCast } from "../../../new_fields/Doc";
import { Document, listSpec, createSchema, makeInterface, defaultSpec } from "../../../new_fields/Schema";
import { FieldValue, Cast, NumCast, BoolCast } from "../../../new_fields/Types";
import { List } from "../../../new_fields/List";
-import { Keyframe, RegionData } from "./Keyframe";
+import { Keyframe, KeyframeFunc } from "./Keyframe";
import { FlyoutProps } from "./Timeline";
interface IProps {
node: Doc;
currentBarX: number;
+ changeCurrentBarX: (x:number) => void;
setFlyout: (props:FlyoutProps) => any;
}
@observer
export class Track extends React.Component<IProps> {
- @observable private _inner = React.createRef<HTMLDivElement>();
+ @observable private _inner = React.createRef<HTMLDivElement>();
+ @observable private _keys = ["x", "y", "width", "height", "panX", "panY", "scale"];
private _reactionDisposers: IReactionDisposer[] = [];
private _selectionManagerChanged?: IReactionDisposer;
- @observable private _keys = ["x", "y", "width", "height", "panX", "panY", "scale"];
-
+ @computed
+ private get regions() {
+ return Cast(this.props.node.regions, listSpec(Doc)) as List<Doc>;
+ }
componentWillMount() {
this.props.node.regions = new List<Doc>();
- console.log((Cast(this.props.node.regions, listSpec(Doc)) as List<Doc>).length);
}
@action
@@ -45,18 +48,21 @@ export class Track extends React.Component<IProps> {
}
});
- // reaction(() => {
- // let keys = Doc.allKeys(this.props.node);
- // let x = keys.indexOf("keyframes");
- // let afterX = keys.slice(x + 1);
- // let beforeX = keys.slice(0, x);
- // keys = beforeX.concat(afterX);
- // return keys.map(key => FieldValue(this.props.node[key]));
- // }, data => {
- // if (this.keyframes.length !== 0){
- // let kf:(Doc | undefined) = this.findKeyframe(this.props.currentBarX);
- // }
- // });
+ reaction(() => {
+ let keys = Doc.allKeys(this.props.node);
+ return keys.map(key => FieldValue(this.props.node[key]));
+ }, data => {
+ let regiondata = this.findRegion(this.props.currentBarX);
+ if (regiondata){
+ (Cast(regiondata.keyframes!, listSpec(Doc)) as List<Doc>).forEach((kf) => {
+ kf = kf as Doc;
+ if(NumCast(kf.time!) === this.props.currentBarX){
+ console.log("hoorayy!!!");
+ }
+ });
+ }
+
+ });
}
/**
* removes reaction when the component is removed from the timeline
@@ -72,21 +78,16 @@ export class Track extends React.Component<IProps> {
let region = this.findRegion(time);
let leftkf: (Doc | undefined) = this.calcMinLeft(region!);
let rightkf: (Doc | undefined) = this.calcMinRight(region!);
-
-
if (leftkf && rightkf) {
this.interpolate(leftkf, rightkf);
} else if (leftkf) {
- console.log("left exists");
+ console.log("left exists");
console.log(leftkf.time);
this._keys.forEach(k => {
let data = leftkf!.key as Doc;
this.props.node[k] = data[k];
});
} else if (rightkf) {
-
- console.log("right exists");
- console.log(rightkf.time);
this._keys.forEach(k => {
let data = rightkf!.key as Doc;
this.props.node[k] = data[k];
@@ -95,11 +96,6 @@ export class Track extends React.Component<IProps> {
}
- /**
- * calculates the closest left keyframe, if there is one
- * @param kfList: keyframe list
- * @param time
- */
@action
calcMinLeft = (region: Doc): (Doc | undefined) => { //returns the time of the closet keyframe to the left
let leftKf:(Doc| undefined) = undefined;
@@ -114,11 +110,7 @@ export class Track extends React.Component<IProps> {
return leftKf;
}
- /**
- * calculates the closest right keyframe, if there is one
- * @param kfList: keyframe lsit
- * @param time: time
- */
+
@action
calcMinRight = (region: Doc): (Doc | undefined) => { //returns the time of the closest keyframe to the right
let rightKf: (Doc|undefined) = undefined;
@@ -133,15 +125,6 @@ export class Track extends React.Component<IProps> {
return rightKf;
}
-
-
- /**
- * Linearly interpolates a document from time1 to time2
- * @param Doc that needs to be modified
- * @param kf1 timeandposition of the first yellow bar
- * @param kf2 timeandposition of the second yellow bar
- * @param time time that you want to interpolate
- */
@action
interpolate = async (kf1: Doc, kf2: Doc) => {
let node1 = kf1.key as Doc;
@@ -158,13 +141,11 @@ export class Track extends React.Component<IProps> {
});
}
-
-
@action
findRegion(time: number): (Doc | undefined) {
let foundRegion = undefined;
this.regions.map(region => {
- region = RegionData(region as Doc);
+ region = region as Doc;
if (time >= NumCast(region.position) && time <= (NumCast(region.position) + NumCast(region.duration))) {
foundRegion = region;
}
@@ -172,25 +153,29 @@ export class Track extends React.Component<IProps> {
return foundRegion;
}
-
@action
onInnerDoubleClick = (e: React.MouseEvent) => {
let inner = this._inner.current!;
let left = inner.getBoundingClientRect().left;
let offsetX = Math.round(e.clientX - left);
- let regiondata: Doc = new Doc(); //creating regiond ata
+ let regiondata: Doc = new Doc(); //creating regiondata
regiondata.duration = 200;
regiondata.position = offsetX;
+ regiondata.fadeIn = 20;
+ regiondata.fadeOut = 20;
regiondata.keyframes = new List<Doc>();
+ 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) < regiondata.fadeIn + regiondata.fadeOut) || (rightRegion && rightRegion.position - regiondata.position < regiondata.fadeIn + regiondata.fadeOut)){
+ return;
+ } else if (rightRegion && rightRegion.position - regiondata.position >= regiondata.fadeIn + regiondata.fadeOut){
+ regiondata.duration = rightRegion.position - regiondata.position;
+ }
this.regions.push(regiondata);
}
- @computed
- private get regions() {
- console.log((Cast(this.props.node.regions, listSpec(Doc)) as List<Doc>).length + "from get");
- return Cast(this.props.node.regions, listSpec(Doc)) as List<Doc>;
- }
+
render() {
return (
@@ -198,7 +183,7 @@ export class Track extends React.Component<IProps> {
<div className="track">
<div className="inner" ref={this._inner} onDoubleClick={this.onInnerDoubleClick}>
{this.regions.map((region) => {
- return <Keyframe node={this.props.node} RegionData={region as Doc} setFlyout={this.props.setFlyout}/>;
+ return <Keyframe node={this.props.node} RegionData={region as Doc} changeCurrentBarX={this.props.changeCurrentBarX} setFlyout={this.props.setFlyout}/>;
})}
</div>
</div>