From 3143c2775cdf7bdafa44f047ea9b6ebbd090b28e Mon Sep 17 00:00:00 2001 From: andrewdkim Date: Sat, 5 Oct 2019 17:26:10 -0400 Subject: animation --- src/client/views/animationtimeline/Timeline.scss | 1 + src/client/views/animationtimeline/Timeline.tsx | 251 ++++++++++++----------- 2 files changed, 131 insertions(+), 121 deletions(-) (limited to 'src') diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index 71fac876d..fbdb2a200 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -20,6 +20,7 @@ position:absolute; background-color: $light-color-secondary; box-shadow: 0px 10px 20px; + transition: transform 500ms ease; .info-container{ margin-top: 80px; diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index bc48f422a..8a41a5943 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -29,25 +29,25 @@ export class Timeline extends React.Component { @observable private _titleContainer = React.createRef(); @observable private _timelineContainer = React.createRef(); @observable private _infoContainer = React.createRef(); - @observable private _roundToggleRef = React.createRef(); - @observable private _roundToggleContainerRef = React.createRef(); + @observable private _roundToggleRef = React.createRef(); + @observable private _roundToggleContainerRef = React.createRef(); @observable private _currentBarX: number = 0; @observable private _windSpeed: number = 1; @observable private _isPlaying: boolean = false; //scrubber playing @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 _visibleLength: number = 0; + @observable private _visibleStart: number = 0; + @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; - @observable private _timelineVisible = false; - @observable private _mouseToggled = false; - @observable private _doubleClickEnabled = false; - @observable private _reactionDisposer:IReactionDisposer[] = []; + @observable private _playButton = faPlayCircle; + @observable private _timelineVisible = false; + @observable private _mouseToggled = false; + @observable private _doubleClickEnabled = false; + @observable private _reactionDisposer: IReactionDisposer[] = []; @computed @@ -65,7 +65,7 @@ export class Timeline extends React.Component { componentWillMount() { - this.props.Document.isAnimating ? this.props.Document.isAnimating = true : this.props.Document.isAnimating = false; + this.props.Document.isAnimating ? this.props.Document.isAnimating = true : this.props.Document.isAnimating = false; } componentDidMount() { @@ -78,29 +78,29 @@ export class Timeline extends React.Component { return NumCast(this.props.Document.curPage); }, curPage => { if (!this._isPlaying) { - this.changeCurrentBarX(curPage * this._tickIncrement / this._tickSpacing); - this.props.Document.curPage = this._currentBarX; - this.play(); + this.changeCurrentBarX(curPage * this._tickIncrement / this._tickSpacing); + this.props.Document.curPage = this._currentBarX; + this.play(); } })); } } runInAction(() => { this._reactionDisposer.push(reaction(() => { - return this._time; + return this._time; }, () => { this._ticks = []; for (let i = 0; i < this._time;) { this._ticks.push(i); i += 1000; } - this._totalLength = this._tickSpacing * (this._time/ this._tickIncrement); - }, {fireImmediately:true})); - this._totalLength = this._tickSpacing * (this._ticks.length/ this._tickIncrement); - this._visibleLength = this._infoContainer.current!.getBoundingClientRect().width; - this._visibleStart = this._infoContainer.current!.scrollLeft; + this._totalLength = this._tickSpacing * (this._time / this._tickIncrement); + }, { fireImmediately: true })); + this._totalLength = this._tickSpacing * (this._ticks.length / this._tickIncrement); + this._visibleLength = this._infoContainer.current!.getBoundingClientRect().width; + this._visibleStart = this._infoContainer.current!.scrollLeft; }); - + } @@ -112,30 +112,30 @@ export class Timeline extends React.Component { //for playing @action onPlay = (e: React.MouseEvent) => { - e.preventDefault(); - e.stopPropagation(); - this.play(); + e.preventDefault(); + e.stopPropagation(); + this.play(); } @action play = () => { if (this._isPlaying) { this._isPlaying = false; - this._playButton = faPlayCircle; + this._playButton = faPlayCircle; } else { this._isPlaying = true; - this._playButton = faPauseCircle; + this._playButton = faPauseCircle; const playTimeline = () => { - if (this._isPlaying){ + if (this._isPlaying) { if (this._currentBarX >= this._totalLength) { - this.changeCurrentBarX(0); + this.changeCurrentBarX(0); } else { this.changeCurrentBarX(this._currentBarX + this._windSpeed); - } - setTimeout(playTimeline, 15); + } + setTimeout(playTimeline, 15); } - }; - playTimeline(); + }; + playTimeline(); } } @@ -143,8 +143,8 @@ export class Timeline extends React.Component { @action windForward = (e: React.MouseEvent) => { - e.preventDefault(); - e.stopPropagation(); + e.preventDefault(); + e.stopPropagation(); if (this._windSpeed < 64) { //max speed is 32 this._windSpeed = this._windSpeed * 2; } @@ -152,8 +152,8 @@ export class Timeline extends React.Component { @action windBackward = (e: React.MouseEvent) => { - e.preventDefault(); - e.stopPropagation(); + e.preventDefault(); + e.stopPropagation(); if (this._windSpeed > 1 / 16) { // min speed is 1/8 this._windSpeed = this._windSpeed / 2; } @@ -177,7 +177,7 @@ export class Timeline extends React.Component { let scrubberbox = this._scrubberbox.current!; let left = scrubberbox.getBoundingClientRect().left; let offsetX = Math.round(e.clientX - left) * this.props.ScreenToLocalTransform().Scale; - this.changeCurrentBarX(offsetX); + this.changeCurrentBarX(offsetX); } @action @@ -186,7 +186,7 @@ export class Timeline extends React.Component { e.stopPropagation(); let scrubberbox = this._scrubberbox.current!; let offsetX = (e.clientX - scrubberbox.getBoundingClientRect().left) * this.props.ScreenToLocalTransform().Scale; - this.changeCurrentBarX(offsetX); + this.changeCurrentBarX(offsetX); } @@ -195,19 +195,21 @@ export class Timeline extends React.Component { onPanDown = (e: React.PointerEvent) => { e.preventDefault(); e.stopPropagation(); - let clientX = e.clientX; - if (this._doubleClickEnabled){ - this._doubleClickEnabled = false; + let clientX = e.clientX; + if (this._doubleClickEnabled) { + this._doubleClickEnabled = false; } else { - setTimeout(() => {if(!this._mouseToggled && this._doubleClickEnabled) this.changeCurrentBarX(this._trackbox.current!.scrollLeft + clientX - this._trackbox.current!.getBoundingClientRect().left); + setTimeout(() => { + if (!this._mouseToggled && this._doubleClickEnabled) this.changeCurrentBarX(this._trackbox.current!.scrollLeft + clientX - this._trackbox.current!.getBoundingClientRect().left); this._mouseToggled = false; - this._doubleClickEnabled = false;}, 200); - this._doubleClickEnabled = true; + this._doubleClickEnabled = false; + }, 200); + this._doubleClickEnabled = true; document.addEventListener("pointermove", this.onPanMove); document.addEventListener("pointerup", () => { document.removeEventListener("pointermove", this.onPanMove); if (!this._doubleClickEnabled) { - this._mouseToggled = false; + this._mouseToggled = false; } }); @@ -219,7 +221,7 @@ export class Timeline extends React.Component { e.preventDefault(); e.stopPropagation(); if (e.movementX !== 0 || e.movementY !== 0) { - this._mouseToggled = true; + this._mouseToggled = true; } let trackbox = this._trackbox.current!; let titleContainer = this._titleContainer.current!; @@ -227,10 +229,10 @@ export class Timeline extends React.Component { trackbox.scrollTop = trackbox.scrollTop - e.movementY; titleContainer.scrollTop = titleContainer.scrollTop - e.movementY; } - @action - movePanX = (pixel:number) => { + @action + movePanX = (pixel: number) => { let infoContainer = this._infoContainer.current!; - infoContainer.scrollLeft = pixel; + infoContainer.scrollLeft = pixel; this._visibleStart = infoContainer.scrollLeft; } @@ -273,131 +275,138 @@ export class Timeline extends React.Component { return `${min}:${sec}`; } - timelineContextMenu = (e:MouseEvent): void => { + timelineContextMenu = (e: MouseEvent): void => { let subitems: ContextMenuProps[] = []; subitems.push({ description: this._timelineVisible ? "Hide Timeline" : "Show Timeline", event: action(() => { - this._timelineVisible = !this._timelineVisible; + this._timelineVisible = !this._timelineVisible; }), icon: this._timelineVisible ? faEyeSlash : "eye" - }); - subitems.push({ description: BoolCast(this.props.Document.isAnimating) ? "Enter Play Mode" : "Enter Authoring Mode", event: () => { - BoolCast(this.props.Document.isAnimating) ? this.props.Document.isAnimating = false : this.props.Document.isAnimating = true;} - , icon:BoolCast(this.props.Document.isAnimating) ? "play" : "edit"}); + }); + subitems.push({ + description: BoolCast(this.props.Document.isAnimating) ? "Enter Play Mode" : "Enter Authoring Mode", event: () => { + BoolCast(this.props.Document.isAnimating) ? this.props.Document.isAnimating = false : this.props.Document.isAnimating = true; + } + , icon: BoolCast(this.props.Document.isAnimating) ? "play" : "edit" + }); ContextMenu.Instance.addItem({ description: "Timeline Funcs...", subitems: subitems, icon: faClock }); } @action onWheelZoom = (e: React.WheelEvent) => { - e.preventDefault(); - e.stopPropagation(); - let offset = e.clientX - this._infoContainer.current!.getBoundingClientRect().left; + e.preventDefault(); + e.stopPropagation(); + let offset = e.clientX - this._infoContainer.current!.getBoundingClientRect().left; let prevTime = KeyframeFunc.convertPixelTime(this._visibleStart + offset, "mili", "time", this._tickSpacing, this._tickIncrement); - let prevCurrent = KeyframeFunc.convertPixelTime(this._currentBarX,"mili", "time", this._tickSpacing, this._tickIncrement); - e.deltaY < 0 ? this.zoom(true) : this.zoom(false); - 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; + let prevCurrent = KeyframeFunc.convertPixelTime(this._currentBarX, "mili", "time", this._tickSpacing, this._tickIncrement); + e.deltaY < 0 ? this.zoom(true) : this.zoom(false); + 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 > 0 ? currPixel - offset : 0; - this._visibleStart += this._visibleLength + this._visibleStart > this._totalLength ? this._totalLength - (this._visibleStart + this._visibleLength) :0; - this.changeCurrentBarX(currCurrent); + this._visibleStart += this._visibleLength + this._visibleStart > this._totalLength ? this._totalLength - (this._visibleStart + this._visibleLength) : 0; + this.changeCurrentBarX(currCurrent); } @action zoom = (dir: boolean) => { - let spacingChange = this._tickSpacing; - let incrementChange = this._tickIncrement; - if (dir){ - if (!(this._tickSpacing === 100 && this._tickIncrement === 1000)){ + let spacingChange = this._tickSpacing; + let incrementChange = this._tickIncrement; + if (dir) { + if (!(this._tickSpacing === 100 && this._tickIncrement === 1000)) { if (this._tickSpacing >= 100) { - incrementChange /= 2; - spacingChange = 50; + incrementChange /= 2; + spacingChange = 50; } else { - spacingChange += 5; + spacingChange += 5; } - } + } } else { if (this._tickSpacing <= 50) { - spacingChange = 100; - incrementChange *= 2; + spacingChange = 100; + incrementChange *= 2; } else { - spacingChange -= 5; + spacingChange -= 5; } } - let finalLength = spacingChange * (this._time / incrementChange); - if (finalLength >= this._infoContainer.current!.getBoundingClientRect().width){ - this._totalLength = finalLength; - this._tickSpacing = spacingChange; - this._tickIncrement = incrementChange; + let finalLength = spacingChange * (this._time / incrementChange); + if (finalLength >= this._infoContainer.current!.getBoundingClientRect().width) { + this._totalLength = finalLength; + this._tickSpacing = spacingChange; + this._tickIncrement = incrementChange; } } - private timelineToolBox = (scale:number) => { + private timelineToolBox = (scale: number) => { let size = 50 * scale; //50 is default - return ( - -
-
-
-
- -
-
+ return ( + +
+
+
+
+ +
+
+
-
); } @action - private toggleChecked = (e:React.PointerEvent) => { - e.preventDefault(); - e.stopPropagation(); - let roundToggle = this._roundToggleRef.current!; - let roundToggleContainer = this._roundToggleContainerRef.current!; - let timelineContainer = this._timelineContainer.current!; - if (BoolCast(this.props.Document.isAnimating)){ + private toggleChecked = (e: React.PointerEvent) => { + e.preventDefault(); + e.stopPropagation(); + let roundToggle = this._roundToggleRef.current!; + let roundToggleContainer = this._roundToggleContainerRef.current!; + let timelineContainer = this._timelineContainer.current!; + if (BoolCast(this.props.Document.isAnimating)) { + roundToggle.style.transform = "translate(0px, 0px)"; - roundToggle.style.animationName = "turnoff"; - roundToggleContainer.style.animationName = "turnoff"; - timelineContainer.style.transform = `translate(0px, ${this._containerHeight}px)`; - this.props.Document.isAnimating = false; + roundToggle.style.animationName = "turnoff"; + roundToggleContainer.style.animationName = "turnoff"; + timelineContainer.style.transform = `translate(0px, ${0}px)`; + setTimeout(() => { + this.props.Document.isAnimating = false; + }, 500); } else { - roundToggle.style.transform = "translate(45px, 0px)"; - roundToggle.style.animationName = "turnon"; - roundToggleContainer.style.animationName = "turnon"; - timelineContainer.style.transform = `translate(0px, ${-this._containerHeight}px)`; - this.props.Document.isAnimating = true; + roundToggle.style.transform = "translate(45px, 0px)"; + roundToggle.style.animationName = "turnon"; + roundToggleContainer.style.animationName = "turnon"; + timelineContainer.style.transform = `translate(0px, ${this._containerHeight}px)`; + this.props.Document.isAnimating = true; + } } render() { return (
-
-
-
-
-
+
+
+
+
+
{this._ticks.map(element => { - if(element % this._tickIncrement === 0) return

{this.toReadTime(element)}

; + if (element % this._tickIncrement === 0) return

{this.toReadTime(element)}

; })}
-
- {DocListCast(this.children).map(doc => )} +
+ {DocListCast(this.children).map(doc => )}
-
- {DocListCast(this.children).map(doc =>
{Doc.BrushDoc(doc);}} onPointerOut={() => {Doc.UnBrushDoc(doc);}}>

{doc.title}

)} +
+ {DocListCast(this.children).map(doc =>
{ Doc.BrushDoc(doc); }} onPointerOut={() => { Doc.UnBrushDoc(doc); }}>

{doc.title}

)}
- +
- { this.timelineToolBox(1) } + {this.timelineToolBox(1)}
- +
); -- cgit v1.2.3-70-g09d2