diff options
author | andrewdkim <adkim414@gmail.com> | 2019-10-05 17:26:10 -0400 |
---|---|---|
committer | andrewdkim <adkim414@gmail.com> | 2019-10-05 17:26:10 -0400 |
commit | 3143c2775cdf7bdafa44f047ea9b6ebbd090b28e (patch) | |
tree | 923b481d26813a45b193567557981a5be08126b7 /src/client/views/animationtimeline/Timeline.tsx | |
parent | e763a0e825a547c34f50915204be586afcd55b18 (diff) |
animation
Diffstat (limited to 'src/client/views/animationtimeline/Timeline.tsx')
-rw-r--r-- | src/client/views/animationtimeline/Timeline.tsx | 251 |
1 files changed, 130 insertions, 121 deletions
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<FieldViewProps> { @observable private _titleContainer = React.createRef<HTMLDivElement>(); @observable private _timelineContainer = React.createRef<HTMLDivElement>(); @observable private _infoContainer = React.createRef<HTMLDivElement>(); - @observable private _roundToggleRef = React.createRef<HTMLDivElement>(); - @observable private _roundToggleContainerRef = 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 _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<FieldViewProps> { 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<FieldViewProps> { 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<FieldViewProps> { //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<FieldViewProps> { @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<FieldViewProps> { @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<FieldViewProps> { 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<FieldViewProps> { 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<FieldViewProps> { 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<FieldViewProps> { 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<FieldViewProps> { 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<FieldViewProps> { 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 ( - - <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 ref={this._roundToggleContainerRef}key="round-toggle" className="round-toggle"> - <div ref={this._roundToggleRef} className="round-toggle-slider" onPointerDown = {this.toggleChecked}> </div> + 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 ref={this._roundToggleContainerRef} key="round-toggle" className="round-toggle"> + <div ref={this._roundToggleRef} className="round-toggle-slider" onPointerDown={this.toggleChecked}> </div> + </div> </div> - </div> ); } @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 ( <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`, top:`${-this._containerHeight}`}}> - <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}> + <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`, top: `-${this._containerHeight}px` }}> + <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>; + 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 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_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 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_resize" onPointerDown={this.onResizeDown}> - <FontAwesomeIcon className="resize" icon={faGripLines}/> + <FontAwesomeIcon className="resize" icon={faGripLines} /> </div> </div> </div> - { this.timelineToolBox(1) } + {this.timelineToolBox(1)} </div> - + </div> ); |