diff options
Diffstat (limited to 'src/client')
-rw-r--r-- | src/client/views/nodes/Keyframe.scss | 70 | ||||
-rw-r--r-- | src/client/views/nodes/Keyframe.tsx | 142 | ||||
-rw-r--r-- | src/client/views/nodes/Timeline.scss | 81 | ||||
-rw-r--r-- | src/client/views/nodes/Timeline.tsx | 68 | ||||
-rw-r--r-- | src/client/views/nodes/Track.scss | 4 | ||||
-rw-r--r-- | src/client/views/nodes/Track.tsx | 1 |
6 files changed, 221 insertions, 145 deletions
diff --git a/src/client/views/nodes/Keyframe.scss b/src/client/views/nodes/Keyframe.scss index afc16e3c0..b3a950afa 100644 --- a/src/client/views/nodes/Keyframe.scss +++ b/src/client/views/nodes/Keyframe.scss @@ -3,13 +3,13 @@ .bar { height: 100%; width: 5px; - background-color: green; - position: relative; + background-color: #4d9900; + position: absolute; // pointer-events: none; .menubox { width: 200px; - height: 200px; + height:200px; top: 50%; position: relative; background-color: $light-color; @@ -21,25 +21,63 @@ } .leftResize{ - left:-10px; - height:20px; - width:20px; + left:-12.5px; + height:25px; + width:25px; border-radius: 50%; - border: 1px black; - background-color: transparent; - top: calc(50% - 10px); + background-color: white; + border:3px solid black; + top: calc(50% - 12.5px); + z-index: 1000; position:absolute; } .rightResize{ - right:-10px; - height:20px; - width:20px; + right:-12.5px; + height:25px; + width:25px; border-radius: 50%; - top:calc(50% - 10px); - background-color:black; + top:calc(50% - 12.5px); + background-color:white; + border:3px solid black; + z-index: 1000; position:absolute; - + } + .fadeLeft{ + left:0px; + height:100%; + position:absolute; + pointer-events: none; + background: linear-gradient(to left, #4d9900 10%, $light-color); } + .fadeRight{ + right:0px; + height:100%; + position:absolute; + pointer-events: none; + background: linear-gradient(to right, #4d9900 10%, $light-color); + } + .divider{ + height:100%; + width: 1px; + position: absolute; + background-color:black; + cursor: col-resize; + } + .keyframe{ + height:100%; + position:absolute; + } + .keyframeCircle{ + left:-15px; + height:30px; + width:30px; + border-radius: 50%; + top:calc(50% - 15px); + background-color:white; + border:3px solid green; + z-index: 1000; + position:absolute; + } -}
\ No newline at end of file +} diff --git a/src/client/views/nodes/Keyframe.tsx b/src/client/views/nodes/Keyframe.tsx index b3dd251f9..7f4f9ab3b 100644 --- a/src/client/views/nodes/Keyframe.tsx +++ b/src/client/views/nodes/Keyframe.tsx @@ -31,6 +31,8 @@ export class Keyframe extends React.Component<IProp> { @observable private _bar = React.createRef<HTMLDivElement>(); @observable private _data:Doc = new Doc(); @observable private _position:number = 0; + @observable private _keyframes:number[] = []; + @action @@ -41,87 +43,82 @@ export class Keyframe extends React.Component<IProp> { this._data.duration = 200; this._data.start = this._position - (this._duration/2); this._data.end = this._position + (this._duration/2); - - } componentWillUnmount() { } - @action - onPointerEnter = (e: React.PointerEvent) => { - e.preventDefault(); - e.stopPropagation(); - //this._display = "block"; - } - - @action - onPointerOut = (e: React.PointerEvent) => { - e.preventDefault(); - e.stopPropagation(); - //this._display = "none"; - } + // @action + // onPointerEnter = (e: React.PointerEvent) => { + // e.preventDefault(); + // e.stopPropagation(); + // //this._display = "block"; + // } + + // @action + // onPointerOut = (e: React.PointerEvent) => { + // e.preventDefault(); + // e.stopPropagation(); + // //this._display = "none"; + // } @action onBarPointerDown = (e: React.PointerEvent) => { - console.log(e.clientX); - this._position = e.clientX; - } - - @action - onKeyDown = (e: React.KeyboardEvent) => { e.preventDefault(); e.stopPropagation(); - console.log("pressed"); - if (e.keyCode === 13){ - console.log("hellow"); - } + document.addEventListener("pointermove", this.onBarPointerMove); + document.addEventListener("pointerup", (e:PointerEvent) => { + document.removeEventListener("pointermove", this.onBarPointerMove); + }); } @action - onPointerDown = (e:React.PointerEvent) => { + onBarPointerMove = (e:PointerEvent) => { e.preventDefault(); e.stopPropagation(); + if (this._position >= 0){ + let futureX = this._position + e.movementX; + if (futureX <= 0){ + this._position = 0; + } else{ + this._position += e.movementX; + } + } } @action onResizeLeft = (e:React.PointerEvent)=>{ e.preventDefault(); - let bar = this._bar.current!; + e.stopPropagation(); document.addEventListener("pointermove", this.onDragResizeLeft); + document.addEventListener("pointerup", ()=>{ + document.removeEventListener("pointermove", this.onDragResizeLeft); + }); } @action - onDragResizeLeft = (e:PointerEvent)=>{ + onResizeRight = (e:React.PointerEvent)=> { e.preventDefault(); - e.stopPropagation(); - console.log("Dragging"); - let bar = this._bar.current!; - let barX = bar.getBoundingClientRect().left; - let offset = barX - e.clientX; - bar.style.width = `${bar.getBoundingClientRect().width + offset}px`; - bar.style.transform = `translate(${e.clientX})`; - document.addEventListener("pointerup", this.onResizeFinished); + e.stopPropagation(); + document.addEventListener("pointermove", this.onDragResizeRight); + document.addEventListener("pointerup", ()=>{ + document.removeEventListener("pointermove", this.onDragResizeRight); + }); } @action - onResizeFinished =(e:PointerEvent) => { + onDragResizeLeft = (e:PointerEvent)=>{ e.preventDefault(); - e.stopPropagation(); - let bar = this._bar.current!; - document.removeEventListener("pointermove", this.onDragResizeLeft); - document.removeEventListener("pointermove", this.onDragResizeRight); + e.stopPropagation(); + let bar = this._bar.current!; + let barX = bar.getBoundingClientRect().left; + let offset = e.clientX - barX; + this._duration -= offset; + this._position += offset; } - @action - onResizeRight = (e:React.PointerEvent)=> { - e.preventDefault(); - e.stopPropagation(); - let bar = this._bar.current!; - document.addEventListener("pointermove", this.onDragResizeRight); - } - + @action onDragResizeRight = (e:PointerEvent) => { e.preventDefault(); @@ -129,35 +126,42 @@ export class Keyframe extends React.Component<IProp> { let bar = this._bar.current!; let barX = bar.getBoundingClientRect().right; let offset = e.clientX - barX; - bar.style.width = `${bar.getBoundingClientRect().width + offset}px`; - document.addEventListener("pointerup", this.onResizeFinished); + console.log(offset); + this._duration += offset; } - @action - onResizeOut = (e:React.PointerEvent)=>{ - let bar = this._bar.current!; - document.addEventListener("pointerup", this.onDragResizeRight); + createDivider = (type?: string):JSX.Element => { + if (type === "left"){ + return <div className="divider" style={{right:"0px"}}></div>; + } else if (type === "right"){ + return <div className="divider" style={{left:"0px"}}> </div>; + } + return <div className="divider"></div>; } - - @action - changeFlyoutContent = () => { - - } - @action - onHover = (e:React.PointerEvent) => { - + createKeyframe = (e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + let mouse = e.nativeEvent; + this._keyframes.push(mouse.offsetX); } - + render() { return ( <div> - <div className="bar" ref={this._bar} style={{ transform: `translate(${this._position - (this._duration/2)}px)`, width:`${this._duration}px`}} onPointerDown={this.onBarPointerDown}> - <div className="leftResize" onPointerDown={this.onResizeLeft} ></div> - <div className="rightResize" onPointerDown={this.onResizeRight} onPointerOut={this.onResizeOut}></div> - <div className="menubox" style={{display: this._display}}> - </div> + <div className="bar" ref={this._bar} style={{ transform: `translate(${this._position}px)`, width:`${this._duration}px`}} onPointerDown={this.onBarPointerDown} onDoubleClick={this.createKeyframe}> + <div className="leftResize" onPointerDown={this.onResizeLeft} ></div> + <div className="rightResize" onPointerDown={this.onResizeRight}></div> + {/* <div className="menubox" style={{display: this._display}}></div> */} + <div className="fadeLeft" style={{width:`${20}px`}}>{this.createDivider("left")}</div> + <div className="fadeRight" style={{width:`${20}px`}}>{this.createDivider("right")}</div> + {this._keyframes.map(kf => {return <div className="keyframe" style={{left: `${kf}px`}}> + {this.createDivider()} + <div className="keyframeCircle"></div> + </div>})} + {this.createDivider("left")} + {this.createDivider("right")} </div> </div> ); diff --git a/src/client/views/nodes/Timeline.scss b/src/client/views/nodes/Timeline.scss index 4b35dcbe9..36f51edf2 100644 --- a/src/client/views/nodes/Timeline.scss +++ b/src/client/views/nodes/Timeline.scss @@ -12,49 +12,52 @@ display:inline-block; } } - .scrubberbox{ + .info-container{ + top: 10px; + margin-left: 10%; position:relative; - background-color: transparent; - height: 30px; - margin-left:calc(10% + 100px); - width: calc(80% - 100px); - overflow-x: scroll; - overflow-y: visible; - .tick{ - height:100%; - width: 1px; - background-color:black; + height: 80%; + width: 80%; + overflow-x: hidden; + + .scrubberbox{ + position:relative; + background-color: transparent; + height: 30px; + width:100%; + + .tick{ + height:100%; + width: 1px; + background-color:black; + } } - - } - .scrubberbox::-webkit-scrollbar{ - display:none; - } - .scrubber{ - margin-left:calc(10% + 100px); - height: 100px; - width: 2px; - position:absolute; - z-index: 1001; - - background-color:black ; - .scrubberhead{ - height: 30px; - width: 30px; - left: -15px; - top: -30px; - position:absolute; + .scrubber{ + height: 100px; + width: 2px; + position:absolute; + z-index: 1001; + background-color:black ; + .scrubberhead{ + height: 30px; + width: 30px; + left: -15px; + //top: -40px; + position:absolute; + } } - } - .trackbox{ - height:60%; - width:80%; - border:1px; - overflow:auto; - background-color:white; - margin-Left:10%; - position:absolute; + .trackbox{ + top: 30px; + height:calc(100%); + width:100%; + border:1px; + overflow:auto; + background-color:white; + position:absolute; + + } } + }
\ No newline at end of file diff --git a/src/client/views/nodes/Timeline.tsx b/src/client/views/nodes/Timeline.tsx index c0f34ace5..90907861f 100644 --- a/src/client/views/nodes/Timeline.tsx +++ b/src/client/views/nodes/Timeline.tsx @@ -13,6 +13,7 @@ import { Self } from "../../../new_fields/FieldSymbols"; import { Doc, DocListCast } from "../../../new_fields/Doc"; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faCircle, faPlayCircle, faBackward, faForward } from "@fortawesome/free-solid-svg-icons"; +import { DocumentContentsView } from "./DocumentContentsView"; @@ -20,6 +21,7 @@ import { faCircle, faPlayCircle, faBackward, faForward } from "@fortawesome/free export class Timeline extends CollectionSubView(Document){ @observable private _scrubberbox = React.createRef<HTMLDivElement>() + @observable private _trackbox = React.createRef<HTMLDivElement>(); @observable private _currentBarX:number = 0; @observable private _windSpeed:number = 1; @observable private _isPlaying:boolean = false; @@ -27,6 +29,8 @@ export class Timeline extends CollectionSubView(Document){ @observable private _nodes:List<Doc> = new List<Doc>(); @observable private _time = 100000; //DEFAULT + @observable private _infoContainer = React.createRef<HTMLDivElement>(); + @observable private _panX = 0; @observable private _ticks: number[] = []; private _reactionDisposers: IReactionDisposer[] = []; @@ -50,16 +54,19 @@ export class Timeline extends CollectionSubView(Document){ this._ticks.push(i); i += 1000; } - + } + + componentDidUpdate(){ + let infoContainer = this._infoContainer.current!; + let trackbox = this._trackbox.current!; + this._boxLength = infoContainer.scrollWidth; + trackbox.style.width = `${this._boxLength}`; } componentWillUnmount(){ } - - - //for playing @action onPlay = async (e: React.MouseEvent) => { @@ -72,8 +79,10 @@ export class Timeline extends CollectionSubView(Document){ } @action - changeCurrentX = () => { - if (this._currentBarX >= this._boxLength && this._isPlaying) { + changeCurrentX = () => { + console.log(this._currentBarX); + console.log(this._boxLength); + if (this._currentBarX === this._boxLength && this._isPlaying) { this._currentBarX = 0; } if (this._currentBarX <= this._boxLength && this._isPlaying) { @@ -109,7 +118,7 @@ export class Timeline extends CollectionSubView(Document){ this._currentBarX = mouse.offsetX; document.addEventListener("pointermove", this.onScrubberMove); document.addEventListener("pointerup", this.onScrubberFinished); - } + } @action onScrubberMove = (e: PointerEvent) => { @@ -125,7 +134,7 @@ export class Timeline extends CollectionSubView(Document){ e.preventDefault(); e.stopPropagation(); let scrubberbox = this._scrubberbox.current!; - document.removeEventListener("pointermove", this.onScrubberMove); + document.removeEventListener("pointermove", this.onScrubberMove); } toTime = (time:number):string => { @@ -141,6 +150,29 @@ export class Timeline extends CollectionSubView(Document){ } + @action + onPanDown = (e:React.PointerEvent) => { + e.preventDefault(); + e.stopPropagation(); + document.addEventListener("pointermove", this.onPanMove); + document.addEventListener("pointerup", this.onPanUp); + } + + @action + onPanMove = (e:PointerEvent) => { + e.preventDefault(); + e.stopPropagation(); + let infoContainer = this._infoContainer.current!; + infoContainer.scrollLeft = infoContainer.scrollLeft - e.movementX; + } + + @action + onPanUp = (e:PointerEvent) => { + e.preventDefault(); + e.stopPropagation(); + document.removeEventListener("pointermove", this.onPanMove); + } + render(){ return ( <div className="timeline-container"> @@ -149,17 +181,17 @@ export class Timeline extends CollectionSubView(Document){ <div onClick={this.onPlay}> <FontAwesomeIcon icon={faPlayCircle} size="lg"/> </div> <div onClick={this.windForward}> <FontAwesomeIcon icon={faForward} size="lg"/> </div> </div> - <div></div> - <div className="scrubberbox" ref ={this._scrubberbox}> - {this._ticks.map(element => {return <div className="tick" style={{transform:`translate(${element / 20}px)`, position:"absolute"}}> <p>{this.toTime(element)}</p></div>})} - - </div> - <div className="scrubber" onPointerDown = {this.onScrubberDown} style={{transform:`translate(${this._currentBarX}px)`}}> - <FontAwesomeIcon className="scrubberhead" icon={faCircle}/>; + <div className="info-container" ref ={this._infoContainer} onPointerDown={this.onPanDown}> + <div className="scrubberbox" ref ={this._scrubberbox}> + {this._ticks.map(element => {return <div className="tick" style={{transform:`translate(${element / 20}px)`, position:"absolute"}}> <p>{this.toTime(element)}</p></div>})} + </div> + <div className="scrubber" onPointerDown = {this.onScrubberDown} style={{transform:`translate(${this._currentBarX}px)`}}> + <FontAwesomeIcon className="scrubberhead" icon={faCircle}/>; + </div> + <div className="trackbox" ref={this._trackbox}> + {this._nodes.map(doc => {return <Track node={(doc as any).value() as Doc}/>;})} + </div> </div> - <div className="trackbox"> - {this._nodes.map(doc => {return <Track node={(doc as any).value() as Doc}/>;})} - </div> </div> ); } diff --git a/src/client/views/nodes/Track.scss b/src/client/views/nodes/Track.scss index e922aa1df..74dc7b5a7 100644 --- a/src/client/views/nodes/Track.scss +++ b/src/client/views/nodes/Track.scss @@ -5,7 +5,7 @@ .datapane{ top:0px; width: 100px; - height: 100px; + height: 75px; background-color: $light-color-secondary; position:relative; float:left; @@ -16,7 +16,7 @@ .inner { top:0px; float:right; - height: 100px; + height: 75px; width: calc(100% - 100px); background-color: $light-color; border-style:solid; diff --git a/src/client/views/nodes/Track.tsx b/src/client/views/nodes/Track.tsx index d7ef68f70..a4c12c996 100644 --- a/src/client/views/nodes/Track.tsx +++ b/src/client/views/nodes/Track.tsx @@ -362,7 +362,6 @@ export class Track extends React.Component<props> { onInnerPointerDown = (e:React.PointerEvent) => { e.preventDefault(); e.stopPropagation(); - console.log("on timeline"); if (this._inner.current) { this._barMoved = true; // let mouse = e.nativeEvent; |