aboutsummaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
Diffstat (limited to 'src/client')
-rw-r--r--src/client/views/nodes/Keyframe.scss70
-rw-r--r--src/client/views/nodes/Keyframe.tsx142
-rw-r--r--src/client/views/nodes/Timeline.scss81
-rw-r--r--src/client/views/nodes/Timeline.tsx68
-rw-r--r--src/client/views/nodes/Track.scss4
-rw-r--r--src/client/views/nodes/Track.tsx1
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;