From 91335b57dafdeda7a1feb703b0839337fcbbfecd Mon Sep 17 00:00:00 2001 From: andrewdkim Date: Tue, 13 Aug 2019 17:26:32 -0400 Subject: timeline overview completed! --- src/client/views/animationtimeline/Keyframe.tsx | 2 + src/client/views/animationtimeline/Timeline.tsx | 77 ++++++++++++++-------- .../views/animationtimeline/TimelineOverview.scss | 24 +++++++ .../views/animationtimeline/TimelineOverview.tsx | 61 +++++++++++++++-- src/client/views/animationtimeline/Track.tsx | 1 + 5 files changed, 134 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx index dbc26e3d4..f6c04d43e 100644 --- a/src/client/views/animationtimeline/Keyframe.tsx +++ b/src/client/views/animationtimeline/Keyframe.tsx @@ -91,6 +91,8 @@ export namespace KeyframeFunc { regiondata.functions = new List(); return regiondata; }; + + } export const RegionDataSchema = createSchema({ diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 97b9ad4db..a29758694 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -1,6 +1,6 @@ import * as React from "react"; import "./Timeline.scss"; -import { CollectionSubView } from "../collections/CollectionSubView"; +import { CollectionSubView, SubCollectionViewProps } from "../collections/CollectionSubView"; import { Document, listSpec } from "../../../new_fields/Schema"; import { observer } from "mobx-react"; import { Track } from "./Track"; @@ -35,8 +35,6 @@ export interface FlyoutProps { @observer export class Timeline extends CollectionSubView(Document) { - static Instance:Timeline; - private readonly DEFAULT_CONTAINER_HEIGHT: number = 300; private readonly DEFAULT_TICK_SPACING: number = 50; @@ -53,16 +51,16 @@ export class Timeline extends CollectionSubView(Document) { @observable private _trackbox = React.createRef(); @observable private _titleContainer = React.createRef(); @observable private _timelineContainer = React.createRef(); - @observable private _timelineWrapper = React.createRef(); @observable private _infoContainer = React.createRef(); - @observable private _currentBarX: number = 0; @observable private _windSpeed: number = 1; @observable private _isPlaying: boolean = false; //scrubber playing @observable private _isFrozen: boolean = false; //timeline freeze - @observable private _boxLength: number = 0; + @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 _time = 100000; //DEFAULT @observable private _ticks: number[] = []; @@ -83,8 +81,10 @@ export class Timeline extends CollectionSubView(Document) { return Cast(this.props.Document[this.props.fieldKey], listSpec(Doc)) as List; } + componentWillMount() { this.props.Document.isAnimating ? this.props.Document.isAnimating = true : this.props.Document.isAnimating = false; + console.log(this._currentBarX); } componentDidMount() { @@ -99,11 +99,10 @@ export class Timeline extends CollectionSubView(Document) { this.changeCurrentBarX(curPage * this._tickIncrement / this._tickSpacing); }); } - } runInAction(() => { reaction(() => { - return this._time; + return this._time; }, () => { this._ticks = []; for (let i = 0; i < this._time;) { @@ -111,17 +110,22 @@ export class Timeline extends CollectionSubView(Document) { i += this._tickIncrement; } let trackbox = this._trackbox.current!; - this._boxLength = this._tickIncrement / 1000 * this._tickSpacing * this._ticks.length; - trackbox.style.width = `${this._boxLength}`; - this._scrubberbox.current!.style.width = `${this._boxLength}`; - }); + this._totalLength = this._tickSpacing * this._ticks.length; + trackbox.style.width = `${this._totalLength}`; + this._scrubberbox.current!.style.width = `${this._totalLength}`; + }, {fireImmediately:true}); + this._visibleLength = this._infoContainer.current!.getBoundingClientRect().width; + this._visibleStart = this._infoContainer.current!.scrollLeft; }); + } + + @action - changeCurrentBarX = (x: number) => { - this._currentBarX = x; + changeCurrentBarX = (pixel: number) => { + this._currentBarX = pixel; } //for playing @@ -139,10 +143,10 @@ export class Timeline extends CollectionSubView(Document) { @action changeCurrentX = () => { - if (this._currentBarX === this._boxLength && this._isPlaying) { + if (this._currentBarX === this._totalLength && this._isPlaying) { this._currentBarX = 0; } - if (this._currentBarX <= this._boxLength && this._isPlaying) { + if (this._currentBarX <= this._totalLength && this._isPlaying) { this._currentBarX = this._currentBarX + this._windSpeed; setTimeout(this.changeCurrentX, 15); } @@ -208,13 +212,18 @@ export class Timeline extends CollectionSubView(Document) { onPanMove = (e: PointerEvent) => { e.preventDefault(); e.stopPropagation(); - let infoContainer = this._infoContainer.current!; let trackbox = this._trackbox.current!; let titleContainer = this._titleContainer.current!; - infoContainer.scrollLeft = infoContainer.scrollLeft - e.movementX; + this.movePanX(this._visibleStart - e.movementX); trackbox.scrollTop = trackbox.scrollTop - e.movementY; titleContainer.scrollTop = titleContainer.scrollTop - e.movementY; } + @action + movePanX = (pixel:number) => { + let infoContainer = this._infoContainer.current!; + infoContainer.scrollLeft = pixel; + this._visibleStart = infoContainer.scrollLeft; + } @action @@ -276,7 +285,7 @@ export class Timeline extends CollectionSubView(Document) { } @action - toTime = (time: number): string => { + toReadTime = (time: number): string => { const inSeconds = time / 1000; let min: (string | number) = Math.floor(inSeconds / 60); let sec: (string | number) = inSeconds % 60; @@ -288,6 +297,23 @@ export class Timeline extends CollectionSubView(Document) { } + convertPixelTime = (pos: number, unit: "mili" | "sec" | "min" | "hr", dir: "pixel" | "time") => { + let time = dir === "pixel" ? pos / this._tickSpacing * this._tickIncrement : pos * this._tickSpacing / this._tickIncrement; + switch (unit) { + case "mili": + return time; + case "sec": + return dir === "pixel" ? time / 1000 : time * 1000; + case "min": + return dir === "pixel" ? time / 60000 : time * 60000; + case "hr": + return dir === "pixel" ? time / 3600000 : time * 3600000; + default: + return time; + } + } + + private _freezeText = "Freeze Timeline"; timelineContextMenu = (e: React.MouseEvent): void => { @@ -337,22 +363,21 @@ export class Timeline extends CollectionSubView(Document) { } render() { - - return (
-
-
-
+
+
+
+
{this._ticks.map(element => { - return

{this.toTime(element)}

; + return

{this.toReadTime(element)}

; })}
@@ -374,7 +399,7 @@ export class Timeline extends CollectionSubView(Document) {
- +
); diff --git a/src/client/views/animationtimeline/TimelineOverview.scss b/src/client/views/animationtimeline/TimelineOverview.scss index a71abf348..21988927d 100644 --- a/src/client/views/animationtimeline/TimelineOverview.scss +++ b/src/client/views/animationtimeline/TimelineOverview.scss @@ -5,9 +5,33 @@ margin-left: 20px; background: white; border: 1px solid black; + padding: 0px; + display:inline-block; .timeline-overview-visible{ height: 100%; background: green; border: 1px solid black; + margin: 0px; + } + .timeline-overview-scrubber-container{ + height: 100%; + margin-top: -40px; + margin-left: 0px; + width: 2px; + z-index: 1001; + background-color:black; + display: inline-block; + .timeline-overview-scrubber-head{ + position:absolute; + height: 30px; + width: 30px; + background-color:transparent; + border-radius: 50%; + border: 5px solid black; + margin-left: -15px; + top: -15px; + + } + } } \ No newline at end of file diff --git a/src/client/views/animationtimeline/TimelineOverview.tsx b/src/client/views/animationtimeline/TimelineOverview.tsx index 0e10e655d..1ad7d20e5 100644 --- a/src/client/views/animationtimeline/TimelineOverview.tsx +++ b/src/client/views/animationtimeline/TimelineOverview.tsx @@ -1,5 +1,5 @@ import * as React from "react"; -import {observable} from "mobx"; +import {observable, action} from "mobx"; import {observer} from "mobx-react"; import "./TimelineOverview.scss"; @@ -9,20 +9,71 @@ interface TimelineOverviewProps{ totalLength: number; visibleLength:number; visibleStart:number; - changeCurrentBarX: (x:number) => any; + currentBarX:number; + changeCurrentBarX: (pixel:number) => void; + movePanX: (pixel:number) => any; } +@observer export class TimelineOverview extends React.Component{ + @observable private _visibleRef = React.createRef(); + @observable private _scrubberRef = React.createRef(); + + @action + onPointerDown = (e:React.PointerEvent) => { + document.removeEventListener("pointermove", this.onPanX); + document.removeEventListener("pointerup", this.onPointerUp); + document.addEventListener("pointermove", this.onPanX); + document.addEventListener("pointerup", this.onPointerUp); + } + + @action + onPanX = (e: PointerEvent) => { + let movX = (this.props.visibleStart / this.props.totalLength)* 300 + e.movementX; + this.props.movePanX((movX / 300) * this.props.totalLength); + } + + @action + onPointerUp = (e: PointerEvent) => { + document.removeEventListener("pointermove", this.onPanX); + document.removeEventListener("pointerup", this.onPointerUp); + } + @action + onScrubberDown = ( e:React.PointerEvent) => { + e.preventDefault(); + e.stopPropagation(); + document.removeEventListener("pointermove", this.onScrubberMove); + document.removeEventListener("pointerup", this.onScrubberUp); + document.addEventListener("pointermove", this.onScrubberMove); + document.addEventListener("pointerup", this.onScrubberUp); + } + + @action + onScrubberMove = (e: PointerEvent) => { + e.preventDefault(); + e.stopPropagation(); + let scrubberRef = this._scrubberRef.current!; + let left = scrubberRef.getBoundingClientRect().left; + let offsetX = Math.round(e.clientX - left); + this.props.changeCurrentBarX(((offsetX / 300) * this.props.totalLength) + this.props.currentBarX); + } + + @action + onScrubberUp = (e:PointerEvent) => { + e.preventDefault(); + e.stopPropagation(); + document.removeEventListener("pointermove", this.onScrubberMove); + document.removeEventListener("pointerup", this.onScrubberUp); + } render(){ return(
-
-
+
+
-
); diff --git a/src/client/views/animationtimeline/Track.tsx b/src/client/views/animationtimeline/Track.tsx index 64e94f0f1..6bdabeb93 100644 --- a/src/client/views/animationtimeline/Track.tsx +++ b/src/client/views/animationtimeline/Track.tsx @@ -94,6 +94,7 @@ export class Track extends React.Component { this.props.node.hidden = false; await this.timeChange(this.props.currentBarX); } else { + console.log("heuulloo"); this.props.node.hidden = true; } }, { fireImmediately: true }); -- cgit v1.2.3-70-g09d2