aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/animationtimeline
diff options
context:
space:
mode:
authorandrewdkim <adkim414@gmail.com>2019-10-02 15:59:56 -0400
committerandrewdkim <adkim414@gmail.com>2019-10-02 15:59:56 -0400
commit00416cdb70aa8dd9698972ab0df8ca0a6c8575f9 (patch)
treefb446dbdf8ff37d58aaa92019ae3edf72409900b /src/client/views/animationtimeline
parent2f09822358dba784ec26d5707423b4025096ee45 (diff)
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web into animationtimeline_two
Diffstat (limited to 'src/client/views/animationtimeline')
-rw-r--r--src/client/views/animationtimeline/Keyframe.tsx103
-rw-r--r--src/client/views/animationtimeline/Timeline.scss56
-rw-r--r--src/client/views/animationtimeline/Timeline.tsx152
-rw-r--r--src/client/views/animationtimeline/TimelineMenu.tsx11
-rw-r--r--src/client/views/animationtimeline/Track.tsx42
5 files changed, 156 insertions, 208 deletions
diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx
index 7197f4b49..66ad6a76d 100644
--- a/src/client/views/animationtimeline/Keyframe.tsx
+++ b/src/client/views/animationtimeline/Keyframe.tsx
@@ -8,7 +8,6 @@ import { Doc, DocListCast, DocListCastAsync } from "../../../new_fields/Doc";
import { Cast, NumCast } from "../../../new_fields/Types";
import { List } from "../../../new_fields/List";
import { createSchema, defaultSpec, makeInterface, listSpec } from "../../../new_fields/Schema";
-import { FlyoutProps } from "./Timeline";
import { Transform } from "../../util/Transform";
import { InkField, StrokeData } from "../../../new_fields/InkField";
import { TimelineMenu } from "./TimelineMenu";
@@ -138,48 +137,13 @@ export class Keyframe extends React.Component<IProps> {
@observable private _mouseToggled = false;
@observable private _doubleClickEnabled = false;
- @computed
- private get regiondata() {
- let index = this.regions.indexOf(this.props.RegionData);
- return RegionData(this.regions[index] as Doc);
- }
-
- @computed
- private get regions() {
- return Cast(this.props.node.regions, listSpec(Doc)) as List<Doc>;
- }
-
- @computed
- private get firstKeyframe() {
- let first: (Doc | undefined) = undefined;
- DocListCast(this.regiondata.keyframes!).forEach(kf => {
- if (kf.type !== KeyframeFunc.KeyframeType.fade) {
- if (!first || first && NumCast(kf.time) < NumCast(first.time)) {
- first = kf;
- }
- }
- });
- return first;
- }
-
- @computed
- private get lastKeyframe() {
- let last: (Doc | undefined) = undefined;
- DocListCast(this.regiondata.keyframes!).forEach(kf => {
- if (kf.type !== KeyframeFunc.KeyframeType.fade) {
- if (!last || last && NumCast(kf.time) > NumCast(last.time)) {
- last = kf;
- }
- }
- });
- return last;
- }
-
- @computed
- private get keyframes(){
- return DocListCast(this.regiondata.keyframes);
- }
-
+ @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 inks() {
if (this.props.collection.data_ext) {
@@ -191,38 +155,18 @@ export class Keyframe extends React.Component<IProps> {
}
}
- @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);
- }
-
- async componentWillMount() {
- if (!this.regiondata.keyframes) {
- this.regiondata.keyframes = new List<Doc>();
- }
- 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)!;
- (fadeIn.key! as Doc).opacity = 1;
- (fadeOut.key! as Doc).opacity = 1;
- (start.key! as Doc).opacity = 0.1;
- (finish.key! as Doc).opacity = 0.1;
+ componentWillMount() {
+ runInAction(async () => {
+ if (!this.regiondata.keyframes) this.regiondata.keyframes = new List<Doc>();
+ 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)!;
+ (fadeIn.key! as Doc).opacity = 1;
+ (fadeOut.key! as Doc).opacity = 1;
+ (start.key! as Doc).opacity = 0.1;
+ (finish.key! as Doc).opacity = 0.1;
+ });
}
@action
@@ -336,7 +280,7 @@ export class Keyframe extends React.Component<IProps> {
let bar = this._bar.current!;
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);
- let firstkf: (Doc | undefined) = this.firstKeyframe;
+ let firstkf: (Doc | undefined) = this.keyframes[0];
if (firstkf && this.regiondata.position + this.regiondata.fadeIn + offset >= NumCast(firstkf!.time)) {
let dif = NumCast(firstkf!.time) - (this.pixelPosition + this.pixelFadeIn);
this.regiondata.position = NumCast(firstkf!.time) - this.regiondata.fadeIn;
@@ -364,8 +308,8 @@ 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);
- if (this.lastKeyframe! && this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut + offset <= NumCast((this.lastKeyframe! as Doc).time)) {
- let dif = this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut - NumCast((this.lastKeyframe! as Doc).time);
+ if (this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut + offset <= NumCast((this.keyframes[this.keyframes.length - 1]).time)) {
+ let dif = this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut - NumCast((this.keyframes[this.keyframes.length - 1]).time);
this.regiondata.duration -= dif;
} else if (this.regiondata.duration + offset < this.regiondata.fadeIn + this.regiondata.fadeOut) { // nokeyframes, just fades
this.regiondata.duration = this.regiondata.fadeIn + this.regiondata.fadeOut;
@@ -532,6 +476,7 @@ export class Keyframe extends React.Component<IProps> {
e.stopPropagation();
let div = ref.current!;
div.style.opacity = "1";
+ Doc.BrushDoc(this.props.node);
}
onContainerOut = (e: React.PointerEvent, ref: React.RefObject<HTMLDivElement>) => {
@@ -539,6 +484,7 @@ export class Keyframe extends React.Component<IProps> {
e.stopPropagation();
let div = ref.current!;
div.style.opacity = "0";
+ Doc.UnBrushDoc(this.props.node);
}
@@ -623,7 +569,6 @@ export class Keyframe extends React.Component<IProps> {
}
}
render() {
- console.log("RERENDERING");
return (
<div>
<div className="bar" ref={this._bar} style={{ transform: `translate(${this.pixelPosition}px)`,
diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss
index 1457d5a84..09fc593fc 100644
--- a/src/client/views/animationtimeline/Timeline.scss
+++ b/src/client/views/animationtimeline/Timeline.scss
@@ -1,11 +1,6 @@
@import "./../globalCssVariables.scss";
-.minimize{
- position:relative;
- z-index: 1000;
- height: 30px;
- width: 100px;
-}
+
.timeline-toolbox{
position:absolute;
@@ -17,6 +12,8 @@
margin-left:10px;
}
}
+
+
.timeline-container{
width:100%;
height:300px;
@@ -37,12 +34,10 @@
background-color: transparent;
height: 30px;
width:100%;
-
.tick{
height:100%;
width: 1px;
background-color:black;
-
}
}
.scrubber{
@@ -119,4 +114,49 @@
width: 100%;
background-color: grey;
}
+}
+
+.round-toggle {
+ position: absolute;
+ height: 40px;
+ width: 80px;
+ background-color: white;
+ border: 2px solid purple;
+ border-radius: 20px;
+ animation-fill-mode: forwards;
+ animation-duration: 500ms;
+ input{
+ position:absolute;
+ opacity: 0;
+ height: 0;
+ width: 0;
+ }
+ .round-toggle-slider{
+ position:absolute;
+ height: 35px;
+ width: 35px;
+ top: 0.5px;
+ background-color: white;
+ border:1px solid grey;
+ border-radius: 20px;
+ transition: transform 500ms ease-in-out;
+
+ }
+
+}
+@keyframes turnon{
+ from{
+ background-color: white;
+ }
+ to{
+ background-color: purple;
+ }
+}
+@keyframes turnoff{
+ from{
+ background-color: purple;
+ }
+ to{
+ background-color: white;
+ }
} \ No newline at end of file
diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx
index c50ffa51b..8127e4de2 100644
--- a/src/client/views/animationtimeline/Timeline.tsx
+++ b/src/client/views/animationtimeline/Timeline.tsx
@@ -15,17 +15,6 @@ import { TimelineOverview } from "./TimelineOverview";
import { FieldViewProps } from "../nodes/FieldView";
import { KeyframeFunc } from "./Keyframe";
-
-
-export interface FlyoutProps {
- x?: number;
- y?: number;
- display?: string;
- regiondata?: Doc;
- regions?: List<Doc>;
-}
-
-
@observer
export class Timeline extends React.Component<FieldViewProps> {
@@ -35,26 +24,23 @@ export class Timeline extends React.Component<FieldViewProps> {
private readonly MAX_CONTAINER_HEIGHT: number = 800;
private readonly DEFAULT_TICK_INCREMENT: number = 1000;
- @observable private _isMinimized = false;
- @observable private _tickSpacing = this.DEFAULT_TICK_SPACING;
- @observable private _tickIncrement = this.DEFAULT_TICK_INCREMENT;
-
@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 _timelineWrapper = React.createRef<HTMLDivElement>();
@observable private _infoContainer = React.createRef<HTMLDivElement>();
+ @observable private _roundToggleRef = React.createRef<HTMLDivElement>();
+ @observable private _roundToggleContainerRef = React.createRef<HTMLDivElement>();
@observable private _currentBarX: number = 0;
@observable private _windSpeed: number = 1;
@observable private _isPlaying: boolean = false; //scrubber playing
- @observable private _isFrozen: boolean = true; //timeline freeze
@observable private _totalLength: number = 0;
@observable private _visibleLength: number = 0;
@observable private _visibleStart: number = 0;
- @observable private _containerHeight: number = this.DEFAULT_CONTAINER_HEIGHT;
+ @observable private _containerHeight: number = this.DEFAULT_CONTAINER_HEIGHT;
+ @observable private _tickSpacing = this.DEFAULT_TICK_SPACING;
+ @observable private _tickIncrement = this.DEFAULT_TICK_INCREMENT;
@observable private _time = 100000; //DEFAULT
@observable private _ticks: number[] = [];
@observable private _playButton = faPlayCircle;
@@ -273,39 +259,7 @@ export class Timeline extends React.Component<FieldViewProps> {
}
}
- @action
- onTimelineDown = (e: React.PointerEvent) => {
- e.preventDefault();
- if (e.nativeEvent.which === 1 && !this._isFrozen) {
- document.addEventListener("pointermove", this.onTimelineMove);
- document.addEventListener("pointerup", () => { document.removeEventListener("pointermove", this.onTimelineMove); });
- }
- }
- @action
- onTimelineMove = (e: PointerEvent) => {
- e.preventDefault();
- e.stopPropagation();
- let timelineContainer = this._timelineWrapper.current!;
- let left = parseFloat(timelineContainer.style.left!);
- let top = parseFloat(timelineContainer.style.top!);
- timelineContainer.style.left = `${left + e.movementX}px`;
- timelineContainer.style.top = `${top + e.movementY}px`;
- }
-
- @action
- minimize = (e: React.MouseEvent) => {
- e.preventDefault();
- e.stopPropagation();
- let timelineContainer = this._timelineContainer.current!;
- if (this._isMinimized) {
- this._isMinimized = false;
- timelineContainer.style.visibility = "visible";
- } else {
- this._isMinimized = true;
- timelineContainer.style.visibility = "hidden";
- }
- }
@action
toReadTime = (time: number): string => {
@@ -321,21 +275,6 @@ export class Timeline extends React.Component<FieldViewProps> {
timelineContextMenu = (e:MouseEvent): void => {
let subitems: ContextMenuProps[] = [];
- let timelineContainer = this._timelineWrapper.current!;
- subitems.push({
- description: "Pin to Top", event: action(() => {
- if (!this._isFrozen) {
- timelineContainer.style.left = "0px";
- timelineContainer.style.top = "0px";
- timelineContainer.style.transition = "none";
- }
- }), icon: faArrowUp
- });
- subitems.push({
- description: this._isFrozen ? "Unfreeze Timeline" : "Freeze Timeline", event: action(() => {
- this._isFrozen = !this._isFrozen;
- }), icon: "thumbtack"
- });
subitems.push({
description: this._timelineVisible ? "Hide Timeline" : "Show Timeline", event: action(() => {
this._timelineVisible = !this._timelineVisible;
@@ -358,7 +297,8 @@ export class Timeline extends React.Component<FieldViewProps> {
let currPixel = KeyframeFunc.convertPixelTime(prevTime, "mili", "pixel", this._tickSpacing, this._tickIncrement);
let currCurrent = KeyframeFunc.convertPixelTime(prevCurrent, "mili", "pixel", this._tickSpacing, this._tickIncrement);
this._infoContainer.current!.scrollLeft = currPixel - offset;
- this._visibleStart = currPixel - offset;
+ this._visibleStart = currPixel - offset > 0 ? currPixel - offset : 0;
+ this._visibleStart += this._visibleLength + this._visibleStart > this._totalLength ? this._totalLength - (this._visibleStart + this._visibleLength) :0;
this.changeCurrentBarX(currCurrent);
}
@@ -393,44 +333,70 @@ export class Timeline extends React.Component<FieldViewProps> {
private timelineToolBox = (scale:number) => {
let size = 50 * scale; //50 is default
- return (
+ return (
+
<div key="timeline_toolbox" className="timeline-toolbox" style={{height:`${size}px`}}>
- <div key="timeline_windBack" onClick={this.windBackward}> <FontAwesomeIcon icon={faBackward} style={{height:`${size}px`, width: `${size}px`}} /> </div>
- <div key =" timeline_play" onClick={this.onPlay}> <FontAwesomeIcon icon={this._playButton} style={{height:`${size}px`, width: `${size}px`}} /> </div>
- <div key="timeline_windForward" onClick={this.windForward}> <FontAwesomeIcon icon={faForward} style={{height:`${size}px`, width: `${size}px`}} /> </div>
- <TimelineOverview scale={scale} currentBarX={this._currentBarX} totalLength={this._totalLength} visibleLength={this._visibleLength} visibleStart={this._visibleStart} changeCurrentBarX={this.changeCurrentBarX} movePanX={this.movePanX}/>
+ <div key="timeline_windBack" onClick={this.windBackward}> <FontAwesomeIcon icon={faBackward} style={{height:`${size}px`, width: `${size}px`}} /> </div>
+ <div key =" timeline_play" onClick={this.onPlay}> <FontAwesomeIcon icon={this._playButton} style={{height:`${size}px`, width: `${size}px`}} /> </div>
+ <div key="timeline_windForward" onClick={this.windForward}> <FontAwesomeIcon icon={faForward} style={{height:`${size}px`, width: `${size}px`}} /> </div>
+ <TimelineOverview scale={scale} currentBarX={this._currentBarX} totalLength={this._totalLength} visibleLength={this._visibleLength} visibleStart={this._visibleStart} changeCurrentBarX={this.changeCurrentBarX} movePanX={this.movePanX}/>
+ <div ref={this._roundToggleContainerRef}key="round-toggle" className="round-toggle">
+ <div ref={this._roundToggleRef} className="round-toggle-slider" onPointerDown = {this.toggleChecked}> </div>
+ </div>
</div>
);
}
+
+ @action
+ private toggleChecked = (e:React.PointerEvent) => {
+ e.preventDefault();
+ e.stopPropagation();
+ let roundToggle = this._roundToggleRef.current!;
+ let roundToggleContainer = this._roundToggleContainerRef.current!;
+ if (BoolCast(this.props.Document.isAnimating)){
+ roundToggle.style.transform = "translate(0px, 0px)";
+ roundToggle.style.animationName = "turnoff";
+ roundToggleContainer.style.animationName = "turnoff";
+
+ this.props.Document.isAnimating = false;
+ } else {
+ roundToggle.style.transform = "translate(45px, 0px)";
+ roundToggle.style.animationName = "turnon";
+ roundToggleContainer.style.animationName = "turnon";
+ this.props.Document.isAnimating = true;
+ }
+ }
render() {
return (
- <div style={{visibility: this._timelineVisible ? "visible" : "hidden"}}>
- <div key="timeline_wrapper" style={{visibility: BoolCast(this.props.Document.isAnimating && this._timelineVisible) ? "visible" :"hidden", left: "0px", top: "0px", position: "absolute", width: "100%", transform: "translate(0px, 0px)"}} ref={this._timelineWrapper}>
- <button key="timeline_minimize" className="minimize" onClick={this.minimize}>Minimize</button>
- <div key="timeline_container" className="timeline-container" style={{ height: `${this._containerHeight}px`, left: "0px", top: "30px" }} ref={this._timelineContainer} onPointerDown={this.onTimelineDown}>
- {this.timelineToolBox(0.5)}
- <div key ="timeline_info"className="info-container" ref={this._infoContainer} onWheel={this.onWheelZoom}>
- <div key="timeline_scrubberbox" className="scrubberbox" ref={this._scrubberbox} style={{width: `${this._totalLength}px`}} onClick={this.onScrubberClick}>
- {this._ticks.map(element => {
- if(element % this._tickIncrement === 0) return <div className="tick" style={{ transform: `translate(${(element / this._tickIncrement)* this._tickSpacing}px)`, position: "absolute", pointerEvents: "none" }}> <p>{this.toReadTime(element)}</p></div>;
- })}
+ <div>
+ <div style={{visibility: this._timelineVisible ? "visible" : "hidden"}}>
+ <div key="timeline_wrapper" style={{visibility: BoolCast(this.props.Document.isAnimating && this._timelineVisible) ? "visible" :"hidden", left: "0px", top: "0px", position: "absolute", width: "100%", transform: "translate(0px, 0px)"}}>
+ <div key="timeline_container" className="timeline-container" ref={this._timelineContainer} style={{ height: `${this._containerHeight}px`, left: "0px", top: "30px" }}>
+ <div key ="timeline_info"className="info-container" ref={this._infoContainer} onWheel={this.onWheelZoom}>
+ <div key="timeline_scrubberbox" className="scrubberbox" ref={this._scrubberbox} style={{width: `${this._totalLength}px`}} onClick={this.onScrubberClick}>
+ {this._ticks.map(element => {
+ if(element % this._tickIncrement === 0) return <div className="tick" style={{ transform: `translate(${(element / this._tickIncrement)* this._tickSpacing}px)`, position: "absolute", pointerEvents: "none" }}> <p>{this.toReadTime(element)}</p></div>;
+ })}
+ </div>
+ <div key="timeline_scrubber" className="scrubber" onPointerDown={this.onScrubberDown} style={{ transform: `translate(${this._currentBarX}px)` }}>
+ <div key="timeline_scrubberhead" className="scrubberhead"></div>
+ </div>
+ <div key="timeline_trackbox" className="trackbox" ref={this._trackbox} onPointerDown={this.onPanDown} style={{width: `${this._totalLength}px`}}>
+ {DocListCast(this.children).map(doc => <Track node={doc} currentBarX={this._currentBarX} changeCurrentBarX={this.changeCurrentBarX} transform={this.props.ScreenToLocalTransform()} time={this._time} tickSpacing = {this._tickSpacing} tickIncrement ={this._tickIncrement} collection = {this.props.Document} timelineVisible = {this._timelineVisible}/>)}
+ </div>
</div>
- <div key="timeline_scrubber" className="scrubber" ref={this._scrubber} onPointerDown={this.onScrubberDown} style={{ transform: `translate(${this._currentBarX}px)` }}>
- <div key="timeline_scrubberhead" className="scrubberhead"></div>
+ <div key="timeline_title"className="title-container" ref={this._titleContainer}>
+ {DocListCast(this.children).map(doc => <div className="datapane" onPointerOver={() => {Doc.BrushDoc(doc);}} onPointerOut={() => {Doc.UnBrushDoc(doc);}}><p>{doc.title}</p></div>)}
</div>
- <div key="timeline_trackbox" className="trackbox" ref={this._trackbox} onPointerDown={this.onPanDown} style={{width: `${this._totalLength}px`}}>
- {DocListCast(this.children).map(doc => <Track node={doc} currentBarX={this._currentBarX} changeCurrentBarX={this.changeCurrentBarX} transform={this.props.ScreenToLocalTransform()} time={this._time} tickSpacing = {this._tickSpacing} tickIncrement ={this._tickIncrement} collection = {this.props.Document} timelineVisible = {this._timelineVisible}/>)}
+ <div key="timeline_resize" onPointerDown={this.onResizeDown}>
+ <FontAwesomeIcon className="resize" icon={faGripLines}/>
</div>
</div>
- <div key="timeline_title"className="title-container" ref={this._titleContainer}>
- {DocListCast(this.children).map(doc => <div className="datapane"><p>{doc.title}</p></div>)}
- </div>
- <div key="timeline_resize" onPointerDown={this.onResizeDown}>
- <FontAwesomeIcon className="resize" icon={faGripLines} />
- </div>
</div>
+ { this.timelineToolBox(1) }
</div>
- {BoolCast(this.props.Document.isAnimating) ? <div></div>: this.timelineToolBox(1) }
+
+
</div>
);
}
diff --git a/src/client/views/animationtimeline/TimelineMenu.tsx b/src/client/views/animationtimeline/TimelineMenu.tsx
index f3b985297..59c25596e 100644
--- a/src/client/views/animationtimeline/TimelineMenu.tsx
+++ b/src/client/views/animationtimeline/TimelineMenu.tsx
@@ -4,6 +4,7 @@ import {observer} from "mobx-react";
import "./TimelineMenu.scss";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faChartLine, faRoad, faClipboard, faPen, faTrash, faTable } from "@fortawesome/free-solid-svg-icons";
+import { Utils } from "../../../Utils";
@observer
@@ -40,7 +41,7 @@ export class TimelineMenu extends React.Component {
if (type === "input"){
let inputRef = React.createRef<HTMLInputElement>();
let text = "";
- this._currentMenu.push(<div className="timeline-menu-item"><FontAwesomeIcon icon={faClipboard} size="lg"/><input className="timeline-menu-input" ref = {inputRef} placeholder={title} onChange={(e) => {
+ this._currentMenu.push(<div key={Utils.GenerateGuid()} className="timeline-menu-item"><FontAwesomeIcon icon={faClipboard} size="lg"/><input className="timeline-menu-input" ref = {inputRef} placeholder={title} onChange={(e) => {
e.stopPropagation();
text = e.target.value;
}} onKeyDown={(e) => {
@@ -52,23 +53,23 @@ export class TimelineMenu extends React.Component {
}}/></div>);
} else if (type === "button") {
let buttonRef = React.createRef<HTMLDivElement>();
- this._currentMenu.push( <div className="timeline-menu-item"><FontAwesomeIcon icon={faChartLine}size="lg"/><p className="timeline-menu-desc" onClick={(e) => {
+ this._currentMenu.push( <div key={Utils.GenerateGuid()} className="timeline-menu-item"><FontAwesomeIcon icon={faChartLine}size="lg"/><p className="timeline-menu-desc" onClick={(e) => {
e.preventDefault();
e.stopPropagation();
event(e);
this.closeMenu();
}}>{title}</p></div>);
- }
+ }
}
@action
addMenu = (title:string) => {
- this._currentMenu.unshift(<div className="timeline-menu-header"><p className="timeline-menu-header-desc">{title}</p></div>);
+ this._currentMenu.unshift(<div key={Utils.GenerateGuid()} className="timeline-menu-header"><p className="timeline-menu-header-desc">{title}</p></div>);
}
render() {
return (
- <div className="timeline-menu-container" style={{opacity: this._opacity, left: this._x, top: this._y}} >
+ <div key={Utils.GenerateGuid()} className="timeline-menu-container" style={{opacity: this._opacity, left: this._x, top: this._y}} >
{this._currentMenu}
</div>
);
diff --git a/src/client/views/animationtimeline/Track.tsx b/src/client/views/animationtimeline/Track.tsx
index c68d9bb3a..3ec410216 100644
--- a/src/client/views/animationtimeline/Track.tsx
+++ b/src/client/views/animationtimeline/Track.tsx
@@ -32,18 +32,24 @@ export class Track extends React.Component<IProps> {
@observable private _onKeyframe: (Doc | undefined) = undefined;
@observable private _onRegionData: (Doc | undefined) = undefined;
@observable private _storedState: (Doc | undefined) = undefined;
-
- @computed
- private get regions() {
- return Cast(this.props.node.regions, listSpec(Doc)) as List<Doc>;
- }
+ @observable private filterList = [
+ "regions",
+ "cursors",
+ "hidden",
+ "nativeHeight",
+ "nativeWidth",
+ "schemaColumns",
+ "baseLayout",
+ "backgroundLayout",
+ "layout",
+ ];
+
+ @computed private get regions() { return Cast(this.props.node.regions, listSpec(Doc)) as List<Doc>;}
componentWillMount() {
- if (!this.props.node.regions) {
- this.props.node.regions = new List<Doc>();
- }
-
-
+ runInAction(() => {
+ if (!this.props.node.regions) this.props.node.regions = new List<Doc>();
+ });
}
componentDidMount() {
@@ -54,11 +60,11 @@ export class Track extends React.Component<IProps> {
this.props.node.hidden = false;
this.props.node.opacity = 1;
});
-
}
componentWillUnmount() {
runInAction(() => {
+ //disposing reactions
if (this._currentBarXReaction) this._currentBarXReaction();
if (this._timelineVisibleReaction) this._timelineVisibleReaction();
});
@@ -166,17 +172,7 @@ export class Track extends React.Component<IProps> {
});
}
- private filterList = [
- "regions",
- "cursors",
- "hidden",
- "nativeHeight",
- "nativeWidth",
- "schemaColumns",
- "baseLayout",
- "backgroundLayout",
- "layout",
- ];
+
@action
private filterKeys = (keys: string[]): string[] => {
@@ -294,7 +290,7 @@ export class Track extends React.Component<IProps> {
return (
<div className="track-container">
<div className="track">
- <div className="inner" ref={this._inner} onDoubleClick={this.onInnerDoubleClick}>
+ <div className="inner" ref={this._inner} onDoubleClick={this.onInnerDoubleClick} onPointerOver = {() => {Doc.BrushDoc(this.props.node);}}onPointerOut={() => {Doc.UnBrushDoc(this.props.node);}}>
{DocListCast(this.regions).map((region) => {
return <Keyframe {...this.props} RegionData={region} />;
})}