From bf3d45f8a16d23384a308f65adfa9a2baee495af Mon Sep 17 00:00:00 2001 From: andrewdkim Date: Thu, 1 Aug 2019 17:00:10 -0400 Subject: prosemirror --- src/client/views/animationtimeline/Timeline.scss | 170 +++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 src/client/views/animationtimeline/Timeline.scss (limited to 'src/client/views/animationtimeline/Timeline.scss') diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss new file mode 100644 index 000000000..47f448adb --- /dev/null +++ b/src/client/views/animationtimeline/Timeline.scss @@ -0,0 +1,170 @@ +@import "./../globalCssVariables.scss"; + +.minimize{ + position:relative; + z-index: 1000; + height: 30px; + width: 100px; +} +.flyout-container{ + background-color: transparent; + position:absolute; + + z-index:9999; + height: 150px; + width: 150px; + + .flyout{ + background-color: transparent; + transform: rotate(180deg); + left:0px; + top:0px; + width: 100%; + height: 100%; + } + .input-container{ + position: absolute; + right:0px; + top: 30px; + width: 70px; + input{ + width: 100%; + } + } + .text-container{ + position:absolute; + top:30px; + left:0px; + color:white + } +} + +.placement-highlight{ + background-color:blue; + transform: translate(0px, 0px); + transition: width 1000ms ease-in-out; + transition: height 1000ms ease-in-out; + position: absolute; +} + +.timeline-container{ + width:100%; + height:300px; + position:absolute; + background-color: $light-color-secondary; + box-shadow: 0px 10px 20px; + //transition: transform 1000ms ease-in-out; + + .toolbox{ + position:absolute; + width: 100%; + top: 10px; + left: 20px; + div{ + float:left; + margin-left: 10px; + position:relative; + .overview{ + width: 200px; + height: 100%; + background-color: black; + position:absolute; + } + } + } + .info-container{ + margin-top: 50px; + right:20px; + position:absolute; + height: calc(100% - 100px); + width: calc(100% - 140px); + overflow: hidden; + + .scrubberbox{ + position:absolute; + background-color: transparent; + height: 30px; + width:100%; + + .tick{ + height:100%; + width: 1px; + background-color:black; + + } + } + .scrubber{ + top:30px; + height: 100%; + width: 2px; + position:absolute; + z-index: 1001; + background-color:black; + .scrubberhead{ + top: -30px; + height: 30px; + width: 30px; + background-color:transparent; + border-radius: 50%; + border: 5px solid black; + left: -15px; + position:absolute; + } + } + + .trackbox{ + top: 30px; + height:calc(100% - 30px); + width:100%; + border:1px; + overflow:hidden; + background-color:white; + position:absolute; + box-shadow: -10px 0px 10px 10px grey; + } + + } + .title-container{ + margin-top: 80px; + margin-left: 20px; + height: calc(100% - 100px - 30px); + width: 100px; + background-color:white; + overflow: hidden; + .datapane{ + top:0px; + width: 100px; + height: 75px; + border: 1px solid $dark-color; + background-color: $intermediate-color; + color: white; + position:relative; + float:left; + border-style:solid; + } + } + .resize{ + bottom: 5px; + position:absolute; + height: 30px; + width: 50px; + left: calc(50% - 25px); + } +} + + + +.overview{ + position: absolute; + height: 50px; + width: 200px; + background-color: black; + .container{ + position: absolute; + float: left 0px; + top: 25%; + height: 75%; + width: 100%; + background-color: grey; + } +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From c7e258d9d56990daec490b239e4103f9ca9d521a Mon Sep 17 00:00:00 2001 From: andrewdkim Date: Mon, 12 Aug 2019 15:17:20 -0400 Subject: playmode / authoring mode --- src/client/views/animationtimeline/Timeline.scss | 66 ++----------- src/client/views/animationtimeline/Timeline.tsx | 121 +++++++++-------------- src/client/views/nodes/DocumentView.tsx | 3 +- 3 files changed, 57 insertions(+), 133 deletions(-) (limited to 'src/client/views/animationtimeline/Timeline.scss') diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index 47f448adb..e5d898502 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -6,72 +6,24 @@ height: 30px; width: 100px; } -.flyout-container{ - background-color: transparent; - position:absolute; - - z-index:9999; - height: 150px; - width: 150px; - .flyout{ - background-color: transparent; - transform: rotate(180deg); - left:0px; - top:0px; - width: 100%; - height: 100%; - } - .input-container{ - position: absolute; - right:0px; - top: 30px; - width: 70px; - input{ - width: 100%; - } +.timeline-toolbox{ + position:absolute; + display:flex; + align-items: flex-start; + flex-direction: row; + top: 10px; + div{ + margin-left:10px; } - .text-container{ - position:absolute; - top:30px; - left:0px; - color:white - } -} - -.placement-highlight{ - background-color:blue; - transform: translate(0px, 0px); - transition: width 1000ms ease-in-out; - transition: height 1000ms ease-in-out; - position: absolute; } - .timeline-container{ width:100%; height:300px; position:absolute; background-color: $light-color-secondary; box-shadow: 0px 10px 20px; - //transition: transform 1000ms ease-in-out; - - .toolbox{ - position:absolute; - width: 100%; - top: 10px; - left: 20px; - div{ - float:left; - margin-left: 10px; - position:relative; - .overview{ - width: 200px; - height: 100%; - background-color: black; - position:absolute; - } - } - } + .info-container{ margin-top: 50px; right:20px; diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 052e6e925..c8f11db5b 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -5,7 +5,7 @@ import { Document, listSpec } from "../../../new_fields/Schema"; import { observer } from "mobx-react"; import { Track } from "./Track"; import { observable, reaction, action, IReactionDisposer, observe, IObservableArray, computed, toJS, Reaction, IObservableObject, trace, autorun, runInAction } from "mobx"; -import { Cast, NumCast, FieldValue, StrCast } from "../../../new_fields/Types"; +import { Cast, NumCast, FieldValue, StrCast, BoolCast } from "../../../new_fields/Types"; import { List } from "../../../new_fields/List"; import { Doc, DocListCast } from "../../../new_fields/Doc"; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; @@ -82,51 +82,48 @@ export class Timeline extends CollectionSubView(Document) { return Cast(this.props.Document[this.props.fieldKey], listSpec(Doc)) as List; } - @computed - private get inks(){ - if (this.props.Document.data_ext){ - let data_ext = Cast(this.props.Document.data_ext, Doc) as Doc; - let ink = Cast(data_ext.ink, InkField) as InkField; - if (ink){ - return ink.inkData; - } - } + componentWillMount() { + this.props.Document.isAnimating ? this.props.Document.isAnimating = true : this.props.Document.isAnimating = false; } - componentDidMount() { if (StrCast(this.props.Document.type) === "video") { console.log("ran"); console.log(this.props.Document.duration); if (this.props.Document.duration) { this._time = Math.round(NumCast(this.props.Document.duration)) * 1000; - reaction(() => { return NumCast(this.props.Document.curPage); }, curPage => { this.changeCurrentBarX(curPage * this._tickIncrement / this._tickSpacing); }); - } } runInAction(() => { - reaction(() => { - return this._time; - }, () => { - this._ticks = []; - for (let i = 0; i < this._time;) { - this._ticks.push(i); - 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}`; - }, { fireImmediately: true }); + return this.props.Document.isAnimating; + }, async isAnimating => { + if (isAnimating){ + this._ticks = []; + for (let i = 0; i < this._time;) { + this._ticks.push(i); + i += this._tickIncrement; + } + observe(this._trackbox, change => {if (change.type === "update"){ + if (this.props.Document.isAnimating){ + 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}`; + } + }}); + } + + }); }); } + @action changeCurrentBarX = (x: number) => { @@ -346,73 +343,47 @@ export class Timeline extends CollectionSubView(Document) { } render() { - return ( -
- -
-
-
-
-
+ let timeline:JSX.Element[] = []; + BoolCast(this.props.Document.isAnimating) ? timeline = [ +
+ +
+
+
+
+
-
-
+
+
{this._ticks.map(element => { return

{this.toTime(element)}

; })}
-
-
+
+
-
+
{DocListCast(this.children).map(doc => )}
-
+
{DocListCast(this.children).map(doc =>

{doc.title}

)}
-
+
- ); - } - -} - - -interface TimelineOverviewProps { - currentBarX: number; -} - -class TimelineOverview extends React.Component{ - - componentWillMount() { - - } - - render() { - return ( -
-
-
-
-
-
-
- ); - } -} - + ] : timeline = [ +
+
+
+
+
]; -class TimelineZoom extends React.Component { - componentDidMount() { - } - render() { return (
- + {timeline}
); } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index a7b4f33db..95970cb81 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -107,7 +107,7 @@ const schema = createSchema({ nativeHeight: "number", backgroundColor: "string", opacity: "number", - hidden: "boolean" + hidden: "boolean", }); export const positionSchema = createSchema({ @@ -565,6 +565,7 @@ export class DocumentView extends DocComponent(Docu cm.addItem({ description: "Pin to Presentation", event: () => PresentationView.Instance.PinDoc(this.props.Document), icon: "map-pin" }); cm.addItem({ description: BoolCast(this.props.Document.lockedPosition) ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.props.Document.lockedPosition) ? "unlock" : "lock" }); cm.addItem({ description: "Transcribe Speech", event: this.listen, icon: "microphone" }); + cm.addItem({ 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"}); let makes: ContextMenuProps[] = []; makes.push({ description: this.props.Document.isBackground ? "Remove Background" : "Make Background", event: this.makeBackground, icon: BoolCast(this.props.Document.lockedPosition) ? "unlock" : "lock" }); makes.push({ description: this.props.Document.isButton ? "Remove Button" : "Make Button", event: this.makeBtnClicked, icon: "concierge-bell" }); -- cgit v1.2.3-70-g09d2 From e04277caf25be1c657a2f779a64eb5fcb4e19461 Mon Sep 17 00:00:00 2001 From: andrewdkim Date: Wed, 14 Aug 2019 16:08:01 -0400 Subject: UI improvements, pointerevents, and improved overview --- src/client/views/animationtimeline/Keyframe.tsx | 51 +++++++---- src/client/views/animationtimeline/Timeline.scss | 2 +- src/client/views/animationtimeline/Timeline.tsx | 100 ++++++++------------- .../views/animationtimeline/TimelineOverview.scss | 5 +- .../views/animationtimeline/TimelineOverview.tsx | 19 ++-- src/client/views/animationtimeline/Track.tsx | 5 +- src/client/views/graph/GraphManager.ts | 2 +- src/client/views/nodes/DocumentView.tsx | 2 +- 8 files changed, 90 insertions(+), 96 deletions(-) (limited to 'src/client/views/animationtimeline/Timeline.scss') diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx index 6a0525eb8..784765318 100644 --- a/src/client/views/animationtimeline/Keyframe.tsx +++ b/src/client/views/animationtimeline/Keyframe.tsx @@ -2,10 +2,10 @@ import * as React from "react"; import "./Keyframe.scss"; import "./Timeline.scss"; import "../globalCssVariables.scss"; -import { observer, Observer } from "mobx-react"; -import { observable, reaction, action, IReactionDisposer, observe, IObservableArray, computed, toJS, isComputedProp, runInAction } from "mobx"; +import { observer} from "mobx-react"; +import { observable, reaction, action, IReactionDisposer, observe, computed, runInAction } from "mobx"; import { Doc, DocListCast, DocListCastAsync } from "../../../new_fields/Doc"; -import { Cast, FieldValue, StrCast, NumCast } from "../../../new_fields/Types"; +import { Cast, NumCast } from "../../../new_fields/Types"; import { List } from "../../../new_fields/List"; import { createSchema, defaultSpec, makeInterface, listSpec } from "../../../new_fields/Schema"; import { FlyoutProps } from "./Timeline"; @@ -13,7 +13,6 @@ import { Transform } from "../../util/Transform"; import { InkField, StrokeData } from "../../../new_fields/InkField"; import { TimelineMenu } from "./TimelineMenu"; import { Docs } from "../../documents/Documents"; -import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView"; import { CollectionDockingView } from "../collections/CollectionDockingView"; export namespace KeyframeFunc { @@ -111,7 +110,6 @@ interface IProps { RegionData: Doc; collection: Doc; changeCurrentBarX: (x: number) => void; - setFlyout: (props: FlyoutProps) => any; transform: Transform; } @@ -183,8 +181,8 @@ export class Keyframe extends React.Component { let finish = await this.makeKeyData(this.regiondata.position + this.regiondata.duration, KeyframeFunc.KeyframeType.fade)!; (fadeIn.key! as Doc).opacity = 1; (fadeOut.key! as Doc).opacity = 1; - (start.key! as Doc).opacity = 0; - (finish.key! as Doc).opacity = 0; + (start.key! as Doc).opacity = 0.1; + (finish.key! as Doc).opacity = 0.1; observe(this.regiondata, change => { if (change.type === "update") { @@ -238,14 +236,32 @@ export class Keyframe extends React.Component { return TK; } + @observable private _mouseToggled = false; + @observable private _doubleClickEnabled = false; @action onBarPointerDown = (e: React.PointerEvent) => { e.preventDefault(); e.stopPropagation(); - document.addEventListener("pointermove", this.onBarPointerMove); - document.addEventListener("pointerup", (e: PointerEvent) => { + + let clientX = e.clientX; + if (this._doubleClickEnabled){ + this.createKeyframe(clientX); + this._doubleClickEnabled = false; + } else { + setTimeout(() => {if(!this._mouseToggled && this._doubleClickEnabled)this.props.changeCurrentBarX(this.regiondata.position + (clientX - this._bar.current!.getBoundingClientRect().left) * this.props.transform.Scale); + this._mouseToggled = false; + this._doubleClickEnabled = false; }, 200); + this._doubleClickEnabled = true; + document.addEventListener("pointermove", this.onBarPointerMove); + document.addEventListener("pointerup", (e: PointerEvent) => { document.removeEventListener("pointermove", this.onBarPointerMove); }); + + } + + + + } @@ -253,6 +269,9 @@ export class Keyframe extends React.Component { onBarPointerMove = (e: PointerEvent) => { e.preventDefault(); e.stopPropagation(); + if (e.movementX !== 0) { + this._mouseToggled = true; + } let left = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.left, this.regiondata, this.regions)!; let right = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.right, this.regiondata, this.regions!); let prevX = this.regiondata.position; @@ -351,11 +370,10 @@ export class Keyframe extends React.Component { } @action - createKeyframe = async (e: React.MouseEvent) => { - e.preventDefault(); - e.stopPropagation(); + createKeyframe = async (clientX:number) => { + this._mouseToggled = true; let bar = this._bar.current!; - let offset = Math.round((e.clientX - bar.getBoundingClientRect().left) * this.props.transform.Scale); + let offset = Math.round((clientX - bar.getBoundingClientRect().left) * this.props.transform.Scale); if (offset > this.regiondata.fadeIn && offset < this.regiondata.duration - this.regiondata.fadeOut) { //make sure keyframe is not created inbetween fades and ends let position = NumCast(this.regiondata.position); await this.makeKeyData(Math.round(position + offset)); @@ -514,8 +532,7 @@ export class Keyframe extends React.Component { return (
+ onPointerDown={this.onBarPointerDown}>
{this.regiondata.keyframes!.map(kf => { @@ -529,8 +546,10 @@ export class Keyframe extends React.Component {
{ this.onContainerOver(e, bodyRef); }} onPointerOut={(e) => { this.onContainerOut(e, bodyRef); }} - onPointerDown={(e) => { this.props.changeCurrentBarX(NumCast(kf.time) + (e.clientX - bodyRef.current!.getBoundingClientRect().left) * this.props.transform.Scale);}} onContextMenu={(e) => { + e.preventDefault(); + e.stopPropagation(); + this._mouseToggled = true; let items = [ TimelineMenu.Instance.addItem("button", "Add Ease", () => {this.onContainerDown(kf, "interpolate");}), TimelineMenu.Instance.addItem("button", "Add Path", () => {this.onContainerDown(kf, "path");}), diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index e5d898502..1457d5a84 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -8,7 +8,7 @@ } .timeline-toolbox{ - position:absolute; + position:absolute; display:flex; align-items: flex-start; flex-direction: row; diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 29787fa03..3d878660d 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -1,26 +1,17 @@ import * as React from "react"; import "./Timeline.scss"; -import { CollectionSubView, SubCollectionViewProps } from "../collections/CollectionSubView"; +import { CollectionSubView } from "../collections/CollectionSubView"; import { Document, listSpec } from "../../../new_fields/Schema"; import { observer } from "mobx-react"; import { Track } from "./Track"; -import { observable, reaction, action, IReactionDisposer, observe, IObservableArray, computed, toJS, Reaction, IObservableObject, trace, autorun, runInAction } from "mobx"; -import { Cast, NumCast, FieldValue, StrCast, BoolCast } from "../../../new_fields/Types"; +import { observable, reaction, action, IReactionDisposer, computed, runInAction } from "mobx"; +import { Cast, NumCast, StrCast, BoolCast } from "../../../new_fields/Types"; import { List } from "../../../new_fields/List"; import { Doc, DocListCast } from "../../../new_fields/Doc"; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faPlayCircle, faBackward, faForward, faGripLines, faArrowUp, faArrowDown, faClock, faPauseCircle } from "@fortawesome/free-solid-svg-icons"; import { ContextMenuProps } from "../ContextMenuItem"; import { ContextMenu } from "../ContextMenu"; -import { DocumentManager } from "../../util/DocumentManager"; -import { VideoBox } from "../nodes/VideoBox"; -import { VideoField } from "../../../new_fields/URLField"; -import { CollectionVideoView } from "../collections/CollectionVideoView"; -import { Transform } from "../../util/Transform"; -import { faGrinTongueSquint } from "@fortawesome/free-regular-svg-icons"; -import { InkField } from "../../../new_fields/InkField"; -import { AddComparisonParameters } from "../../northstar/model/idea/idea"; -import { keepAlive } from "mobx-utils"; import { TimelineOverview } from "./TimelineOverview"; @@ -57,7 +48,7 @@ export class Timeline extends CollectionSubView(Document) { @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 _isFrozen: boolean = true; //timeline freeze @observable private _totalLength: number = 0; @observable private _visibleLength: number = 0; @observable private _visibleStart: number = 0; @@ -65,7 +56,6 @@ export class Timeline extends CollectionSubView(Document) { @observable private _time = 100000; //DEFAULT @observable private _ticks: number[] = []; @observable private _playButton = faPlayCircle; - @observable private flyoutInfo: FlyoutProps = { x: 0, y: 0, display: "none", regiondata: new Doc(), regions: new List() }; @computed private get children(): List { @@ -130,30 +120,33 @@ export class Timeline extends CollectionSubView(Document) { //for playing @action - onPlay = async (e: React.MouseEvent) => { + onPlay = (e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); if (this._isPlaying) { this._isPlaying = false; this._playButton = faPlayCircle; } else { this._isPlaying = true; this._playButton = faPauseCircle; - this.changeCurrentX(); - } - } - - @action - changeCurrentX = () => { - if (this._currentBarX === this._totalLength && this._isPlaying) { - this._currentBarX = 0; - } - if (this._currentBarX <= this._totalLength && this._isPlaying) { - this._currentBarX = this._currentBarX + this._windSpeed; - setTimeout(this.changeCurrentX, 15); + const playTimeline = () => { + if (this._isPlaying){ + if (this._currentBarX >= this._totalLength) { + this.changeCurrentBarX(0); + } else { + this.changeCurrentBarX(this._currentBarX + this._windSpeed); + setTimeout(playTimeline, 15); + } + } + }; + playTimeline(); } } @action windForward = (e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); if (this._windSpeed < 64) { //max speed is 32 this._windSpeed = this._windSpeed * 2; } @@ -161,6 +154,8 @@ export class Timeline extends CollectionSubView(Document) { @action windBackward = (e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); if (this._windSpeed > 1 / 16) { // min speed is 1/8 this._windSpeed = this._windSpeed / 2; } @@ -313,16 +308,12 @@ export class Timeline extends CollectionSubView(Document) { } } - - private _freezeText = "Freeze Timeline"; - timelineContextMenu = (e: React.MouseEvent): void => { let subitems: ContextMenuProps[] = []; let timelineContainer = this._timelineWrapper.current!; subitems.push({ description: "Pin to Top", event: action(() => { if (!this._isFrozen) { - timelineContainer.style.transition = "top 1000ms ease-in, left 1000ms ease-in"; //????? timelineContainer.style.left = "0px"; timelineContainer.style.top = "0px"; timelineContainer.style.transition = "none"; @@ -330,22 +321,11 @@ export class Timeline extends CollectionSubView(Document) { }), icon: faArrowUp }); subitems.push({ - description: "Pin to Bottom", event: action(() => { - console.log(this.props.Document.y); - - if (!this._isFrozen) { - timelineContainer.style.transform = `translate(0px, ${e.pageY - this._containerHeight}px)`; - } - }), icon: faArrowDown - }); - subitems.push({ - description: this._freezeText, event: action(() => { + description: this._isFrozen ? "Unfreeze Timeline" : "Freeze Timeline", event: action(() => { if (this._isFrozen) { this._isFrozen = false; - this._freezeText = "Freeze Timeline"; } else { this._isFrozen = true; - this._freezeText = "Unfreeze Timeline"; } }), icon: "thumbtack" }); @@ -353,27 +333,24 @@ export class Timeline extends CollectionSubView(Document) { } - - @action - getFlyout = (props: FlyoutProps) => { - for (const [k, v] of Object.entries(props)) { - (this.flyoutInfo as any)[k] = v; - } - console.log(this.flyoutInfo); + private timelineToolBox = (scale:number) => { + let size = 50 * scale; //50 is default + return ( +
+
+
+
+ +
+ ); } - render() { return (
-
-
-
-
- -
+ {this.timelineToolBox(0.5)}
{this._ticks.map(element => { @@ -384,7 +361,7 @@ export class Timeline extends CollectionSubView(Document) {
- {DocListCast(this.children).map(doc => )} + {DocListCast(this.children).map(doc => )}
@@ -395,12 +372,7 @@ export class Timeline extends CollectionSubView(Document) {
-
-
-
-
- -
+ {BoolCast(this.props.Document.isAnimating) ?
: this.timelineToolBox(1) }
); } diff --git a/src/client/views/animationtimeline/TimelineOverview.scss b/src/client/views/animationtimeline/TimelineOverview.scss index 21988927d..9e69c2adf 100644 --- a/src/client/views/animationtimeline/TimelineOverview.scss +++ b/src/client/views/animationtimeline/TimelineOverview.scss @@ -1,16 +1,17 @@ +@import "./../globalCssVariables.scss"; + .timeline-overview-container{ width: 300px; height: 40px; margin-top: 10px; margin-left: 20px; background: white; - border: 1px solid black; + border: 2px solid black; padding: 0px; display:inline-block; .timeline-overview-visible{ height: 100%; background: green; - border: 1px solid black; margin: 0px; } .timeline-overview-scrubber-container{ diff --git a/src/client/views/animationtimeline/TimelineOverview.tsx b/src/client/views/animationtimeline/TimelineOverview.tsx index 1ad7d20e5..4fdf1381e 100644 --- a/src/client/views/animationtimeline/TimelineOverview.tsx +++ b/src/client/views/animationtimeline/TimelineOverview.tsx @@ -6,6 +6,7 @@ import "./TimelineOverview.scss"; interface TimelineOverviewProps{ + scale: number; totalLength: number; visibleLength:number; visibleStart:number; @@ -19,7 +20,9 @@ interface TimelineOverviewProps{ export class TimelineOverview extends React.Component{ @observable private _visibleRef = React.createRef(); @observable private _scrubberRef = React.createRef(); - + private readonly DEFAULT_HEIGHT = 50; + private readonly DEFAULT_WIDTH = 300; + @action onPointerDown = (e:React.PointerEvent) => { document.removeEventListener("pointermove", this.onPanX); @@ -30,8 +33,8 @@ export class TimelineOverview extends React.Component{ @action onPanX = (e: PointerEvent) => { - let movX = (this.props.visibleStart / this.props.totalLength)* 300 + e.movementX; - this.props.movePanX((movX / 300) * this.props.totalLength); + let movX = (this.props.visibleStart / this.props.totalLength)* (this.DEFAULT_WIDTH * this.props.scale) + e.movementX; + this.props.movePanX((movX / (this.DEFAULT_WIDTH * this.props.scale)) * this.props.totalLength); } @action @@ -57,7 +60,7 @@ export class TimelineOverview extends React.Component{ 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); + this.props.changeCurrentBarX(((offsetX / (this.DEFAULT_WIDTH * this.props.scale)) * this.props.totalLength) + this.props.currentBarX); } @action @@ -70,10 +73,10 @@ export class TimelineOverview extends React.Component{ render(){ return( -
-
-
-
+
+
+
+
); diff --git a/src/client/views/animationtimeline/Track.tsx b/src/client/views/animationtimeline/Track.tsx index 288a1d2ad..d91954022 100644 --- a/src/client/views/animationtimeline/Track.tsx +++ b/src/client/views/animationtimeline/Track.tsx @@ -17,7 +17,6 @@ interface IProps { transform: Transform; collection: Doc; changeCurrentBarX: (x: number) => void; - setFlyout: (props: FlyoutProps) => any; } @observer @@ -177,7 +176,7 @@ export class Track extends React.Component { const timeratio = (this.props.currentBarX - NumCast(left.time)) / dif_time; //linear let keyframes = (await DocListCastAsync(regiondata.keyframes!))!; let indexLeft = keyframes.indexOf(left); - let interY:List = await ((regiondata.functions as List)[indexLeft] as Doc).interpolationY as List; + let interY:List = (await ((regiondata.functions as List)[indexLeft] as Doc).interpolationY as List)!; let realIndex = (interY.length - 1) * timeratio; let xIndex = Math.floor(realIndex); let yValue = interY[xIndex]; @@ -276,7 +275,7 @@ export class Track extends React.Component {
{DocListCast(this.regions).map((region) => { - return ; + return ; })}
diff --git a/src/client/views/graph/GraphManager.ts b/src/client/views/graph/GraphManager.ts index 9d62b1ef8..b62f2337b 100644 --- a/src/client/views/graph/GraphManager.ts +++ b/src/client/views/graph/GraphManager.ts @@ -32,7 +32,7 @@ export class GraphManager { defaultGraphs = () => { - this.GraphData.linear = ; + } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index f2be7097a..28af39fb3 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -729,7 +729,7 @@ export class DocumentView extends DocComponent(Docu render() { - trace(); + // trace(); let backgroundColor = this.layoutDoc.isBackground || (this.props.ContainingCollectionView && this.props.ContainingCollectionView.props.Document.clusterOverridesDefaultBackground && this.layoutDoc.backgroundColor === this.layoutDoc.defaultBackgroundColor) ? this.props.backgroundColor(this.layoutDoc) || StrCast(this.layoutDoc.backgroundColor) : StrCast(this.layoutDoc.backgroundColor) || this.props.backgroundColor(this.layoutDoc); -- cgit v1.2.3-70-g09d2 From 8c018a7a686a752ef1b86b852ec2d298792aa354 Mon Sep 17 00:00:00 2001 From: andrewdkim Date: Sat, 28 Sep 2019 17:00:47 -0400 Subject: toggle --- src/client/views/animationtimeline/Keyframe.tsx | 100 ++++------------- src/client/views/animationtimeline/Timeline.scss | 20 ++++ src/client/views/animationtimeline/Timeline.tsx | 121 ++++++--------------- .../views/animationtimeline/TimelineMenu.tsx | 11 +- .../views/animationtimeline/TimelineOverview.tsx | 2 + src/client/views/animationtimeline/Track.tsx | 40 +++---- .../views/nodes/CollectionFreeFormDocumentView.tsx | 3 +- 7 files changed, 102 insertions(+), 195 deletions(-) (limited to 'src/client/views/animationtimeline/Timeline.scss') diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx index 9728c2462..66ad6a76d 100644 --- a/src/client/views/animationtimeline/Keyframe.tsx +++ b/src/client/views/animationtimeline/Keyframe.tsx @@ -8,7 +8,6 @@ import { Doc, DocListCast, DocListCastAsync } from "../../../new_fields/Doc"; import { Cast, NumCast } from "../../../new_fields/Types"; import { List } from "../../../new_fields/List"; import { createSchema, defaultSpec, makeInterface, listSpec } from "../../../new_fields/Schema"; -import { FlyoutProps } from "./Timeline"; import { Transform } from "../../util/Transform"; import { InkField, StrokeData } from "../../../new_fields/InkField"; import { TimelineMenu } from "./TimelineMenu"; @@ -138,48 +137,13 @@ export class Keyframe extends React.Component { @observable private _mouseToggled = false; @observable private _doubleClickEnabled = false; - @computed - private get regiondata() { - let index = this.regions.indexOf(this.props.RegionData); - return RegionData(this.regions[index] as Doc); - } - - @computed - private get regions() { - return Cast(this.props.node.regions, listSpec(Doc)) as List; - } - - @computed - private get firstKeyframe() { - let first: (Doc | undefined) = undefined; - DocListCast(this.regiondata.keyframes!).forEach(kf => { - if (kf.type !== KeyframeFunc.KeyframeType.fade) { - if (!first || first && NumCast(kf.time) < NumCast(first.time)) { - first = kf; - } - } - }); - return first; - } - - @computed - private get lastKeyframe() { - let last: (Doc | undefined) = undefined; - DocListCast(this.regiondata.keyframes!).forEach(kf => { - if (kf.type !== KeyframeFunc.KeyframeType.fade) { - if (!last || last && NumCast(kf.time) > NumCast(last.time)) { - last = kf; - } - } - }); - return last; - } - - @computed - private get keyframes(){ - return DocListCast(this.regiondata.keyframes); - } - + @computed private get regiondata() { return RegionData(this.regions[this.regions.indexOf(this.props.RegionData)] as Doc);} + @computed private get regions() { return Cast(this.props.node.regions, listSpec(Doc)) as List;} + @computed private get keyframes(){ return DocListCast(this.regiondata.keyframes); } + @computed private get pixelPosition(){ return KeyframeFunc.convertPixelTime(this.regiondata.position, "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement);} + @computed private get pixelDuration(){ return KeyframeFunc.convertPixelTime(this.regiondata.duration, "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement); } + @computed private get pixelFadeIn() { return KeyframeFunc.convertPixelTime(this.regiondata.fadeIn, "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement); } + @computed private get pixelFadeOut(){ return KeyframeFunc.convertPixelTime(this.regiondata.fadeOut, "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement); } @computed private get inks() { if (this.props.collection.data_ext) { @@ -191,38 +155,18 @@ export class Keyframe extends React.Component { } } - @computed - private get pixelPosition(){ - return KeyframeFunc.convertPixelTime(this.regiondata.position, "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement); - } - - @computed - private get pixelDuration(){ - return KeyframeFunc.convertPixelTime(this.regiondata.duration, "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement); - } - - @computed - private get pixelFadeIn() { - return KeyframeFunc.convertPixelTime(this.regiondata.fadeIn, "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement); - } - - @computed - private get pixelFadeOut(){ - return KeyframeFunc.convertPixelTime(this.regiondata.fadeOut, "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement); - } - - async componentWillMount() { - if (!this.regiondata.keyframes) { - this.regiondata.keyframes = new List(); - } - let fadeIn = await this.makeKeyData(this.regiondata.position + this.regiondata.fadeIn, KeyframeFunc.KeyframeType.fade)!; - let fadeOut = await this.makeKeyData(this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut, KeyframeFunc.KeyframeType.fade)!; - let start = await this.makeKeyData(this.regiondata.position, KeyframeFunc.KeyframeType.fade)!; - let finish = await this.makeKeyData(this.regiondata.position + this.regiondata.duration, KeyframeFunc.KeyframeType.fade)!; - (fadeIn.key! as Doc).opacity = 1; - (fadeOut.key! as Doc).opacity = 1; - (start.key! as Doc).opacity = 0.1; - (finish.key! as Doc).opacity = 0.1; + componentWillMount() { + runInAction(async () => { + if (!this.regiondata.keyframes) this.regiondata.keyframes = new List(); + let fadeIn = await this.makeKeyData(this.regiondata.position + this.regiondata.fadeIn, KeyframeFunc.KeyframeType.fade)!; + let fadeOut = await this.makeKeyData(this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut, KeyframeFunc.KeyframeType.fade)!; + let start = await this.makeKeyData(this.regiondata.position, KeyframeFunc.KeyframeType.fade)!; + let finish = await this.makeKeyData(this.regiondata.position + this.regiondata.duration, KeyframeFunc.KeyframeType.fade)!; + (fadeIn.key! as Doc).opacity = 1; + (fadeOut.key! as Doc).opacity = 1; + (start.key! as Doc).opacity = 0.1; + (finish.key! as Doc).opacity = 0.1; + }); } @action @@ -336,7 +280,7 @@ export class Keyframe extends React.Component { let bar = this._bar.current!; let offset = KeyframeFunc.convertPixelTime(Math.round((e.clientX - bar.getBoundingClientRect().left) * this.props.transform.Scale), "mili", "time", this.props.tickSpacing, this.props.tickIncrement); let leftRegion = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.left, this.regiondata, this.regions); - let firstkf: (Doc | undefined) = this.firstKeyframe; + let firstkf: (Doc | undefined) = this.keyframes[0]; if (firstkf && this.regiondata.position + this.regiondata.fadeIn + offset >= NumCast(firstkf!.time)) { let dif = NumCast(firstkf!.time) - (this.pixelPosition + this.pixelFadeIn); this.regiondata.position = NumCast(firstkf!.time) - this.regiondata.fadeIn; @@ -364,8 +308,8 @@ export class Keyframe extends React.Component { let bar = this._bar.current!; let offset = KeyframeFunc.convertPixelTime(Math.round((e.clientX - bar.getBoundingClientRect().right) * this.props.transform.Scale), "mili", "time", this.props.tickSpacing, this.props.tickIncrement); let rightRegion = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.right, this.regiondata, this.regions); - if (this.lastKeyframe! && this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut + offset <= NumCast((this.lastKeyframe! as Doc).time)) { - let dif = this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut - NumCast((this.lastKeyframe! as Doc).time); + if (this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut + offset <= NumCast((this.keyframes[this.keyframes.length - 1]).time)) { + let dif = this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut - NumCast((this.keyframes[this.keyframes.length - 1]).time); this.regiondata.duration -= dif; } else if (this.regiondata.duration + offset < this.regiondata.fadeIn + this.regiondata.fadeOut) { // nokeyframes, just fades this.regiondata.duration = this.regiondata.fadeIn + this.regiondata.fadeOut; diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index 1457d5a84..990bc681c 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -119,4 +119,24 @@ width: 100%; background-color: grey; } +} + +.round-toggle { + position: absolute; + height: 40px; + width: 80px; + background-color: white; + border: 2px solid purple; + border-radius: 20px; + input{ + opacity: 0; + height: 0; + width: 0; + } + .slider{ + height: 40px; + width: 40px; + background-color: black; + border-radius: 20px; + } } \ No newline at end of file diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 875a0b8f3..8f96315a0 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -15,17 +15,6 @@ import { TimelineOverview } from "./TimelineOverview"; import { FieldViewProps } from "../nodes/FieldView"; import { KeyframeFunc } from "./Keyframe"; - - -export interface FlyoutProps { - x?: number; - y?: number; - display?: string; - regiondata?: Doc; - regions?: List; -} - - @observer export class Timeline extends React.Component { @@ -35,26 +24,21 @@ export class Timeline extends React.Component { private readonly MAX_CONTAINER_HEIGHT: number = 800; private readonly DEFAULT_TICK_INCREMENT: number = 1000; - @observable private _isMinimized = false; - @observable private _tickSpacing = this.DEFAULT_TICK_SPACING; - @observable private _tickIncrement = this.DEFAULT_TICK_INCREMENT; - @observable private _scrubberbox = React.createRef(); - @observable private _scrubber = React.createRef(); @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 = true; //timeline freeze @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 _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; @@ -273,39 +257,7 @@ export class Timeline extends React.Component { } } - @action - onTimelineDown = (e: React.PointerEvent) => { - e.preventDefault(); - if (e.nativeEvent.which === 1 && !this._isFrozen) { - document.addEventListener("pointermove", this.onTimelineMove); - document.addEventListener("pointerup", () => { document.removeEventListener("pointermove", this.onTimelineMove); }); - } - } - @action - onTimelineMove = (e: PointerEvent) => { - e.preventDefault(); - e.stopPropagation(); - let timelineContainer = this._timelineWrapper.current!; - let left = parseFloat(timelineContainer.style.left!); - let top = parseFloat(timelineContainer.style.top!); - timelineContainer.style.left = `${left + e.movementX}px`; - timelineContainer.style.top = `${top + e.movementY}px`; - } - - @action - minimize = (e: React.MouseEvent) => { - e.preventDefault(); - e.stopPropagation(); - let timelineContainer = this._timelineContainer.current!; - if (this._isMinimized) { - this._isMinimized = false; - timelineContainer.style.visibility = "visible"; - } else { - this._isMinimized = true; - timelineContainer.style.visibility = "hidden"; - } - } @action toReadTime = (time: number): string => { @@ -321,21 +273,6 @@ export class Timeline extends React.Component { timelineContextMenu = (e:MouseEvent): void => { let subitems: ContextMenuProps[] = []; - let timelineContainer = this._timelineWrapper.current!; - subitems.push({ - description: "Pin to Top", event: action(() => { - if (!this._isFrozen) { - timelineContainer.style.left = "0px"; - timelineContainer.style.top = "0px"; - timelineContainer.style.transition = "none"; - } - }), icon: faArrowUp - }); - subitems.push({ - description: this._isFrozen ? "Unfreeze Timeline" : "Freeze Timeline", event: action(() => { - this._isFrozen = !this._isFrozen; - }), icon: "thumbtack" - }); subitems.push({ description: this._timelineVisible ? "Hide Timeline" : "Show Timeline", event: action(() => { this._timelineVisible = !this._timelineVisible; @@ -358,7 +295,8 @@ export class Timeline extends React.Component { 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; + 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); } @@ -402,35 +340,42 @@ export class Timeline extends React.Component {
); } + render() { return ( -
-
- -
- {this.timelineToolBox(0.5)} -
-
- {this._ticks.map(element => { - if(element % this._tickIncrement === 0) return

{this.toReadTime(element)}

; - })} +
+
+
+
+ {this.timelineToolBox(0.5)} +
+
+ {this._ticks.map(element => { + if(element % this._tickIncrement === 0) return

{this.toReadTime(element)}

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

{doc.title}

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

{doc.title}

)} -
-
- -
+ {BoolCast(this.props.Document.isAnimating) ?
: this.timelineToolBox(1) }
- {BoolCast(this.props.Document.isAnimating) ?
: this.timelineToolBox(1) } + +
); } diff --git a/src/client/views/animationtimeline/TimelineMenu.tsx b/src/client/views/animationtimeline/TimelineMenu.tsx index f3b985297..59c25596e 100644 --- a/src/client/views/animationtimeline/TimelineMenu.tsx +++ b/src/client/views/animationtimeline/TimelineMenu.tsx @@ -4,6 +4,7 @@ import {observer} from "mobx-react"; import "./TimelineMenu.scss"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faChartLine, faRoad, faClipboard, faPen, faTrash, faTable } from "@fortawesome/free-solid-svg-icons"; +import { Utils } from "../../../Utils"; @observer @@ -40,7 +41,7 @@ export class TimelineMenu extends React.Component { if (type === "input"){ let inputRef = React.createRef(); let text = ""; - this._currentMenu.push(
{ + this._currentMenu.push(
{ e.stopPropagation(); text = e.target.value; }} onKeyDown={(e) => { @@ -52,23 +53,23 @@ export class TimelineMenu extends React.Component { }}/>
); } else if (type === "button") { let buttonRef = React.createRef(); - this._currentMenu.push(

{ + this._currentMenu.push(

{ e.preventDefault(); e.stopPropagation(); event(e); this.closeMenu(); }}>{title}

); - } + } } @action addMenu = (title:string) => { - this._currentMenu.unshift(

{title}

); + this._currentMenu.unshift(

{title}

); } render() { return ( -
+
{this._currentMenu}
); diff --git a/src/client/views/animationtimeline/TimelineOverview.tsx b/src/client/views/animationtimeline/TimelineOverview.tsx index 38b823cbc..a8f7faba8 100644 --- a/src/client/views/animationtimeline/TimelineOverview.tsx +++ b/src/client/views/animationtimeline/TimelineOverview.tsx @@ -78,6 +78,8 @@ export class TimelineOverview extends React.Component{ } render(){ + console.log("rendered"); + console.log(this.props.visibleStart); return(
diff --git a/src/client/views/animationtimeline/Track.tsx b/src/client/views/animationtimeline/Track.tsx index 274b215d9..3ec410216 100644 --- a/src/client/views/animationtimeline/Track.tsx +++ b/src/client/views/animationtimeline/Track.tsx @@ -32,18 +32,24 @@ export class Track extends React.Component { @observable private _onKeyframe: (Doc | undefined) = undefined; @observable private _onRegionData: (Doc | undefined) = undefined; @observable private _storedState: (Doc | undefined) = undefined; - - @computed - private get regions() { - return Cast(this.props.node.regions, listSpec(Doc)) as List; - } + @observable private filterList = [ + "regions", + "cursors", + "hidden", + "nativeHeight", + "nativeWidth", + "schemaColumns", + "baseLayout", + "backgroundLayout", + "layout", + ]; + + @computed private get regions() { return Cast(this.props.node.regions, listSpec(Doc)) as List;} componentWillMount() { - if (!this.props.node.regions) { - this.props.node.regions = new List(); - } - - + runInAction(() => { + if (!this.props.node.regions) this.props.node.regions = new List(); + }); } componentDidMount() { @@ -54,11 +60,11 @@ export class Track extends React.Component { this.props.node.hidden = false; this.props.node.opacity = 1; }); - } componentWillUnmount() { runInAction(() => { + //disposing reactions if (this._currentBarXReaction) this._currentBarXReaction(); if (this._timelineVisibleReaction) this._timelineVisibleReaction(); }); @@ -166,17 +172,7 @@ export class Track extends React.Component { }); } - private filterList = [ - "regions", - "cursors", - "hidden", - "nativeHeight", - "nativeWidth", - "schemaColumns", - "baseLayout", - "backgroundLayout", - "layout", - ]; + @action private filterKeys = (keys: string[]): string[] => { diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index af2651dc8..bbfc5eb51 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -115,8 +115,7 @@ export class CollectionFreeFormDocumentView extends DocComponent Date: Tue, 1 Oct 2019 16:24:18 -0400 Subject: toggle button --- src/client/views/animationtimeline/Timeline.scss | 44 +++++++++++++++------ src/client/views/animationtimeline/Timeline.tsx | 45 ++++++++++++++++------ .../views/animationtimeline/TimelineOverview.tsx | 2 - 3 files changed, 65 insertions(+), 26 deletions(-) (limited to 'src/client/views/animationtimeline/Timeline.scss') diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index 990bc681c..09fc593fc 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -1,11 +1,6 @@ @import "./../globalCssVariables.scss"; -.minimize{ - position:relative; - z-index: 1000; - height: 30px; - width: 100px; -} + .timeline-toolbox{ position:absolute; @@ -17,6 +12,8 @@ margin-left:10px; } } + + .timeline-container{ width:100%; height:300px; @@ -37,12 +34,10 @@ background-color: transparent; height: 30px; width:100%; - .tick{ height:100%; width: 1px; background-color:black; - } } .scrubber{ @@ -128,15 +123,40 @@ background-color: white; border: 2px solid purple; border-radius: 20px; + animation-fill-mode: forwards; + animation-duration: 500ms; input{ + position:absolute; opacity: 0; height: 0; width: 0; } - .slider{ - height: 40px; - width: 40px; - background-color: black; + .round-toggle-slider{ + position:absolute; + height: 35px; + width: 35px; + top: 0.5px; + background-color: white; + border:1px solid grey; border-radius: 20px; + transition: transform 500ms ease-in-out; + + } + +} +@keyframes turnon{ + from{ + background-color: white; + } + to{ + background-color: purple; + } +} +@keyframes turnoff{ + from{ + background-color: purple; + } + to{ + background-color: white; } } \ No newline at end of file diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 8f96315a0..8127e4de2 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -29,6 +29,8 @@ 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 _currentBarX: number = 0; @observable private _windSpeed: number = 1; @@ -331,23 +333,45 @@ export class Timeline extends React.Component { 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!; + if (BoolCast(this.props.Document.isAnimating)){ + roundToggle.style.transform = "translate(0px, 0px)"; + roundToggle.style.animationName = "turnoff"; + roundToggleContainer.style.animationName = "turnoff"; + + this.props.Document.isAnimating = false; + } else { + roundToggle.style.transform = "translate(45px, 0px)"; + roundToggle.style.animationName = "turnon"; + roundToggleContainer.style.animationName = "turnon"; + this.props.Document.isAnimating = true; + } + } render() { return (
- {this.timelineToolBox(0.5)}
{this._ticks.map(element => { @@ -365,16 +389,13 @@ export class Timeline extends React.Component { {DocListCast(this.children).map(doc =>
{Doc.BrushDoc(doc);}} onPointerOut={() => {Doc.UnBrushDoc(doc);}}>

{doc.title}

)}
- +
- {BoolCast(this.props.Document.isAnimating) ?
: this.timelineToolBox(1) } + { this.timelineToolBox(1) }
- +
); diff --git a/src/client/views/animationtimeline/TimelineOverview.tsx b/src/client/views/animationtimeline/TimelineOverview.tsx index a8f7faba8..38b823cbc 100644 --- a/src/client/views/animationtimeline/TimelineOverview.tsx +++ b/src/client/views/animationtimeline/TimelineOverview.tsx @@ -78,8 +78,6 @@ export class TimelineOverview extends React.Component{ } render(){ - console.log("rendered"); - console.log(this.props.visibleStart); return(
-- cgit v1.2.3-70-g09d2 From 7ccce9564e11ede82bec01b9eea3889da4dc1bc2 Mon Sep 17 00:00:00 2001 From: andrewdkim Date: Tue, 1 Oct 2019 17:10:17 -0400 Subject: changes with toggling --- src/client/views/animationtimeline/Timeline.scss | 11 +++++------ src/client/views/animationtimeline/Timeline.tsx | 8 +++++--- 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'src/client/views/animationtimeline/Timeline.scss') diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index 09fc593fc..71fac876d 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -22,7 +22,7 @@ box-shadow: 0px 10px 20px; .info-container{ - margin-top: 50px; + margin-top: 80px; right:20px; position:absolute; height: calc(100% - 100px); @@ -72,7 +72,7 @@ } .title-container{ - margin-top: 80px; + margin-top: 110px; margin-left: 20px; height: calc(100% - 100px - 30px); width: 100px; @@ -117,7 +117,6 @@ } .round-toggle { - position: absolute; height: 40px; width: 80px; background-color: white; @@ -125,6 +124,7 @@ border-radius: 20px; animation-fill-mode: forwards; animation-duration: 500ms; + top: 20px; input{ position:absolute; opacity: 0; @@ -132,15 +132,14 @@ width: 0; } .round-toggle-slider{ - position:absolute; height: 35px; width: 35px; - top: 0.5px; background-color: white; border:1px solid grey; border-radius: 20px; transition: transform 500ms ease-in-out; - + margin-left: 0px; + margin-top: 0.5px; } } diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 8127e4de2..bc48f422a 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -18,7 +18,7 @@ import { KeyframeFunc } from "./Keyframe"; @observer export class Timeline extends React.Component { - private readonly DEFAULT_CONTAINER_HEIGHT: number = 300; + private readonly DEFAULT_CONTAINER_HEIGHT: number = 330; private readonly DEFAULT_TICK_SPACING: number = 50; private readonly MIN_CONTAINER_HEIGHT: number = 205; private readonly MAX_CONTAINER_HEIGHT: number = 800; @@ -353,16 +353,18 @@ export class Timeline extends React.Component { 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; } 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; } } @@ -371,7 +373,7 @@ export class Timeline extends React.Component {
-
+
{this._ticks.map(element => { -- cgit v1.2.3-70-g09d2 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/client/views/animationtimeline/Timeline.scss') 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 From 98cc5ba95454be7d36343917c6e2c28047f109b9 Mon Sep 17 00:00:00 2001 From: andrewdkim Date: Sun, 6 Oct 2019 16:59:33 -0400 Subject: refactoring and resize right fix --- src/client/views/animationtimeline/Keyframe.tsx | 121 +++++++++++++---------- src/client/views/animationtimeline/Timeline.scss | 12 +-- src/client/views/animationtimeline/Timeline.tsx | 104 +++++-------------- 3 files changed, 98 insertions(+), 139 deletions(-) (limited to 'src/client/views/animationtimeline/Timeline.scss') diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx index 66ad6a76d..587625efa 100644 --- a/src/client/views/animationtimeline/Keyframe.tsx +++ b/src/client/views/animationtimeline/Keyframe.tsx @@ -288,7 +288,7 @@ export class Keyframe extends React.Component { } else if (this.regiondata.duration - offset < this.regiondata.fadeIn + this.regiondata.fadeOut) { // no keyframes, just fades this.regiondata.position -= (this.regiondata.fadeIn + this.regiondata.fadeOut - this.regiondata.duration); this.regiondata.duration = this.regiondata.fadeIn + this.regiondata.fadeOut; - } else if (leftRegion && this.regiondata.position + offset <= leftRegion.position + leftRegion.duration) { + } else if (leftRegion && this.regiondata.position + offset <= leftRegion.position + leftRegion.duration) { let dif = this.regiondata.position - (leftRegion.position + leftRegion.duration); this.regiondata.position = leftRegion.position + leftRegion.duration; this.regiondata.duration += dif; @@ -296,8 +296,8 @@ export class Keyframe extends React.Component { this.regiondata.duration -= offset; this.regiondata.position += offset; } - this.keyframes[0].time = this.regiondata.position; - this.keyframes[1].time = this.regiondata.position + this.regiondata.fadeIn; + // this.keyframes[0].time = this.regiondata.position; + // this.keyframes[1].time = this.regiondata.position + this.regiondata.fadeIn; } @@ -308,14 +308,11 @@ export class Keyframe extends React.Component { let bar = this._bar.current!; let offset = KeyframeFunc.convertPixelTime(Math.round((e.clientX - bar.getBoundingClientRect().right) * this.props.transform.Scale), "mili", "time", this.props.tickSpacing, this.props.tickIncrement); let rightRegion = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.right, this.regiondata, this.regions); - if (this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut + offset <= NumCast((this.keyframes[this.keyframes.length - 1]).time)) { - let dif = this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut - NumCast((this.keyframes[this.keyframes.length - 1]).time); - this.regiondata.duration -= dif; - } else if (this.regiondata.duration + offset < this.regiondata.fadeIn + this.regiondata.fadeOut) { // nokeyframes, just fades - this.regiondata.duration = this.regiondata.fadeIn + this.regiondata.fadeOut; - } else if (rightRegion && this.regiondata.position + this.regiondata.duration + offset >= rightRegion.position) { - let dif = rightRegion.position - (this.regiondata.position + this.regiondata.duration); - this.regiondata.duration += dif; + console.log(offset); + console.log(this.keyframes[this.keyframes.length - 3].time); + console.log(this.regiondata.position + this.regiondata.duration - offset); + if (this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut - offset <= NumCast(this.keyframes[this.keyframes.length - 3].time)) { + console.log("HI"); } else { this.regiondata.duration += offset; } @@ -458,6 +455,7 @@ export class Keyframe extends React.Component { TimelineMenu.Instance.openMenu(e.clientX, e.clientY); } + @action checkInput = (val: any) => { return typeof(val === "number"); } @@ -471,6 +469,7 @@ export class Keyframe extends React.Component { }); } + @action onContainerOver = (e: React.PointerEvent, ref: React.RefObject) => { e.preventDefault(); e.stopPropagation(); @@ -479,6 +478,7 @@ export class Keyframe extends React.Component { Doc.BrushDoc(this.props.node); } + @action onContainerOut = (e: React.PointerEvent, ref: React.RefObject) => { e.preventDefault(); e.stopPropagation(); @@ -568,6 +568,60 @@ export class Keyframe extends React.Component { document.removeEventListener("pointerup", this.onReactionListen); } } + + @action + drawKeyframes = () => { + let keyframeDivs:JSX.Element[] = []; + this.keyframes.forEach( kf => { + if (kf.type as KeyframeFunc.KeyframeType === KeyframeFunc.KeyframeType.default) { + keyframeDivs.push( +
+
+
{ this.moveKeyframe(e, kf); }} onContextMenu={(e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + this.makeKeyframeMenu(kf, e.nativeEvent); + }}>
+
+ ); + } + else { + keyframeDivs.push( +
+
+
+ ); + } + }); + return keyframeDivs; + } + + @action + drawKeyframeDividers = () => { + let keyframeDividers:JSX.Element[] = []; + this.keyframes.forEach(kf => { + if(this.keyframes.indexOf(kf ) !== this.keyframes.length - 1) { + let left = this.keyframes[this.keyframes.indexOf(kf) + 1]; + let bodyRef = React.createRef(); + let kfPos = KeyframeFunc.convertPixelTime(NumCast(kf.time), "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement); + let leftPos = KeyframeFunc.convertPixelTime(NumCast(left!.time), "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement); + return ( +
{ this.onContainerOver(e, bodyRef); }} + onPointerOut={(e) => { this.onContainerOut(e, bodyRef); }} + onContextMenu={(e) => { + e.preventDefault(); + e.stopPropagation(); + this._mouseToggled = true; + this.makeRegionMenu(kf, e.nativeEvent); + }}> +
+ ); + } + }); + return keyframeDividers; + } + render() { return (
@@ -577,49 +631,8 @@ export class Keyframe extends React.Component { onPointerDown={this.onBarPointerDown}>
- {this.keyframes.map(kf => { - if (kf.type as KeyframeFunc.KeyframeType === KeyframeFunc.KeyframeType.default) { - return ( -
-
-
{ this.moveKeyframe(e, kf); }} onContextMenu={(e: React.MouseEvent) => { - e.preventDefault(); - e.stopPropagation(); - this.makeKeyframeMenu(kf, e.nativeEvent); - }}>
-
- ); - } - else { - return ( -
-
-
- ); - } - - })} - {this.keyframes.map( kf => { - if(this.keyframes.indexOf(kf ) !== this.keyframes.length - 1) { - let left = this.keyframes[this.keyframes.indexOf(kf) + 1]; - let bodyRef = React.createRef(); - let kfPos = KeyframeFunc.convertPixelTime(NumCast(kf.time), "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement); - let leftPos = KeyframeFunc.convertPixelTime(NumCast(left!.time), "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement); - return ( -
{ this.onContainerOver(e, bodyRef); }} - onPointerOut={(e) => { this.onContainerOut(e, bodyRef); }} - onContextMenu={(e) => { - e.preventDefault(); - e.stopPropagation(); - this._mouseToggled = true; - this.makeRegionMenu(kf, e.nativeEvent); - }}> -
- ); - } - })} - + {this.drawKeyframes()} + {this.drawKeyframeDividers()}
); diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index fbdb2a200..cf6b4b3d5 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -13,7 +13,11 @@ } } - +.tick{ + height:100%; + width: 1px; + background-color:black; +} .timeline-container{ width:100%; height:300px; @@ -35,11 +39,7 @@ background-color: transparent; height: 30px; width:100%; - .tick{ - height:100%; - width: 1px; - background-color:black; - } + } .scrubber{ top:30px; diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 8a41a5943..9ac5d98d2 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -8,12 +8,13 @@ import { Cast, NumCast, StrCast, BoolCast } from "../../../new_fields/Types"; import { List } from "../../../new_fields/List"; import { Doc, DocListCast } from "../../../new_fields/Doc"; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { faPlayCircle, faBackward, faForward, faGripLines, faArrowUp, faArrowDown, faClock, faPauseCircle, faEyeSlash } from "@fortawesome/free-solid-svg-icons"; +import { faPlayCircle, faBackward, faForward, faGripLines, faArrowUp, faArrowDown, faClock, faPauseCircle, faEyeSlash, faTimes } from "@fortawesome/free-solid-svg-icons"; import { ContextMenuProps } from "../ContextMenuItem"; import { ContextMenu } from "../ContextMenu"; import { TimelineOverview } from "./TimelineOverview"; import { FieldViewProps } from "../nodes/FieldView"; import { KeyframeFunc } from "./Keyframe"; +import { Utils } from "../../../Utils"; @observer export class Timeline extends React.Component { @@ -24,7 +25,6 @@ export class Timeline extends React.Component { private readonly MAX_CONTAINER_HEIGHT: number = 800; private readonly DEFAULT_TICK_INCREMENT: number = 1000; - @observable private _scrubberbox = React.createRef(); @observable private _trackbox = React.createRef(); @observable private _titleContainer = React.createRef(); @observable private _timelineContainer = React.createRef(); @@ -42,13 +42,10 @@ export class Timeline extends React.Component { @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 _doubleClickEnabled = false; @computed private get children(): List { @@ -63,47 +60,28 @@ export class Timeline extends React.Component { 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; - } - componentDidMount() { - if (StrCast(this.props.Document.type) === "video") { - console.log("video"); - console.log(this.props.Document.duration); - if (this.props.Document.duration) { - this._time = Math.round(NumCast(this.props.Document.duration)) * 1000; - this._reactionDisposer.push(reaction(() => { - 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(); - } - })); - } - } runInAction(() => { - this._reactionDisposer.push(reaction(() => { - 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._totalLength = this._tickSpacing * (this._time / this._tickIncrement); this._visibleLength = this._infoContainer.current!.getBoundingClientRect().width; this._visibleStart = this._infoContainer.current!.scrollLeft; }); + } - + /** + * React Functional Component + * Purpose: For drawing Tick marks across the timeline in authoring mode + */ + @action + drawTicks = () => { + let ticks = []; + for (let i = 0; i < this._time / this._tickIncrement; i++){ + ticks.push(

{this.toReadTime(i * this._tickIncrement)}

); + } + return ticks; } + @action changeCurrentBarX = (pixel: number) => { pixel <= 0 ? this._currentBarX = 0 : pixel >= this._totalLength ? this._currentBarX = this._totalLength : this._currentBarX = pixel; @@ -174,23 +152,12 @@ export class Timeline extends React.Component { onScrubberMove = (e: PointerEvent) => { e.preventDefault(); e.stopPropagation(); - let scrubberbox = this._scrubberbox.current!; + let scrubberbox = this._infoContainer.current!; let left = scrubberbox.getBoundingClientRect().left; let offsetX = Math.round(e.clientX - left) * this.props.ScreenToLocalTransform().Scale; this.changeCurrentBarX(offsetX); } - @action - onScrubberClick = (e: React.MouseEvent) => { - e.preventDefault(); - e.stopPropagation(); - let scrubberbox = this._scrubberbox.current!; - let offsetX = (e.clientX - scrubberbox.getBoundingClientRect().left) * this.props.ScreenToLocalTransform().Scale; - this.changeCurrentBarX(offsetX); - } - - - @action onPanDown = (e: React.PointerEvent) => { e.preventDefault(); @@ -236,7 +203,6 @@ export class Timeline extends React.Component { this._visibleStart = infoContainer.scrollLeft; } - @action onResizeDown = (e: React.PointerEvent) => { e.preventDefault(); @@ -261,8 +227,6 @@ export class Timeline extends React.Component { } } - - @action toReadTime = (time: number): string => { const inSeconds = time / 1000; @@ -276,21 +240,12 @@ export class Timeline extends React.Component { } timelineContextMenu = (e: MouseEvent): void => { - let subitems: ContextMenuProps[] = []; - subitems.push({ - description: this._timelineVisible ? "Hide Timeline" : "Show Timeline", event: action(() => { - 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" - }); - ContextMenu.Instance.addItem({ description: "Timeline Funcs...", subitems: subitems, icon: faClock }); + ContextMenu.Instance.addItem({description: (this._timelineVisible ? "Close" : "Open") + " Animation Timeline", event: action(() => { + this._timelineVisible = !this._timelineVisible; + }), icon: faTimes}); } + @action onWheelZoom = (e: React.WheelEvent) => { e.preventDefault(); @@ -339,14 +294,13 @@ export class Timeline extends React.Component { private timelineToolBox = (scale: number) => { let size = 50 * scale; //50 is default return ( -
-
-
+
+
); @@ -360,7 +314,6 @@ export class Timeline extends React.Component { 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"; @@ -374,7 +327,6 @@ export class Timeline extends React.Component { roundToggleContainer.style.animationName = "turnon"; timelineContainer.style.transform = `translate(0px, ${this._containerHeight}px)`; this.props.Document.isAnimating = true; - } } render() { @@ -384,11 +336,7 @@ export class Timeline extends React.Component {
-
- {this._ticks.map(element => { - if (element % this._tickIncrement === 0) return

{this.toReadTime(element)}

; - })} -
+ {this.drawTicks()}
@@ -406,8 +354,6 @@ export class Timeline extends React.Component {
{this.timelineToolBox(1)}
- -
); } -- cgit v1.2.3-70-g09d2 From 8e45ed5a6705becf6708c3d9e9740ce8febe65d9 Mon Sep 17 00:00:00 2001 From: andrewdkim Date: Sun, 20 Oct 2019 17:16:52 -0400 Subject: changed ui input, and more bug fixes --- src/client/views/animationtimeline/Timeline.scss | 68 ++++++++++++++---------- src/client/views/animationtimeline/Timeline.tsx | 51 +++++++++++++++--- 2 files changed, 85 insertions(+), 34 deletions(-) (limited to 'src/client/views/animationtimeline/Timeline.scss') diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index cf6b4b3d5..f6a48d876 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -7,10 +7,48 @@ display:flex; align-items: flex-start; flex-direction: row; + justify-content: space-evenly; + align-items: baseline; top: 10px; div{ margin-left:10px; } + .animation-text{ + font-size: 20px; + height: auto; + width: auto; + } + .round-toggle { + height: 40px; + width: 80px; + background-color: white; + border: 2px solid purple; + border-radius: 20px; + animation-fill-mode: forwards; + animation-duration: 500ms; + top: 30px; + input{ + position:absolute; + opacity: 0; + height: 0; + width: 0; + } + .round-toggle-slider{ + height: 35px; + width: 35px; + background-color: white; + border:1px solid grey; + border-radius: 20px; + transition: transform 500ms ease-in-out; + margin-left: 0px; + margin-top: 0.5px; + } + } + .time-input{ + height: 40px; + width: 100px; + + } } .tick{ @@ -112,38 +150,12 @@ float: left 0px; top: 25%; height: 75%; - width: 100%; + width: 100%; background-color: grey; } } -.round-toggle { - height: 40px; - width: 80px; - background-color: white; - border: 2px solid purple; - border-radius: 20px; - animation-fill-mode: forwards; - animation-duration: 500ms; - top: 20px; - input{ - position:absolute; - opacity: 0; - height: 0; - width: 0; - } - .round-toggle-slider{ - height: 35px; - width: 35px; - background-color: white; - border:1px solid grey; - border-radius: 20px; - transition: transform 500ms ease-in-out; - margin-left: 0px; - margin-top: 0.5px; - } - -} + @keyframes turnon{ from{ background-color: white; diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 666048a54..30fa70b12 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -31,6 +31,7 @@ export class Timeline extends React.Component { @observable private _infoContainer = React.createRef(); @observable private _roundToggleRef = React.createRef(); @observable private _roundToggleContainerRef = React.createRef(); + @observable private _timeInputRef = React.createRef(); @observable private _currentBarX: number = 0; @observable private _windSpeed: number = 1; @@ -62,12 +63,27 @@ export class Timeline extends React.Component { componentDidMount() { runInAction(() => { + if (!this.props.Document.AnimationLength){ + this.props.Document.AnimationLength = this._time; + } else { + this._time = NumCast(this.props.Document.AnimationLength); + console.log(this._time); + } this._totalLength = this._tickSpacing * (this._time / this._tickIncrement); this._visibleLength = this._infoContainer.current!.getBoundingClientRect().width; this._visibleStart = this._infoContainer.current!.scrollLeft; + this.props.Document.isAnimating = !this.props.Document.isAnimating; + this.toggleHandle(); }); } + componentWillUnmount(){ + runInAction(() => { + console.log(this._time); + this.props.Document.AnimationLength = this._time; + }); + } + /** * React Functional Component * Purpose: For drawing Tick marks across the timeline in authoring mode @@ -194,16 +210,20 @@ export class Timeline extends React.Component { let titleContainer = this._titleContainer.current!; this.movePanX(this._visibleStart - e.movementX); trackbox.scrollTop = trackbox.scrollTop - e.movementY; - titleContainer.scrollTop = titleContainer.scrollTop - e.movementY; + titleContainer.scrollTop = titleContainer.scrollTop - e.movementY; + if (this._visibleStart + this._visibleLength + 20>= this._totalLength){ + this._visibleStart -= e.movementX; + this._totalLength -= e.movementX; + this._time -= KeyframeFunc.convertPixelTime(e.movementX, "mili", "time", this._tickSpacing, this._tickIncrement); + this.props.Document.AnimationLength = this._time; + } + } @action movePanX = (pixel: number) => { let infoContainer = this._infoContainer.current!; infoContainer.scrollLeft = pixel; this._visibleStart = infoContainer.scrollLeft; - console.log(infoContainer.scrollLeft); - console.log(this._totalLength); - console.log(this._visibleLength); } @action @@ -300,19 +320,39 @@ export class Timeline extends React.Component {
-
+
+

Timeline Overview

+

Mode: {this.props.Document.isAnimating ? "Authoring" : "Play"}

+

Length:

+ +
); } + + @action + private onTimeInput = (e: React.KeyboardEvent) => { + if (e.keyCode === 13){ + let timeInput = this._timeInputRef.current!; + this._time = parseInt(timeInput.value, 10); + this._totalLength = KeyframeFunc.convertPixelTime(this._time, "mili", "pixel", this._tickSpacing, this._tickIncrement); + this.props.Document.AnimationLength = this._time; + + } + } @action private toggleChecked = (e: React.PointerEvent) => { e.preventDefault(); e.stopPropagation(); + this.toggleHandle(); + } + + private toggleHandle = () => { let roundToggle = this._roundToggleRef.current!; let roundToggleContainer = this._roundToggleContainerRef.current!; let timelineContainer = this._timelineContainer.current!; @@ -322,7 +362,6 @@ export class Timeline extends React.Component { roundToggleContainer.style.animationName = "turnoff"; timelineContainer.style.top = `${-this._containerHeight}px`; this.props.Document.isAnimating = false; - } else { roundToggle.style.transform = "translate(45px, 0px)"; roundToggle.style.animationName = "turnon"; -- cgit v1.2.3-70-g09d2 From 21621ac406b7703811ac40b429c51dac752dd142 Mon Sep 17 00:00:00 2001 From: andrewdkim Date: Sat, 26 Oct 2019 16:47:42 -0400 Subject: ui changes, bug fix, icon fix --- src/client/views/animationtimeline/Keyframe.tsx | 1 + src/client/views/animationtimeline/Timeline.scss | 21 +++++++-------------- src/client/views/animationtimeline/Timeline.tsx | 10 ++++++---- 3 files changed, 14 insertions(+), 18 deletions(-) (limited to 'src/client/views/animationtimeline/Timeline.scss') diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx index c872b8740..6a5163cde 100644 --- a/src/client/views/animationtimeline/Keyframe.tsx +++ b/src/client/views/animationtimeline/Keyframe.tsx @@ -125,6 +125,7 @@ interface IProps { tickSpacing: number; tickIncrement: number; time: number; + changeCurrentBarX: (x: number) => void; transform: Transform; } diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index f6a48d876..8317a3606 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -156,19 +156,12 @@ } -@keyframes turnon{ - from{ - background-color: white; - } - to{ - background-color: purple; - } -} -@keyframes turnoff{ - from{ - background-color: purple; - } - to{ - background-color: white; +.timeline-checker{ + height: auto; + width: auto; + position: absolute; + .check{ + width: 100px; + height: 100px; } } \ No newline at end of file diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 30fa70b12..0b6b06aaa 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -8,7 +8,7 @@ import { Cast, NumCast, StrCast, BoolCast } from "../../../new_fields/Types"; import { List } from "../../../new_fields/List"; import { Doc, DocListCast } from "../../../new_fields/Doc"; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { faPlayCircle, faBackward, faForward, faGripLines, faArrowUp, faArrowDown, faClock, faPauseCircle, faEyeSlash, faTimes } from "@fortawesome/free-solid-svg-icons"; +import { faPlayCircle, faBackward, faForward, faGripLines, faArrowUp, faArrowDown, faClock, faPauseCircle, faEyeSlash, faTimes, faEye, faCheck, faCross} from "@fortawesome/free-solid-svg-icons"; import { ContextMenuProps } from "../ContextMenuItem"; import { ContextMenu } from "../ContextMenu"; import { TimelineOverview } from "./TimelineOverview"; @@ -265,7 +265,7 @@ export class Timeline extends React.Component { timelineContextMenu = (e: MouseEvent): void => { ContextMenu.Instance.addItem({description: (this._timelineVisible ? "Close" : "Open") + " Animation Timeline", event: action(() => { this._timelineVisible = !this._timelineVisible; - }), icon: faTimes}); + }), icon: this._timelineVisible ? faEyeSlash : faEye }); } @@ -329,7 +329,6 @@ export class Timeline extends React.Component {

Length:

-
); } @@ -341,7 +340,6 @@ export class Timeline extends React.Component { this._time = parseInt(timeInput.value, 10); this._totalLength = KeyframeFunc.convertPixelTime(this._time, "mili", "pixel", this._tickSpacing, this._tickIncrement); this.props.Document.AnimationLength = this._time; - } } @@ -392,6 +390,10 @@ export class Timeline extends React.Component {
+
+ + +
{this.timelineToolBox(1)}
-- cgit v1.2.3-70-g09d2 From 2b7b564aa051db78c89d14ff48cf38ace2f42b37 Mon Sep 17 00:00:00 2001 From: andrewdkim Date: Sun, 27 Oct 2019 16:42:34 -0400 Subject: confirm box, regiondata bugfix --- src/client/views/animationtimeline/Keyframe.tsx | 24 ++++++++++------ src/client/views/animationtimeline/Timeline.scss | 16 +++++++++-- src/client/views/animationtimeline/Timeline.tsx | 36 ++++++++++++++++++++---- src/client/views/animationtimeline/Track.tsx | 3 ++ 4 files changed, 62 insertions(+), 17 deletions(-) (limited to 'src/client/views/animationtimeline/Timeline.scss') diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx index 6a5163cde..35d7afc7a 100644 --- a/src/client/views/animationtimeline/Keyframe.tsx +++ b/src/client/views/animationtimeline/Keyframe.tsx @@ -125,9 +125,10 @@ interface IProps { tickSpacing: number; tickIncrement: number; time: number; - + check: string; changeCurrentBarX: (x: number) => void; transform: Transform; + checkCallBack: (visible: boolean) => void; } @observer @@ -137,6 +138,7 @@ export class Keyframe extends React.Component { @observable private _gain = 20; //default @observable private _mouseToggled = false; @observable private _doubleClickEnabled = false; + @observable private _index:number = 0; @computed private get regiondata() { return RegionData(this.regions[this.regions.indexOf(this.props.RegionData)] as Doc);} @computed private get regions() { return Cast(this.props.node.regions, listSpec(Doc)) as List;} @@ -386,7 +388,7 @@ export class Keyframe extends React.Component { }), TimelineMenu.Instance.addItem("button", "Remove Region", ()=>{ runInAction(() => { - this.regions.splice(this.regions.indexOf(this.regiondata), 1);} + this.regions.splice(this.regions.indexOf(this.props.RegionData), 1);} );}), TimelineMenu.Instance.addItem("input", `fadeIn: ${this.regiondata.fadeIn}ms`, (val) => { runInAction(() => { @@ -492,10 +494,12 @@ export class Keyframe extends React.Component { private _plotList: ([string, StrokeData] | undefined) = undefined; private _interpolationKeyframe: (Doc | undefined) = undefined; private _type: string = ""; + @action onContainerDown = (kf: Doc, type: string) => { - let listenerCreated = false; + let listenerCreated = false; + this.props.checkCallBack(true); this._type = type; this.props.collection.backgroundColor = "rgb(0,0,0)"; this._reac = reaction(() => { @@ -504,16 +508,20 @@ export class Keyframe extends React.Component { if (!listenerCreated) { this._plotList = Array.from(data!)[data!.size - 1]!; this._interpolationKeyframe = kf; - document.addEventListener("pointerup", this.onReactionListen); listenerCreated = true; + const reac = reaction(() => { + return this.props.check; + }, () => { + if(this.props.check === "yes") this.onReactionListen(); + reac(); + this.props.checkCallBack(false); + }); } }); } @action - onReactionListen = (e: PointerEvent) => { - e.preventDefault(); - e.stopPropagation(); + onReactionListen = () => { if (this._reac && this._plotList && this._interpolationKeyframe) { this.props.collection.backgroundColor = "#FFF"; this._reac(); @@ -554,8 +562,6 @@ export class Keyframe extends React.Component { this._reac = undefined; this._interpolationKeyframe = undefined; this._plotList = undefined; - this._type = ""; - document.removeEventListener("pointerup", this.onReactionListen); } } diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index 8317a3606..0f98ed7c4 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -159,9 +159,19 @@ .timeline-checker{ height: auto; width: auto; - position: absolute; + overflow: hidden; + position: absolute; + display: flex; + padding: 10px 10px; + div{ + height: auto; + width: auto; + overflow: hidden; + margin: 0px 10px; + cursor: pointer + } .check{ - width: 100px; - height: 100px; + width: 50px; + height: 50px; } } \ No newline at end of file diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 0b6b06aaa..6028656dc 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -8,7 +8,7 @@ import { Cast, NumCast, StrCast, BoolCast } from "../../../new_fields/Types"; import { List } from "../../../new_fields/List"; import { Doc, DocListCast } from "../../../new_fields/Doc"; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { faPlayCircle, faBackward, faForward, faGripLines, faArrowUp, faArrowDown, faClock, faPauseCircle, faEyeSlash, faTimes, faEye, faCheck, faCross} from "@fortawesome/free-solid-svg-icons"; +import { faPlayCircle, faBackward, faForward, faGripLines, faArrowUp, faArrowDown, faClock, faPauseCircle, faEyeSlash, faTimes, faEye, faCheck, faCross, faCheckCircle, faTimesCircle} from "@fortawesome/free-solid-svg-icons"; import { ContextMenuProps } from "../ContextMenuItem"; import { ContextMenu } from "../ContextMenu"; import { TimelineOverview } from "./TimelineOverview"; @@ -368,6 +368,28 @@ export class Timeline extends React.Component { this.props.Document.isAnimating = true; } } + + + @observable private _check:string = ""; + @observable private _checkVisible:boolean = false; + @action + private onCheckClicked = (type: string) => { + if (type === "yes"){ + this._check = "yes"; + } else if (type === "no"){ + this._check = "no"; + } + } + + + @action + private checkCallBack = (visible:boolean) => { + this._checkVisible = visible; + if (!visible){ //when user confirms + this._check = ""; + } + + } render() { return (
@@ -380,7 +402,7 @@ export class Timeline extends React.Component {
- {DocListCast(this.children).map(doc => )} + {DocListCast(this.children).map(doc => )}
@@ -390,9 +412,13 @@ export class Timeline extends React.Component {
-
- - +
+
{this.onCheckClicked("yes");}}> + +
+
{this.onCheckClicked("no");}}> + +
{this.timelineToolBox(1)} diff --git a/src/client/views/animationtimeline/Track.tsx b/src/client/views/animationtimeline/Track.tsx index 7a8f42ea7..14e309f68 100644 --- a/src/client/views/animationtimeline/Track.tsx +++ b/src/client/views/animationtimeline/Track.tsx @@ -20,7 +20,10 @@ interface IProps { tickIncrement: number; tickSpacing: number; timelineVisible: boolean; + check: string; changeCurrentBarX: (x: number) => void; + checkCallBack: (visible: boolean) => void; + } @observer -- cgit v1.2.3-70-g09d2 From 7977625e5b408d6e47432caaf7382aa315fc9832 Mon Sep 17 00:00:00 2001 From: andrewdkim Date: Sun, 3 Nov 2019 16:48:56 -0500 Subject: changes to timeline overview --- src/client/views/animationtimeline/Keyframe.tsx | 1 - src/client/views/animationtimeline/Timeline.scss | 35 +++++++---- src/client/views/animationtimeline/Timeline.tsx | 10 +-- .../views/animationtimeline/TimelineOverview.scss | 73 ++++++++++++++++++---- .../views/animationtimeline/TimelineOverview.tsx | 30 ++++++--- 5 files changed, 109 insertions(+), 40 deletions(-) (limited to 'src/client/views/animationtimeline/Timeline.scss') diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx index 35d7afc7a..55a2b2075 100644 --- a/src/client/views/animationtimeline/Keyframe.tsx +++ b/src/client/views/animationtimeline/Keyframe.tsx @@ -138,7 +138,6 @@ export class Keyframe extends React.Component { @observable private _gain = 20; //default @observable private _mouseToggled = false; @observable private _doubleClickEnabled = false; - @observable private _index:number = 0; @computed private get regiondata() { return RegionData(this.regions[this.regions.indexOf(this.props.RegionData)] as Doc);} @computed private get regions() { return Cast(this.props.node.regions, listSpec(Doc)) as List;} diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index 0f98ed7c4..6270eed41 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -4,25 +4,33 @@ .timeline-toolbox{ position:absolute; + margin: 0px; + padding: 0px; display:flex; align-items: flex-start; - flex-direction: row; - justify-content: space-evenly; - align-items: baseline; - top: 10px; + flex-direction: row; + justify-content: space-evenly; + align-items: center; + top: 15px; div{ + padding: 0px; margin-left:10px; } .animation-text{ font-size: 20px; height: auto; width: auto; + white-space: nowrap; + font-size: 16px; + color: grey; + letter-spacing: 2px; + text-transform: uppercase; } .round-toggle { height: 40px; width: 80px; background-color: white; - border: 2px solid purple; + border: 2px solid grey; border-radius: 20px; animation-fill-mode: forwards; animation-duration: 500ms; @@ -44,13 +52,18 @@ margin-top: 0.5px; } } - .time-input{ - height: 40px; - width: 100px; - - } + +} +.time-input{ + height: 40px; + width: 100px; + white-space: nowrap; + font-size: 16px; + color: grey; + letter-spacing: 2px; + text-transform: uppercase; + } - .tick{ height:100%; width: 1px; diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 6028656dc..94cd0629d 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -321,14 +321,14 @@ export class Timeline extends React.Component {
-

Timeline Overview

- -

Mode: {this.props.Document.isAnimating ? "Authoring" : "Play"}

+
Timeline Overview
+ +
Mode: {this.props.Document.isAnimating ? "Authoring" : "Play"}
-

Length:

- +
Length:
+
); } diff --git a/src/client/views/animationtimeline/TimelineOverview.scss b/src/client/views/animationtimeline/TimelineOverview.scss index 9e69c2adf..c7f9bd059 100644 --- a/src/client/views/animationtimeline/TimelineOverview.scss +++ b/src/client/views/animationtimeline/TimelineOverview.scss @@ -1,38 +1,85 @@ @import "./../globalCssVariables.scss"; -.timeline-overview-container{ + +.timeline-overview-container{ + padding: 0px; + margin: 0px; width: 300px; height: 40px; - margin-top: 10px; - margin-left: 20px; background: white; + position: relative; border: 2px solid black; - padding: 0px; - display:inline-block; + .timeline-overview-visible{ + position: absolute; height: 100%; background: green; + display: inline-block; margin: 0px; + padding: 0px; } - .timeline-overview-scrubber-container{ + .timeline-overview-scrubber-container{ + margin: 0px; + padding: 0px; + position: absolute; height: 100%; - margin-top: -40px; - margin-left: 0px; width: 2px; + top: 0px; + left: 0px; z-index: 1001; background-color:black; display: inline-block; - .timeline-overview-scrubber-head{ + + .timeline-overview-scrubber-head{ + padding: 0px; + margin: 0px; position:absolute; height: 30px; width: 30px; background-color:transparent; border-radius: 50%; border: 5px solid black; - margin-left: -15px; - top: -15px; - + left: -15px; + top: -30px; } - } +} + + + +.timeline-play-bar{ + position: relative; + padding: 0px; + margin: 0px; + width: 300px; + height: 4px; + background-color: grey; + border-radius: 20px; + cursor: pointer; + + .timeline-play-head{ + position: absolute; + padding: 0px; + margin: 0px; + width: 20px; + height: 20px; + border-radius: 50%; + background-color: white; + border: 3px grey solid; + left: 0px; + top: -10px; + cursor: pointer; + } +} +.timeline-play-tail{ + position: absolute; + padding: 0px; + margin: 0px; + height: 4px; + width: 0px; + z-index: 1000; + background-color: green; + border-radius: 20px; + margin-top: -4px; + cursor: pointer; } \ No newline at end of file diff --git a/src/client/views/animationtimeline/TimelineOverview.tsx b/src/client/views/animationtimeline/TimelineOverview.tsx index 38b823cbc..4741969dc 100644 --- a/src/client/views/animationtimeline/TimelineOverview.tsx +++ b/src/client/views/animationtimeline/TimelineOverview.tsx @@ -6,11 +6,11 @@ import "./TimelineOverview.scss"; interface TimelineOverviewProps{ - scale: number; totalLength: number; visibleLength:number; visibleStart:number; - currentBarX:number; + currentBarX:number; + isAuthoring: boolean; changeCurrentBarX: (pixel:number) => void; movePanX: (pixel:number) => any; } @@ -37,8 +37,8 @@ export class TimelineOverview extends React.Component{ onPanX = (e: PointerEvent) => { e.stopPropagation(); e.preventDefault(); - let movX = (this.props.visibleStart / this.props.totalLength)* (this.DEFAULT_WIDTH * this.props.scale) + e.movementX; - this.props.movePanX((movX / (this.DEFAULT_WIDTH * this.props.scale)) * this.props.totalLength); + let movX = (this.props.visibleStart / this.props.totalLength)* (this.DEFAULT_WIDTH) + e.movementX; + this.props.movePanX((movX / (this.DEFAULT_WIDTH )) * this.props.totalLength); } @action @@ -66,7 +66,7 @@ export class TimelineOverview extends React.Component{ let scrubberRef = this._scrubberRef.current!; let left = scrubberRef.getBoundingClientRect().left; let offsetX = Math.round(e.clientX - left); - this.props.changeCurrentBarX(((offsetX / (this.DEFAULT_WIDTH * this.props.scale)) * this.props.totalLength) + this.props.currentBarX); + this.props.changeCurrentBarX((offsetX / (this.DEFAULT_WIDTH) * this.props.totalLength) + this.props.currentBarX); } @action @@ -78,12 +78,22 @@ export class TimelineOverview extends React.Component{ } render(){ + let timeline = this.props.isAuthoring ? [ +
+
, +
+
+
+
+ ] : [ +
+
+
, +
+ ]; return( -
-
-
-
-
+
+ {timeline}
); } -- cgit v1.2.3-70-g09d2 From 4d4db3aecf54a501a981c239feacdfddfe71152c Mon Sep 17 00:00:00 2001 From: andrewdkim Date: Tue, 12 Nov 2019 17:20:21 -0500 Subject: bug fix with ui changes --- src/client/views/animationtimeline/Keyframe.tsx | 13 ++++++++----- src/client/views/animationtimeline/Timeline.scss | 5 +++-- src/client/views/animationtimeline/Timeline.tsx | 10 ++++++---- 3 files changed, 17 insertions(+), 11 deletions(-) (limited to 'src/client/views/animationtimeline/Timeline.scss') diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx index 55a2b2075..424f4ed8d 100644 --- a/src/client/views/animationtimeline/Keyframe.tsx +++ b/src/client/views/animationtimeline/Keyframe.tsx @@ -572,11 +572,11 @@ export class Keyframe extends React.Component { keyframeDivs.push(
-
{ this.moveKeyframe(e, kf); }} onContextMenu={(e: React.MouseEvent) => { +
{ e.preventDefault(); e.stopPropagation(); this.moveKeyframe(e, kf); }} onContextMenu={(e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); this.makeKeyframeMenu(kf, e.nativeEvent); - }}>
+ }} onDoubleClick={(e) => {e.preventDefault(); e.stopPropagation(); }}>
); } @@ -595,7 +595,8 @@ export class Keyframe extends React.Component { drawKeyframeDividers = () => { let keyframeDividers:JSX.Element[] = []; DocListCast(this.regiondata.keyframes).forEach(kf => { - if(this.keyframes.indexOf(kf ) !== this.keyframes.length - 1) { + let index = this.keyframes.indexOf(kf); + if(index !== this.keyframes.length - 1 ) { let left = this.keyframes[this.keyframes.indexOf(kf) + 1]; let bodyRef = React.createRef(); let kfPos = KeyframeFunc.convertPixelTime(NumCast(kf.time), "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement); @@ -606,8 +607,10 @@ export class Keyframe extends React.Component { onPointerOut={(e) => { e.preventDefault(); e.stopPropagation(); this.onContainerOut(e, bodyRef); }} onContextMenu={(e) => { e.preventDefault(); - e.stopPropagation(); - this._mouseToggled = true; + e.stopPropagation(); + if (index !== 0 || index !== this.keyframes.length - 2){ + this._mouseToggled = true; + } this.makeRegionMenu(kf, e.nativeEvent); }}>
diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index 6270eed41..88d602d76 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -11,7 +11,7 @@ flex-direction: row; justify-content: space-evenly; align-items: center; - top: 15px; + top: 20px; div{ padding: 0px; margin-left:10px; @@ -56,12 +56,13 @@ } .time-input{ height: 40px; - width: 100px; + width: 120px; white-space: nowrap; font-size: 16px; color: grey; letter-spacing: 2px; text-transform: uppercase; + padding-left: 5px; } .tick{ diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 94cd0629d..73e6c600f 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -315,12 +315,12 @@ export class Timeline extends React.Component { } private timelineToolBox = (scale: number) => { - let size = 50 * scale; //50 is default + let size = 40 * scale; //50 is default return (
-
-
-
+
+
+
Timeline Overview
Mode: {this.props.Document.isAnimating ? "Authoring" : "Play"}
@@ -358,12 +358,14 @@ export class Timeline extends React.Component { roundToggle.style.transform = "translate(0px, 0px)"; roundToggle.style.animationName = "turnoff"; roundToggleContainer.style.animationName = "turnoff"; + roundToggleContainer.style.backgroundColor = "white"; timelineContainer.style.top = `${-this._containerHeight}px`; this.props.Document.isAnimating = false; } else { roundToggle.style.transform = "translate(45px, 0px)"; roundToggle.style.animationName = "turnon"; roundToggleContainer.style.animationName = "turnon"; + roundToggleContainer.style.backgroundColor = "green"; timelineContainer.style.top = "0px"; this.props.Document.isAnimating = true; } -- cgit v1.2.3-70-g09d2 From 5becac4b0442da73a6fe3b48e3a248f6cf2df61d Mon Sep 17 00:00:00 2001 From: monikahedman Date: Sat, 23 Nov 2019 15:40:07 -0500 Subject: responsive ui --- src/client/views/animationtimeline/Timeline.scss | 276 ++++++++++++----------- src/client/views/animationtimeline/Timeline.tsx | 129 ++++++----- src/client/views/animationtimeline/Track.scss | 1 - src/client/views/animationtimeline/Track.tsx | 88 ++++---- src/client/views/linking/LinkFollowBox.tsx | 2 +- 5 files changed, 260 insertions(+), 236 deletions(-) (limited to 'src/client/views/animationtimeline/Timeline.scss') diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index 88d602d76..493b084a8 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -1,191 +1,209 @@ -@import "./../globalCssVariables.scss"; +@import "./../globalCssVariables.scss"; -.timeline-toolbox{ - position:absolute; - margin: 0px; - padding: 0px; - display:flex; - align-items: flex-start; +.timeline-toolbox { + position: absolute; + margin: 0px; + padding: 0px; + display: flex; + align-items: flex-start; flex-direction: row; justify-content: space-evenly; align-items: center; top: 20px; - div{ - padding: 0px; - margin-left:10px; + + div { + padding: 0px; + margin-left: 10px; } - .animation-text{ - font-size: 20px; - height: auto; - width: auto; + + .animation-text { + font-size: 20px; + height: auto; + width: auto; white-space: nowrap; font-size: 16px; color: grey; letter-spacing: 2px; text-transform: uppercase; } + .round-toggle { height: 40px; width: 80px; background-color: white; border: 2px solid grey; border-radius: 20px; - animation-fill-mode: forwards; + animation-fill-mode: forwards; animation-duration: 500ms; - top: 30px; - input{ - position:absolute; - opacity: 0; - height: 0; - width: 0; + top: 30px; + + input { + position: absolute; + opacity: 0; + height: 0; + width: 0; } - .round-toggle-slider{ - height: 35px; - width: 35px; + + .round-toggle-slider { + height: 35px; + width: 35px; background-color: white; - border:1px solid grey; - border-radius: 20px; - transition: transform 500ms ease-in-out; - margin-left: 0px; - margin-top: 0.5px; - } + border: 1px solid grey; + border-radius: 20px; + transition: transform 500ms ease-in-out; + margin-left: 0px; + margin-top: 0.5px; + } } - + } -.time-input{ - height: 40px; - width: 120px; + +.time-input { + height: 40px; + width: 120px; white-space: nowrap; font-size: 16px; color: grey; letter-spacing: 2px; text-transform: uppercase; - padding-left: 5px; - + padding-left: 5px; + } -.tick{ - height:100%; - width: 1px; - background-color:black; -} -.timeline-container{ - width:100%; - height:300px; - position:absolute; + +.tick { + height: 100%; + width: 1px; + background-color: black; +} + +.timeline-container { + width: 100%; + height: 300px; + position: absolute; background-color: $light-color-secondary; - box-shadow: 0px 10px 20px; - transition: transform 500ms ease; - - .info-container{ - margin-top: 80px; - right:20px; - position:absolute; - height: calc(100% - 100px); - width: calc(100% - 140px); + box-shadow: 0px 10px 20px; + transition: transform 500ms ease; + + .info-container { + margin-top: 80px; + right: 20px; + position: absolute; + height: calc(100% - 100px); + width: calc(100% - 140px); overflow: hidden; - .scrubberbox{ - position:absolute; - background-color: transparent; + .scrubberbox { + position: absolute; + background-color: transparent; height: 30px; - width:100%; - + width: 100%; + } - .scrubber{ - top:30px; - height: 100%; - width: 2px; - position:absolute; + + .scrubber { + top: 30px; + height: 100%; + width: 2px; + position: absolute; z-index: 1001; - background-color:black; - .scrubberhead{ - top: -30px; - height: 30px; + background-color: black; + + .scrubberhead { + top: -30px; + height: 30px; width: 30px; - background-color:transparent; - border-radius: 50%; - border: 5px solid black; + background-color: transparent; + border-radius: 50%; + border: 5px solid black; left: -15px; - position:absolute; + position: absolute; } } - .trackbox{ - top: 30px; - height:calc(100% - 30px); - width:100%; - border:1px; - overflow:hidden; - background-color:white; - position:absolute; - box-shadow: -10px 0px 10px 10px grey; + .trackbox { + top: 30px; + height: calc(100% - 30px); + width: 100%; + border: 1px; + overflow: hidden; + background-color: white; + position: absolute; + box-shadow: -10px 0px 10px 10px grey; } - + } - .title-container{ - margin-top: 110px; - margin-left: 20px; - height: calc(100% - 100px - 30px); - width: 100px; - background-color:white; - overflow: hidden; - .datapane{ - top:0px; - width: 100px; - height: 75px; + + .title-container { + margin-top: 110px; + margin-left: 20px; + height: calc(100% - 100px - 30px); + width: 100px; + background-color: white; + overflow: hidden; + + .datapane { + top: 0px; + width: 100px; + height: 30%; border: 1px solid $dark-color; - background-color: $intermediate-color; - color: white; - position:relative; - float:left; - border-style:solid; + background-color: $intermediate-color; + color: white; + position: relative; + float: left; + border-style: solid; + overflow-y: scroll; + overflow-x: hidden; } } - .resize{ - bottom: 5px; - position:absolute; - height: 30px; - width: 50px; + + .resize { + bottom: 5px; + position: absolute; + height: 30px; + width: 50px; left: calc(50% - 25px); } } -.overview{ - position: absolute; - height: 50px; - width: 200px; - background-color: black; - .container{ - position: absolute; - float: left 0px; - top: 25%; - height: 75%; - width: 100%; - background-color: grey; +.overview { + position: absolute; + height: 50px; + width: 200px; + background-color: black; + + .container { + position: absolute; + float: left 0px; + top: 25%; + height: 75%; + width: 100%; + background-color: grey; } } -.timeline-checker{ - height: auto; - width: auto; - overflow: hidden; - position: absolute; - display: flex; - padding: 10px 10px; - div{ - height: auto; +.timeline-checker { + height: auto; + width: auto; + overflow: hidden; + position: absolute; + display: flex; + padding: 10px 10px; + + div { + height: auto; width: auto; - overflow: hidden; - margin: 0px 10px; + overflow: hidden; + margin: 0px 10px; cursor: pointer } - .check{ - width: 50px; - height: 50px; + + .check { + width: 50px; + height: 50px; } } \ No newline at end of file diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 43019903e..f8aa88755 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -8,7 +8,7 @@ import { Cast, NumCast, StrCast, BoolCast } from "../../../new_fields/Types"; import { List } from "../../../new_fields/List"; import { Doc, DocListCast } from "../../../new_fields/Doc"; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { faPlayCircle, faBackward, faForward, faGripLines, faArrowUp, faArrowDown, faClock, faPauseCircle, faEyeSlash, faTimes, faEye, faCheck, faCross, faCheckCircle, faTimesCircle} from "@fortawesome/free-solid-svg-icons"; +import { faPlayCircle, faBackward, faForward, faGripLines, faArrowUp, faArrowDown, faClock, faPauseCircle, faEyeSlash, faTimes, faEye, faCheck, faCross, faCheckCircle, faTimesCircle } from "@fortawesome/free-solid-svg-icons"; import { ContextMenuProps } from "../ContextMenuItem"; import { ContextMenu } from "../ContextMenu"; import { TimelineOverview } from "./TimelineOverview"; @@ -19,9 +19,9 @@ import { Utils } from "../../../Utils"; @observer export class Timeline extends React.Component { - private readonly DEFAULT_CONTAINER_HEIGHT: number = 330; + private DEFAULT_CONTAINER_HEIGHT: number = 330; private readonly DEFAULT_TICK_SPACING: number = 50; - private readonly MIN_CONTAINER_HEIGHT: number = 205; + private MIN_CONTAINER_HEIGHT: number = 205; private readonly MAX_CONTAINER_HEIGHT: number = 800; private readonly DEFAULT_TICK_INCREMENT: number = 1000; @@ -31,7 +31,7 @@ export class Timeline extends React.Component { @observable private _infoContainer = React.createRef(); @observable private _roundToggleRef = React.createRef(); @observable private _roundToggleContainerRef = React.createRef(); - @observable private _timeInputRef = React.createRef(); + @observable private _timeInputRef = React.createRef(); @observable private _currentBarX: number = 0; @observable private _windSpeed: number = 1; @@ -46,8 +46,8 @@ export class Timeline extends React.Component { @observable private _playButton = faPlayCircle; @observable private _timelineVisible = false; @observable private _mouseToggled = false; - @observable private _doubleClickEnabled = false; - + @observable private _doubleClickEnabled = false; + private _titleHeight = 0; @computed private get children(): List { let extendedDocument = ["image", "video", "pdf"].includes(StrCast(this.props.Document.type)); @@ -60,28 +60,33 @@ export class Timeline extends React.Component { } return Cast(this.props.Document[this.props.fieldKey], listSpec(Doc)) as List; } + componentWillMount() { + this._titleHeight = window.innerHeight / 14; //arbitrary number, but for responsiveness + this.MIN_CONTAINER_HEIGHT = this._titleHeight + 130; + this.DEFAULT_CONTAINER_HEIGHT = this._titleHeight * 2 + 130; + } componentDidMount() { runInAction(() => { - if (!this.props.Document.AnimationLength){ - this.props.Document.AnimationLength = this._time; + if (!this.props.Document.AnimationLength) { + this.props.Document.AnimationLength = this._time; } else { - this._time = NumCast(this.props.Document.AnimationLength); - console.log(this._time); + this._time = NumCast(this.props.Document.AnimationLength); + console.log(this._time); } this._totalLength = this._tickSpacing * (this._time / this._tickIncrement); this._visibleLength = this._infoContainer.current!.getBoundingClientRect().width; this._visibleStart = this._infoContainer.current!.scrollLeft; - this.props.Document.isATOn = !this.props.Document.isATOn; - this.toggleHandle(); + this.props.Document.isATOn = !this.props.Document.isATOn; + this.toggleHandle(); }); } - componentWillUnmount(){ + componentWillUnmount() { runInAction(() => { - console.log(this._time); - this.props.Document.AnimationLength = this._time; - }); + console.log(this._time); + this.props.Document.AnimationLength = this._time; + }); } /** @@ -90,11 +95,11 @@ export class Timeline extends React.Component { */ @action drawTicks = () => { - let ticks = []; - for (let i = 0; i < this._time / this._tickIncrement; i++){ - ticks.push(

{this.toReadTime(i * this._tickIncrement)}

); + let ticks = []; + for (let i = 0; i < this._time / this._tickIncrement; i++) { + ticks.push(

{this.toReadTime(i * this._tickIncrement)}

); } - return ticks; + return ticks; } @@ -210,14 +215,14 @@ export class Timeline extends React.Component { let titleContainer = this._titleContainer.current!; this.movePanX(this._visibleStart - e.movementX); trackbox.scrollTop = trackbox.scrollTop - e.movementY; - titleContainer.scrollTop = titleContainer.scrollTop - e.movementY; - if (this._visibleStart + this._visibleLength + 20>= this._totalLength){ - this._visibleStart -= e.movementX; + titleContainer.scrollTop = titleContainer.scrollTop - e.movementY; + if (this._visibleStart + this._visibleLength + 20 >= this._totalLength) { + this._visibleStart -= e.movementX; this._totalLength -= e.movementX; - this._time -= KeyframeFunc.convertPixelTime(e.movementX, "mili", "time", this._tickSpacing, this._tickIncrement); - this.props.Document.AnimationLength = this._time; + this._time -= KeyframeFunc.convertPixelTime(e.movementX, "mili", "time", this._tickSpacing, this._tickIncrement); + this.props.Document.AnimationLength = this._time; } - + } @action movePanX = (pixel: number) => { @@ -263,9 +268,11 @@ export class Timeline extends React.Component { } timelineContextMenu = (e: MouseEvent): void => { - ContextMenu.Instance.addItem({description: (this._timelineVisible ? "Close" : "Open") + " Animation Timeline", event: action(() => { - this._timelineVisible = !this._timelineVisible; - }), icon: this._timelineVisible ? faEyeSlash : faEye }); + ContextMenu.Instance.addItem({ + description: (this._timelineVisible ? "Close" : "Open") + " Animation Timeline", event: action(() => { + this._timelineVisible = !this._timelineVisible; + }), icon: this._timelineVisible ? faEyeSlash : faEye + }); } @@ -318,28 +325,28 @@ export class Timeline extends React.Component { let size = 40 * scale; //50 is default return (
-
-
-
+
+
+
Timeline Overview
- +
Mode: {this.props.Document.isATOn ? "Authoring" : "Play"}
-
Length:
- +
Length:
+
); } - - @action + + @action private onTimeInput = (e: React.KeyboardEvent) => { - if (e.keyCode === 13){ - let timeInput = this._timeInputRef.current!; + if (e.keyCode === 13) { + let timeInput = this._timeInputRef.current!; this._time = parseInt(timeInput.value, 10); - this._totalLength = KeyframeFunc.convertPixelTime(this._time, "mili", "pixel", this._tickSpacing, this._tickIncrement); - this.props.Document.AnimationLength = this._time; + this._totalLength = KeyframeFunc.convertPixelTime(this._time, "mili", "pixel", this._tickSpacing, this._tickIncrement); + this.props.Document.AnimationLength = this._time; } } @@ -347,7 +354,7 @@ export class Timeline extends React.Component { private toggleChecked = (e: React.PointerEvent) => { e.preventDefault(); e.stopPropagation(); - this.toggleHandle(); + this.toggleHandle(); } private toggleHandle = () => { @@ -358,36 +365,36 @@ export class Timeline extends React.Component { roundToggle.style.transform = "translate(0px, 0px)"; roundToggle.style.animationName = "turnoff"; roundToggleContainer.style.animationName = "turnoff"; - roundToggleContainer.style.backgroundColor = "white"; + roundToggleContainer.style.backgroundColor = "white"; timelineContainer.style.top = `${-this._containerHeight}px`; this.props.Document.isATOn = false; } else { roundToggle.style.transform = "translate(45px, 0px)"; roundToggle.style.animationName = "turnon"; roundToggleContainer.style.animationName = "turnon"; - roundToggleContainer.style.backgroundColor = "green"; - timelineContainer.style.top = "0px"; + roundToggleContainer.style.backgroundColor = "green"; + timelineContainer.style.top = "0px"; this.props.Document.isATOn = true; } } - @observable private _check:string = ""; - @observable private _checkVisible:boolean = false; + @observable private _check: string = ""; + @observable private _checkVisible: boolean = false; @action private onCheckClicked = (type: string) => { - if (type === "yes"){ - this._check = "yes"; - } else if (type === "no"){ + if (type === "yes") { + this._check = "yes"; + } else if (type === "no") { this._check = "no"; } } - @action - private checkCallBack = (visible:boolean) => { - this._checkVisible = visible; - if (!visible){ //when user confirms + @action + private checkCallBack = (visible: boolean) => { + this._checkVisible = visible; + if (!visible) { //when user confirms this._check = ""; } @@ -404,22 +411,22 @@ export class Timeline extends React.Component {
- {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.onCheckClicked("yes");}}> - +
+
{ this.onCheckClicked("yes"); }}> +
-
{this.onCheckClicked("no");}}> - +
{ this.onCheckClicked("no"); }}> +
diff --git a/src/client/views/animationtimeline/Track.scss b/src/client/views/animationtimeline/Track.scss index c8d56edf6..61a8e0b88 100644 --- a/src/client/views/animationtimeline/Track.scss +++ b/src/client/views/animationtimeline/Track.scss @@ -5,7 +5,6 @@ .track { .inner { top:0px; - height: 75px; width: calc(100%); background-color: $light-color; border: 1px solid $dark-color; diff --git a/src/client/views/animationtimeline/Track.tsx b/src/client/views/animationtimeline/Track.tsx index e66b42690..bee9933b0 100644 --- a/src/client/views/animationtimeline/Track.tsx +++ b/src/client/views/animationtimeline/Track.tsx @@ -19,10 +19,10 @@ interface IProps { time: number; tickIncrement: number; tickSpacing: number; - timelineVisible: boolean; - check: string; + timelineVisible: boolean; + check: string; changeCurrentBarX: (x: number) => void; - checkCallBack: (visible: boolean) => void; + checkCallBack: (visible: boolean) => void; } @@ -36,35 +36,35 @@ export class Track extends React.Component { @observable private _onRegionData: (Doc | undefined) = undefined; @observable private _storedState: (Doc | undefined) = undefined; @observable private filterList = [ - "regions", - "cursors", - "hidden", - "nativeHeight", - "nativeWidth", - "schemaColumns", - "baseLayout", - "backgroundLayout", - "layout", - ]; - - @computed private get regions() { return Cast(this.props.node.regions, listSpec(Doc)) as List;} + "regions", + "cursors", + "hidden", + "nativeHeight", + "nativeWidth", + "schemaColumns", + "baseLayout", + "backgroundLayout", + "layout", + ]; + private _trackHeight = 0; + + @computed private get regions() { return Cast(this.props.node.regions, listSpec(Doc)) as List; } componentWillMount() { runInAction(() => { - if (!this.props.node.regions) this.props.node.regions = new List(); - console.log("hi"); - console.log("HELLO"); - console.log("hi"); + if (!this.props.node.regions) this.props.node.regions = new List(); + this._trackHeight = window.innerHeight / 14; //for responsiveness + }); } componentDidMount() { runInAction(async () => { - this._timelineVisibleReaction = this.timelineVisibleReaction(); + this._timelineVisibleReaction = this.timelineVisibleReaction(); this._currentBarXReaction = this.currentBarXReaction(); if (this.regions.length === 0) this.createRegion(KeyframeFunc.convertPixelTime(this.props.currentBarX, "mili", "time", this.props.tickSpacing, this.props.tickIncrement)); - this.props.node.hidden = false; - this.props.node.opacity = 1; + this.props.node.hidden = false; + this.props.node.opacity = 1; }); } @@ -72,7 +72,7 @@ export class Track extends React.Component { runInAction(() => { //disposing reactions if (this._currentBarXReaction) this._currentBarXReaction(); - if (this._timelineVisibleReaction) this._timelineVisibleReaction(); + if (this._timelineVisibleReaction) this._timelineVisibleReaction(); }); } @@ -81,7 +81,7 @@ export class Track extends React.Component { let keyframes: List = (Cast(regiondata.keyframes, listSpec(Doc)) as List); let kfIndex: number = keyframes.indexOf(ref); let kf = keyframes[kfIndex] as Doc; - if (!kf) return; + if (!kf) return; if (kf.type === KeyframeFunc.KeyframeType.default) { // only save for non-fades kf.key = Doc.MakeCopy(this.props.node, true); let leftkf: (Doc | undefined) = await KeyframeFunc.calcMinLeft(regiondata!, KeyframeFunc.convertPixelTime(this.props.currentBarX, "mili", "time", this.props.tickSpacing, this.props.tickIncrement), kf); // lef keyframe, if it exists @@ -107,13 +107,13 @@ export class Track extends React.Component { this._isOnKeyframe = false; } - @action + @action revertState = () => { - let copyDoc = Doc.MakeCopy(this.props.node, true); + let copyDoc = Doc.MakeCopy(this.props.node, true); if (this._storedState) this.applyKeys(this._storedState); - let newState = new Doc(); - newState.key = copyDoc; - this._storedState = newState; + let newState = new Doc(); + newState.key = copyDoc; + this._storedState = newState; } @action @@ -129,13 +129,13 @@ export class Track extends React.Component { } }); } - @action + @action timelineVisibleReaction = () => { return reaction(() => { - return this.props.timelineVisible; + return this.props.timelineVisible; }, isVisible => { - this.revertState(); - }); + this.revertState(); + }); } @action @@ -162,28 +162,28 @@ export class Track extends React.Component { @action private applyKeys = async (kf: Doc) => { let kfNode = await Cast(kf.key, Doc) as Doc; - let docFromApply = kfNode; + let docFromApply = kfNode; if (this.filterKeys(Doc.allKeys(this.props.node)).length > this.filterKeys(Doc.allKeys(kfNode)).length) docFromApply = this.props.node; this.filterKeys(Doc.allKeys(docFromApply)).forEach(key => { if (!kfNode[key]) { this.props.node[key] = undefined; } else { let stored = kfNode[key]; - if(stored instanceof ObjectField){ - this.props.node[key] = stored[Copy](); + if (stored instanceof ObjectField) { + this.props.node[key] = stored[Copy](); } else { - this.props.node[key] = stored; + this.props.node[key] = stored; } } }); } - + @action private filterKeys = (keys: string[]): string[] => { return keys.reduce((acc: string[], key: string) => { - if (!this.filterList.includes(key)) acc.push(key); + if (!this.filterList.includes(key)) acc.push(key); return acc; }, []); } @@ -249,10 +249,10 @@ export class Track extends React.Component { } } else { let stored = leftNode[key]; - if(stored instanceof ObjectField){ - this.props.node[key] = stored[Copy](); + if (stored instanceof ObjectField) { + this.props.node[key] = stored[Copy](); } else { - this.props.node[key] = stored; + this.props.node[key] = stored; } } }); @@ -276,7 +276,7 @@ export class Track extends React.Component { let inner = this._inner.current!; let offsetX = Math.round((e.clientX - inner.getBoundingClientRect().left) * this.props.transform.Scale); this.createRegion(KeyframeFunc.convertPixelTime(offsetX, "mili", "time", this.props.tickSpacing, this.props.tickIncrement)); - this.forceUpdate(); + this.forceUpdate(); } createRegion = (position: number) => { @@ -297,7 +297,7 @@ export class Track extends React.Component { return (
-
{Doc.BrushDoc(this.props.node);}}onPointerOut={() => {Doc.UnBrushDoc(this.props.node);}}> +
{ Doc.BrushDoc(this.props.node); }} onPointerOut={() => { Doc.UnBrushDoc(this.props.node); }} style={{ height: `${this._trackHeight}px` }}> {DocListCast(this.regions).map((region) => { return ; })} diff --git a/src/client/views/linking/LinkFollowBox.tsx b/src/client/views/linking/LinkFollowBox.tsx index efe2c7f2a..f3193896f 100644 --- a/src/client/views/linking/LinkFollowBox.tsx +++ b/src/client/views/linking/LinkFollowBox.tsx @@ -21,7 +21,7 @@ import { docs_v1 } from "googleapis"; import { Utils } from "../../../Utils"; import { Link } from "@react-pdf/renderer"; -enum FollowModes { +export enum FollowModes { OPENTAB = "Open in Tab", OPENRIGHT = "Open in Right Split", OPENFULL = "Open Full Screen", -- cgit v1.2.3-70-g09d2 From b25276d9442f5ae9196a72b4af05849b9e69ef2f Mon Sep 17 00:00:00 2001 From: Andrew Kim Date: Sat, 11 Jan 2020 15:42:58 +0900 Subject: phantom region fix, scrubber double click, fade kf --- src/client/views/animationtimeline/Keyframe.tsx | 104 +++++++---------------- src/client/views/animationtimeline/Timeline.scss | 2 + src/client/views/animationtimeline/Timeline.tsx | 4 +- src/client/views/animationtimeline/Track.tsx | 26 +++--- 4 files changed, 51 insertions(+), 85 deletions(-) (limited to 'src/client/views/animationtimeline/Timeline.scss') diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx index c3c1f5f8c..62528483b 100644 --- a/src/client/views/animationtimeline/Keyframe.tsx +++ b/src/client/views/animationtimeline/Keyframe.tsx @@ -22,6 +22,7 @@ import { undoBatch, UndoManager } from "../../util/UndoManager"; */ export namespace KeyframeFunc { export enum KeyframeType { + end = "end", fade = "fade", default = "default", } @@ -194,8 +195,8 @@ export class Keyframe extends React.Component { if (!this.regiondata.keyframes) this.regiondata.keyframes = new List(); let fadeIn = await this.makeKeyData(this.regiondata.position + this.regiondata.fadeIn, KeyframeFunc.KeyframeType.fade)!; let fadeOut = await this.makeKeyData(this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut, KeyframeFunc.KeyframeType.fade)!; - let start = await this.makeKeyData(this.regiondata.position, KeyframeFunc.KeyframeType.fade)!; - let finish = await this.makeKeyData(this.regiondata.position + this.regiondata.duration, KeyframeFunc.KeyframeType.fade)!; + let start = await this.makeKeyData(this.regiondata.position, KeyframeFunc.KeyframeType.end)!; + let finish = await this.makeKeyData(this.regiondata.position + this.regiondata.duration, KeyframeFunc.KeyframeType.end)!; (fadeIn.key! as Doc).opacity = 1; (fadeOut.key! as Doc).opacity = 1; (start.key! as Doc).opacity = 0.1; @@ -206,7 +207,6 @@ export class Keyframe extends React.Component { @action makeKeyData = async (kfpos: number, type: KeyframeFunc.KeyframeType = KeyframeFunc.KeyframeType.default) => { //Kfpos is mouse offsetX, representing time - const batch = UndoManager.StartBatch("makeKeyData"); let doclist = (await DocListCastAsync(this.regiondata.keyframes))!; let existingkf: (Doc | undefined) = undefined; doclist.forEach(TK => { @@ -218,19 +218,11 @@ export class Keyframe extends React.Component { TK.key = Doc.MakeCopy(this.props.node, true); TK.type = type; this.regiondata.keyframes!.push(TK); - - // myObservable++; - // UndoManager.AddEvent({ - // undo: action(() => myObservable--), - // redo: action(() => myObservable++) - // }); - let interpolationFunctions = new Doc(); interpolationFunctions.interpolationX = new List([0, 1]); interpolationFunctions.interpolationY = new List([0, 100]); interpolationFunctions.pathX = new List(); interpolationFunctions.pathY = new List(); - this.regiondata.functions!.push(interpolationFunctions); let found: boolean = false; this.regiondata.keyframes!.forEach(compkf => { @@ -244,7 +236,6 @@ export class Keyframe extends React.Component { return; } }); - batch.end(); return TK; } @@ -384,15 +375,6 @@ export class Keyframe extends React.Component { this.props.changeCurrentBarX(KeyframeFunc.convertPixelTime(NumCast(kf.time!), "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement)); } - - @action - onKeyframeOver = (e: React.PointerEvent) => { - e.preventDefault(); - e.stopPropagation(); - this.props.node.backgroundColor = "#000000"; - } - - /** * custom keyframe context menu items (when clicking on the keyframe circle) */ @@ -412,7 +394,6 @@ export class Keyframe extends React.Component { }), TimelineMenu.Instance.addItem("input", "Move", (val) => { runInAction(() => { - if (this.checkInput(val)) { let cannotMove: boolean = false; let kfIndex: number = this.keyframes.indexOf(kf); if (val < 0 || (val < NumCast(this.keyframes[kfIndex - 1].time) || val > NumCast(this.keyframes[kfIndex + 1].time))) { @@ -422,7 +403,6 @@ export class Keyframe extends React.Component { this.keyframes[kfIndex].time = parseInt(val, 10); this.keyframes[1].time = this.regiondata.position + this.regiondata.fadeIn; } - } }); }); TimelineMenu.Instance.addMenu("Keyframe"); @@ -448,7 +428,6 @@ export class Keyframe extends React.Component { }), TimelineMenu.Instance.addItem("input", `fadeIn: ${this.regiondata.fadeIn}ms`, (val) => { runInAction(() => { - if (this.checkInput(val)) { let cannotMove: boolean = false; if (val < 0 || val > NumCast(this.keyframes[2].time) - this.regiondata.position) { cannotMove = true; @@ -457,59 +436,52 @@ export class Keyframe extends React.Component { this.regiondata.fadeIn = parseInt(val, 10); this.keyframes[1].time = this.regiondata.position + this.regiondata.fadeIn; } - } }); }), TimelineMenu.Instance.addItem("input", `fadeOut: ${this.regiondata.fadeOut}ms`, (val) => { runInAction(() => { - if (this.checkInput(val)) { - let cannotMove: boolean = false; - if (val < 0 || val > this.regiondata.position + this.regiondata.duration - NumCast(this.keyframes[this.keyframes.length - 3].time)) { - cannotMove = true; - } - if (!cannotMove) { - this.regiondata.fadeOut = parseInt(val, 10); - this.keyframes[this.keyframes.length - 2].time = this.regiondata.position + this.regiondata.duration - val; - } + let cannotMove: boolean = false; + if (val < 0 || val > this.regiondata.position + this.regiondata.duration - NumCast(this.keyframes[this.keyframes.length - 3].time)) { + cannotMove = true; + } + if (!cannotMove) { + this.regiondata.fadeOut = parseInt(val, 10); + this.keyframes[this.keyframes.length - 2].time = this.regiondata.position + this.regiondata.duration - val; } }); }), TimelineMenu.Instance.addItem("input", `position: ${this.regiondata.position}ms`, (val) => { runInAction(() => { - if (this.checkInput(val)) { - let prevPosition = this.regiondata.position; - let cannotMove: boolean = false; - DocListCast(this.regions).forEach(region => { - if (NumCast(region.position) !== this.regiondata.position) { - if ((val < 0) || (val > NumCast(region.position) && val < NumCast(region.position) + NumCast(region.duration) || (this.regiondata.duration + val > NumCast(region.position) && this.regiondata.duration + val < NumCast(region.position) + NumCast(region.duration)))) { - cannotMove = true; - } + let prevPosition = this.regiondata.position; + let cannotMove: boolean = false; + DocListCast(this.regions).forEach(region => { + if (NumCast(region.position) !== this.regiondata.position) { + if ((val < 0) || (val > NumCast(region.position) && val < NumCast(region.position) + NumCast(region.duration) || (this.regiondata.duration + val > NumCast(region.position) && this.regiondata.duration + val < NumCast(region.position) + NumCast(region.duration)))) { + cannotMove = true; } - }); - if (!cannotMove) { - this.regiondata.position = parseInt(val, 10); - this.updateKeyframes(this.regiondata.position - prevPosition); } + }); + if (!cannotMove) { + this.regiondata.position = parseInt(val, 10); + this.updateKeyframes(this.regiondata.position - prevPosition); } }); }), TimelineMenu.Instance.addItem("input", `duration: ${this.regiondata.duration}ms`, (val) => { runInAction(() => { - if (this.checkInput(val)) { - let cannotMove: boolean = false; - DocListCast(this.regions).forEach(region => { - if (NumCast(region.position) !== this.regiondata.position) { - val += this.regiondata.position; - if ((val < 0) || (val > NumCast(region.position) && val < NumCast(region.position) + NumCast(region.duration))) { - cannotMove = true; - } + let cannotMove: boolean = false; + DocListCast(this.regions).forEach(region => { + if (NumCast(region.position) !== this.regiondata.position) { + val += this.regiondata.position; + if ((val < 0) || (val > NumCast(region.position) && val < NumCast(region.position) + NumCast(region.duration))) { + cannotMove = true; } - }); - if (!cannotMove) { - this.regiondata.duration = parseInt(val, 10); - this.keyframes[this.keyframes.length - 1].time = this.regiondata.position + this.regiondata.duration; - this.keyframes[this.keyframes.length - 2].time = this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut; } + }); + if (!cannotMove) { + this.regiondata.duration = parseInt(val, 10); + this.keyframes[this.keyframes.length - 1].time = this.regiondata.position + this.regiondata.duration; + this.keyframes[this.keyframes.length - 2].time = this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut; } }); }), @@ -517,15 +489,6 @@ export class Keyframe extends React.Component { TimelineMenu.Instance.openMenu(e.clientX, e.clientY); } - - /** - * checking if input is correct (might have to use external module) - */ - @action - checkInput = (val: any) => { - return typeof (val === "number"); - } - @action updateKeyframes = (incr: number, filter: number[] = []) => { this.keyframes.forEach(kf => { @@ -652,7 +615,7 @@ export class Keyframe extends React.Component { drawKeyframes = () => { let keyframeDivs: JSX.Element[] = []; DocListCast(this.regiondata.keyframes).forEach(kf => { - if (kf.type as KeyframeFunc.KeyframeType === KeyframeFunc.KeyframeType.default) { + if (kf.type as KeyframeFunc.KeyframeType !== KeyframeFunc.KeyframeType.end) { keyframeDivs.push(
@@ -663,8 +626,7 @@ export class Keyframe extends React.Component { }} onDoubleClick={(e) => { e.preventDefault(); e.stopPropagation(); }}>
); - } - else { + } else { keyframeDivs.push(
diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index 493b084a8..76c8475d1 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -109,6 +109,7 @@ position: absolute; z-index: 1001; background-color: black; + pointer-events: none; .scrubberhead { top: -30px; @@ -119,6 +120,7 @@ border: 5px solid black; left: -15px; position: absolute; + pointer-events: all; } } diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 9cf600b5f..df25f709a 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -504,8 +504,8 @@ export class Timeline extends React.Component {
{this.drawTicks()} -
-
+
+
{DocListCast(this.children).map(doc => )} diff --git a/src/client/views/animationtimeline/Track.tsx b/src/client/views/animationtimeline/Track.tsx index d9b8026c5..2ea3d168f 100644 --- a/src/client/views/animationtimeline/Track.tsx +++ b/src/client/views/animationtimeline/Track.tsx @@ -96,6 +96,7 @@ export class Track extends React.Component { /** * keyframe save logic. Needs to be changed so it's more efficient + * */ @action saveKeyframe = async (ref: Doc, regiondata: Doc) => { @@ -354,19 +355,20 @@ export class Track extends React.Component { /** * creates a region (KEYFRAME.TSX stuff). */ - createRegion = (position: number) => { - let regiondata = KeyframeFunc.defaultKeyframe(); - regiondata.position = position; - let rightRegion = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.right, regiondata, this.regions); - - if (rightRegion && rightRegion.position - regiondata.position <= 4000) { - regiondata.duration = rightRegion.position - regiondata.position; - } - if (this.regions.length === 0 || !rightRegion || (rightRegion && rightRegion.position - regiondata.position >= NumCast(regiondata.fadeIn) + NumCast(regiondata.fadeOut))) { - this.regions.push(regiondata); - return regiondata; + createRegion = async (time: number) => { + if (await this.findRegion(time) === undefined){ //check if there is a region where double clicking (prevents phantom regions) + let regiondata = KeyframeFunc.defaultKeyframe(); //create keyframe data + regiondata.position = time; //set position + let rightRegion = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.right, regiondata, this.regions); + + if (rightRegion && rightRegion.position - regiondata.position <= 4000) { //edge case when there is less than default 4000 duration space between this and right region + regiondata.duration = rightRegion.position - regiondata.position; + } + if (this.regions.length === 0 || !rightRegion || (rightRegion && rightRegion.position - regiondata.position >= NumCast(regiondata.fadeIn) + NumCast(regiondata.fadeOut))) { + this.regions.push(regiondata); + return regiondata; + } } - } -- cgit v1.2.3-70-g09d2 From b481a3a3d95a7481c785373b9a088c442488dfde Mon Sep 17 00:00:00 2001 From: monikahedman Date: Tue, 14 Jan 2020 17:27:26 -0500 Subject: initial stylistic changes --- src/client/views/animationtimeline/Timeline.scss | 30 +++-- src/client/views/animationtimeline/Timeline.tsx | 18 +-- .../views/animationtimeline/TimelineOverview.scss | 138 +++++++++++---------- 3 files changed, 97 insertions(+), 89 deletions(-) (limited to 'src/client/views/animationtimeline/Timeline.scss') diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index 76c8475d1..83988e324 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -1,6 +1,6 @@ @import "./../globalCssVariables.scss"; - +$timelineColor: #9acedf; .timeline-toolbox { position: absolute; @@ -13,6 +13,10 @@ align-items: center; top: 20px; + .timeline-icon { + color: $timelineColor; + } + div { padding: 0px; margin-left: 10px; @@ -24,7 +28,7 @@ width: auto; white-space: nowrap; font-size: 16px; - color: grey; + color: black; letter-spacing: 2px; text-transform: uppercase; } @@ -33,7 +37,7 @@ height: 40px; width: 80px; background-color: white; - border: 2px solid grey; + border: 2px solid black; border-radius: 20px; animation-fill-mode: forwards; animation-duration: 500ms; @@ -50,7 +54,7 @@ height: 35px; width: 35px; background-color: white; - border: 1px solid grey; + border: 1px solid black; border-radius: 20px; transition: transform 500ms ease-in-out; margin-left: 0px; @@ -65,7 +69,7 @@ width: 120px; white-space: nowrap; font-size: 16px; - color: grey; + color: black; letter-spacing: 2px; text-transform: uppercase; padding-left: 5px; @@ -112,13 +116,13 @@ pointer-events: none; .scrubberhead { - top: -30px; - height: 30px; - width: 30px; - background-color: transparent; + top: -20px; + height: 20px; + width: 20px; + background-color: white; border-radius: 50%; - border: 5px solid black; - left: -15px; + border: 3px solid black; + left: -9px; position: absolute; pointer-events: all; } @@ -132,7 +136,7 @@ overflow: hidden; background-color: white; position: absolute; - box-shadow: -10px 0px 10px 10px grey; + // box-shadow: -10px 0px 10px 10px red; } } @@ -156,7 +160,7 @@ float: left; border-style: solid; overflow-y: scroll; - overflow-x: hidden; + overflow-x: hidden; } } diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index fedffe8c1..589470111 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -8,7 +8,7 @@ import { Cast, NumCast, StrCast, BoolCast } from "../../../new_fields/Types"; import { List } from "../../../new_fields/List"; import { Doc, DocListCast } from "../../../new_fields/Doc"; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { faPlayCircle, faBackward, faForward, faGripLines,faPauseCircle, faEyeSlash,faEye,faCheckCircle, faTimesCircle } from "@fortawesome/free-solid-svg-icons"; +import { faPlayCircle, faBackward, faForward, faGripLines, faPauseCircle, faEyeSlash, faEye, faCheckCircle, faTimesCircle } from "@fortawesome/free-solid-svg-icons"; import { ContextMenu } from "../ContextMenu"; import { TimelineOverview } from "./TimelineOverview"; import { FieldViewProps } from "../nodes/FieldView"; @@ -43,14 +43,14 @@ export class Timeline extends React.Component { //readonly constants private readonly DEFAULT_TICK_SPACING: number = 50; - private readonly MAX_TITLE_HEIGHT = 75; + private readonly MAX_TITLE_HEIGHT = 75; private readonly MAX_CONTAINER_HEIGHT: number = 800; private readonly DEFAULT_TICK_INCREMENT: number = 1000; //height variables private DEFAULT_CONTAINER_HEIGHT: number = 330; private MIN_CONTAINER_HEIGHT: number = 205; - + //react refs @observable private _trackbox = React.createRef(); @observable private _titleContainer = React.createRef(); @@ -224,7 +224,7 @@ export class Timeline extends React.Component { e.stopPropagation(); let scrubberbox = this._infoContainer.current!; let left = scrubberbox.getBoundingClientRect().left; - let offsetX = Math.round(e.clientX - left) * this.props.ScreenToLocalTransform().Scale; + let offsetX = Math.round(e.clientX - left) * this.props.ScreenToLocalTransform().Scale; this.changeCurrentBarX(offsetX + this._visibleStart); //changes scrubber to clicked scrubber position } @@ -403,9 +403,9 @@ export class Timeline extends React.Component { let size = 40 * scale; //50 is default return (
-
-
-
+
+
+
Timeline Overview
Mode: {this.props.Document.isATOn ? "Authoring" : "Play"}
@@ -460,7 +460,7 @@ export class Timeline extends React.Component { roundToggle.style.transform = "translate(45px, 0px)"; roundToggle.style.animationName = "turnon"; roundToggleContainer.style.animationName = "turnon"; - roundToggleContainer.style.backgroundColor = "green"; + roundToggleContainer.style.backgroundColor = "#9acedf"; timelineContainer.style.top = "0px"; this.props.Document.isATOn = true; } @@ -499,7 +499,7 @@ export class Timeline extends React.Component { render() { return (
-
+
diff --git a/src/client/views/animationtimeline/TimelineOverview.scss b/src/client/views/animationtimeline/TimelineOverview.scss index c7f9bd059..c643b978b 100644 --- a/src/client/views/animationtimeline/TimelineOverview.scss +++ b/src/client/views/animationtimeline/TimelineOverview.scss @@ -1,85 +1,89 @@ -@import "./../globalCssVariables.scss"; +@import "./../globalCssVariables.scss"; +$timelineColor: #9acedf; -.timeline-overview-container{ - padding: 0px; - margin: 0px; - width: 300px; +.timeline-overview-container { + padding: 0px; + margin: 0px; + width: 300px; height: 40px; - background: white; - position: relative; - border: 2px solid black; - - .timeline-overview-visible{ - position: absolute; - height: 100%; - background: green; + background: white; + position: relative; + border: 2px solid black; + + .timeline-overview-visible { + position: absolute; + height: 98%; + background: $timelineColor; display: inline-block; - margin: 0px; - padding: 0px; + margin: 0px; + padding: 0px; } - .timeline-overview-scrubber-container{ - margin: 0px; - padding: 0px; - position: absolute; + + .timeline-overview-scrubber-container { + margin: 0px; + padding: 0px; + position: absolute; height: 100%; - width: 2px; - top: 0px; - left: 0px; + width: 2px; + top: 0px; + left: 0px; z-index: 1001; - background-color:black; - display: inline-block; + background-color: black; + display: inline-block; - .timeline-overview-scrubber-head{ - padding: 0px; - margin: 0px; - position:absolute; - height: 30px; - width: 30px; - background-color:transparent; - border-radius: 50%; - border: 5px solid black; - left: -15px; - top: -30px; + .timeline-overview-scrubber-head { + padding: 0px; + margin: 0px; + position: absolute; + height: 10px; + width: 10px; + // background-color: black; + border-radius: 50%; + // border: 3px solid black; + left: -4px; + // top: -30px; + top: -10px; } } } -.timeline-play-bar{ - position: relative; - padding: 0px; - margin: 0px; - width: 300px; - height: 4px; - background-color: grey; +.timeline-play-bar { + position: relative; + padding: 0px; + margin: 0px; + width: 300px; + height: 4px; + background-color: $timelineColor; border-radius: 20px; - cursor: pointer; - - .timeline-play-head{ - position: absolute; - padding: 0px; - margin: 0px; - width: 20px; - height: 20px; - border-radius: 50%; - background-color: white; - border: 3px grey solid; - left: 0px; - top: -10px; - cursor: pointer; + cursor: pointer; + + .timeline-play-head { + position: absolute; + padding: 0px; + margin: 0px; + width: 20px; + height: 20px; + border-radius: 50%; + background-color: white; + border: 3px $timelineColor; + left: 0px; + top: -10px; + cursor: pointer; } -} -.timeline-play-tail{ - position: absolute; - padding: 0px; - margin: 0px; - height: 4px; - width: 0px; - z-index: 1000; - background-color: green; +} + +.timeline-play-tail { + position: absolute; + padding: 0px; + margin: 0px; + height: 4px; + width: 0px; + z-index: 1000; + background-color: $timelineColor; border-radius: 20px; - margin-top: -4px; - cursor: pointer; + margin-top: -4px; + cursor: pointer; } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 95e321930a5e6f5a6fd86047542615dff49813f2 Mon Sep 17 00:00:00 2001 From: monikahedman Date: Tue, 14 Jan 2020 19:35:47 -0500 Subject: color fixes --- src/client/views/animationtimeline/Timeline.scss | 9 ++++++++- src/client/views/animationtimeline/Timeline.tsx | 4 ++-- src/client/views/animationtimeline/TimelineOverview.scss | 6 +++--- 3 files changed, 13 insertions(+), 6 deletions(-) (limited to 'src/client/views/animationtimeline/Timeline.scss') diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index 83988e324..060627c17 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -54,7 +54,7 @@ $timelineColor: #9acedf; height: 35px; width: 35px; background-color: white; - border: 1px solid black; + border: 3px solid black; border-radius: 20px; transition: transform 500ms ease-in-out; margin-left: 0px; @@ -80,6 +80,13 @@ $timelineColor: #9acedf; height: 100%; width: 1px; background-color: black; + color: black; +} + +.number-label { + color: black; + padding-left: 5px; + } .timeline-container { diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 589470111..2332b4d5f 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -131,7 +131,7 @@ export class Timeline extends React.Component { drawTicks = () => { let ticks = []; for (let i = 0; i < this._time / this._tickIncrement; i++) { - ticks.push(

{this.toReadTime(i * this._tickIncrement)}

); + ticks.push(

{this.toReadTime(i * this._tickIncrement)}

); } return ticks; } @@ -457,7 +457,7 @@ export class Timeline extends React.Component { timelineContainer.style.top = `${-this._containerHeight}px`; this.props.Document.isATOn = false; } else { - roundToggle.style.transform = "translate(45px, 0px)"; + roundToggle.style.transform = "translate(40px, 0px)"; roundToggle.style.animationName = "turnon"; roundToggleContainer.style.animationName = "turnon"; roundToggleContainer.style.backgroundColor = "#9acedf"; diff --git a/src/client/views/animationtimeline/TimelineOverview.scss b/src/client/views/animationtimeline/TimelineOverview.scss index c643b978b..3517d3f39 100644 --- a/src/client/views/animationtimeline/TimelineOverview.scss +++ b/src/client/views/animationtimeline/TimelineOverview.scss @@ -38,7 +38,7 @@ $timelineColor: #9acedf; position: absolute; height: 10px; width: 10px; - // background-color: black; + background-color: black; border-radius: 50%; // border: 3px solid black; left: -4px; @@ -68,9 +68,9 @@ $timelineColor: #9acedf; height: 20px; border-radius: 50%; background-color: white; - border: 3px $timelineColor; + border: 3px solid $timelineColor; left: 0px; - top: -10px; + top: -8px; cursor: pointer; } } -- cgit v1.2.3-70-g09d2 From da6ce86f604ad5a6e7857f073ebba0095fc5d467 Mon Sep 17 00:00:00 2001 From: monikahedman Date: Tue, 14 Jan 2020 20:02:57 -0500 Subject: more minor changes --- src/client/views/animationtimeline/Timeline.scss | 20 ++++++++++++-------- src/client/views/animationtimeline/Timeline.tsx | 7 ++++--- 2 files changed, 16 insertions(+), 11 deletions(-) (limited to 'src/client/views/animationtimeline/Timeline.scss') diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index 060627c17..02c1bdb16 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -1,6 +1,7 @@ @import "./../globalCssVariables.scss"; $timelineColor: #9acedf; +$timelineDark: #77a1aa; .timeline-toolbox { position: absolute; @@ -78,15 +79,15 @@ $timelineColor: #9acedf; .tick { height: 100%; - width: 1px; + width: 2px; background-color: black; color: black; } .number-label { color: black; - padding-left: 5px; - + transform: rotate(-90deg) translate(-15px, 8px); + font-size: .85em; } .timeline-container { @@ -94,7 +95,7 @@ $timelineColor: #9acedf; height: 300px; position: absolute; background-color: $light-color-secondary; - box-shadow: 0px 10px 20px; + border-bottom: 2px solid $timelineDark; transition: transform 500ms ease; .info-container { @@ -139,7 +140,7 @@ $timelineColor: #9acedf; top: 30px; height: calc(100% - 30px); width: 100%; - border: 1px; + border: 2px solid black; overflow: hidden; background-color: white; position: absolute; @@ -155,6 +156,9 @@ $timelineColor: #9acedf; width: 100px; background-color: white; overflow: hidden; + border-left: 2px solid black; + border-top: 2px solid black; + border-bottom: 2px solid black; .datapane { top: 0px; @@ -172,10 +176,10 @@ $timelineColor: #9acedf; } .resize { - bottom: 5px; + bottom: 0px; position: absolute; - height: 30px; - width: 50px; + height: 20px; + width: 40px; left: calc(50% - 25px); } } diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 2332b4d5f..37d93f6c1 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -401,11 +401,12 @@ export class Timeline extends React.Component { */ private timelineToolBox = (scale: number) => { let size = 40 * scale; //50 is default + let iconSize = 25; return (
-
-
-
+
+
+
Timeline Overview
Mode: {this.props.Document.isATOn ? "Authoring" : "Play"}
-- cgit v1.2.3-70-g09d2 From 68a8c2bdbeafc7bc799884a6c1dcea86dbfd9f27 Mon Sep 17 00:00:00 2001 From: monikahedman Date: Fri, 24 Jan 2020 15:04:59 -0500 Subject: change branch --- src/client/views/animationtimeline/Timeline.scss | 92 ++++++++--- src/client/views/animationtimeline/Timeline.tsx | 88 ++++++++-- .../views/animationtimeline/TimelineOverview.scss | 29 ++-- .../views/animationtimeline/TimelineOverview.tsx | 180 ++++++++++++++------- 4 files changed, 284 insertions(+), 105 deletions(-) (limited to 'src/client/views/animationtimeline/Timeline.scss') diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index 02c1bdb16..a8dd9b9e7 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -10,39 +10,79 @@ $timelineDark: #77a1aa; display: flex; align-items: flex-start; flex-direction: row; - justify-content: space-evenly; + // justify-content: space-evenly; align-items: center; - top: 20px; + top: 3px; + width: 100%; - .timeline-icon { - color: $timelineColor; + .overview-tool { + display: flex; + justify-content: center; } - div { - padding: 0px; + .playbackControls { + display: flex; + margin-left: 30px; + max-width: 84px; + width: 84px; + + .timeline-icon { + color: $timelineColor; + margin-left: 3px; + } + + } + + .grid-box { + display: grid; + grid-template-columns: [first] 50% [line2] 25% [line3] 25%; + width: calc(100% - 150px); + // width: 100%; margin-left: 10px; + + .time-box { + margin-left: 5px; + display: flex; + } + + .mode-box { + display: flex; + margin-left: 5px; + } + + .overview-box { + width: 100%; + display: flex; + } + + div { + padding: 0px; + // margin-left: 10px; + } } .animation-text { - font-size: 20px; + // font-size: 16px; height: auto; width: auto; white-space: nowrap; - font-size: 16px; + font-size: 14px; color: black; letter-spacing: 2px; text-transform: uppercase; } .round-toggle { - height: 40px; - width: 80px; + height: 20px; + width: 40px; + min-width: 40px; background-color: white; - border: 2px solid black; + border: 2px solid $timelineDark; border-radius: 20px; animation-fill-mode: forwards; animation-duration: 500ms; top: 30px; + margin-left: 5px; input { position: absolute; @@ -52,29 +92,30 @@ $timelineDark: #77a1aa; } .round-toggle-slider { - height: 35px; - width: 35px; + height: 17px; + width: 17px; background-color: white; - border: 3px solid black; - border-radius: 20px; + border: 2px solid $timelineDark; + border-radius: 50%; transition: transform 500ms ease-in-out; margin-left: 0px; - margin-top: 0.5px; + // margin-top: 0.5px; } } } .time-input { - height: 40px; - width: 120px; + height: 20px; + // width: 120px; + width: 100%; white-space: nowrap; - font-size: 16px; + font-size: 12px; color: black; letter-spacing: 2px; text-transform: uppercase; padding-left: 5px; - + margin-left: 5px; } .tick { @@ -99,7 +140,7 @@ $timelineDark: #77a1aa; transition: transform 500ms ease; .info-container { - margin-top: 80px; + margin-top: 50px; right: 20px; position: absolute; height: calc(100% - 100px); @@ -138,9 +179,12 @@ $timelineDark: #77a1aa; .trackbox { top: 30px; + // TODO: where is this 30px coming from? height: calc(100% - 30px); + // height: 100%; width: 100%; - border: 2px solid black; + border-top: 2px solid black; + border-bottom: 2px solid black; overflow: hidden; background-color: white; position: absolute; @@ -150,7 +194,7 @@ $timelineDark: #77a1aa; } .title-container { - margin-top: 110px; + margin-top: 80px; margin-left: 20px; height: calc(100% - 100px - 30px); width: 100px; @@ -159,6 +203,7 @@ $timelineDark: #77a1aa; border-left: 2px solid black; border-top: 2px solid black; border-bottom: 2px solid black; + border-right: 2px solid $timelineDark; .datapane { top: 0px; @@ -181,6 +226,7 @@ $timelineDark: #77a1aa; height: 20px; width: 40px; left: calc(50% - 25px); + color: $timelineDark; } } diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 37d93f6c1..e6201d431 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -3,7 +3,7 @@ import "./Timeline.scss"; import { listSpec } from "../../../new_fields/Schema"; import { observer } from "mobx-react"; import { Track } from "./Track"; -import { observable, action, computed, runInAction } from "mobx"; +import { observable, action, computed, runInAction, IReactionDisposer, reaction } from "mobx"; import { Cast, NumCast, StrCast, BoolCast } from "../../../new_fields/Types"; import { List } from "../../../new_fields/List"; import { Doc, DocListCast } from "../../../new_fields/Doc"; @@ -77,6 +77,11 @@ export class Timeline extends React.Component { @observable private _doubleClickEnabled = false; @observable private _titleHeight = 0; + // so a reaction can be made + @observable public _isAuthoring = this.props.Document.isATOn; + @observable private _resizeReaction?: IReactionDisposer; + @observable private _panelWidth = 0; + /** * collection get method. Basically defines what defines collection's children. These will be tracked in the timeline. Do not edit. */ @@ -114,6 +119,19 @@ export class Timeline extends React.Component { this.props.Document.isATOn = !this.props.Document.isATOn; //turns the boolean on, saying AT (animation timeline) is on this.toggleHandle(); }); + + this._resizeReaction = reaction( + () => this.props.PanelWidth, + () => { + // if (!this.props.parent._isAuthoring) { + // runInAction(() => { + console.log("resizing"); + // this.setOverviewWidth(); + // }); + // } + }, + ); + } componentWillUnmount() { @@ -402,19 +420,58 @@ export class Timeline extends React.Component { private timelineToolBox = (scale: number) => { let size = 40 * scale; //50 is default let iconSize = 25; + + //decides if information should be omitted because the timeline is very small + // if its less than 950 pixels then it's going to be overlapping + let shouldCompress = false; + let width: number = this.props.PanelWidth(); + if (width < 850) { + shouldCompress = true; + } + + let modeString, overviewString, lengthString; + let modeType = this.props.Document.isATOn ? "Author" : "Play"; + + if (!shouldCompress) { + modeString = "Mode: " + modeType; + overviewString = "Overview:"; + lengthString = "Length: "; + } + else { + modeString = modeType; + overviewString = ""; + lengthString = ""; + } + + + // let modeType: string = this.props.Document.isATOn ? "Author" : "Play"; + // let modeString: string = "Mode: " + modeType; + // let overviewString: string = "Overview:"; + // let lengthString: string = "Length: "; + return (
-
-
-
-
Timeline Overview
- -
Mode: {this.props.Document.isATOn ? "Authoring" : "Play"}
-
-
+
+
+
+
+
+
+
+
{overviewString}
+ +
+
+
{modeString}
+
+
+
+
+
+
{lengthString}
+ +
-
Length:
-
); } @@ -457,13 +514,15 @@ export class Timeline extends React.Component { roundToggleContainer.style.backgroundColor = "white"; timelineContainer.style.top = `${-this._containerHeight}px`; this.props.Document.isATOn = false; + this._isAuthoring = false; } else { - roundToggle.style.transform = "translate(40px, 0px)"; + roundToggle.style.transform = "translate(20px, 0px)"; roundToggle.style.animationName = "turnon"; roundToggleContainer.style.animationName = "turnon"; roundToggleContainer.style.backgroundColor = "#9acedf"; timelineContainer.style.top = "0px"; this.props.Document.isATOn = true; + this._isAuthoring = true; } } @@ -498,6 +557,11 @@ export class Timeline extends React.Component { * basically the only thing you need to edit besides render methods in track (individual track lines) and keyframe (green region) */ render() { + console.log(this.props.PanelWidth()); + runInAction(() => { + this._panelWidth = this.props.PanelWidth(); + console.log("changing!!") + }); return (
diff --git a/src/client/views/animationtimeline/TimelineOverview.scss b/src/client/views/animationtimeline/TimelineOverview.scss index 3517d3f39..a0b9d462b 100644 --- a/src/client/views/animationtimeline/TimelineOverview.scss +++ b/src/client/views/animationtimeline/TimelineOverview.scss @@ -1,23 +1,34 @@ @import "./../globalCssVariables.scss"; $timelineColor: #9acedf; +$timelineDark: #77a1aa; + +.timelineOverview-bounding { + width: 100%; + margin-right: 10px; +} .timeline-overview-container { - padding: 0px; - margin: 0px; - width: 300px; - height: 40px; + // padding: 0px; + margin-right: 5px; + // margin: 0px; + margin-left: 5px; + // width: 300px; + width: 100%; + height: 25px; background: white; position: relative; - border: 2px solid black; + border: 2px solid $timelineDark; + // width: 100%; .timeline-overview-visible { position: absolute; - height: 98%; + height: 21px; background: $timelineColor; display: inline-block; margin: 0px; padding: 0px; + // top: 1px; } .timeline-overview-scrubber-container { @@ -38,9 +49,9 @@ $timelineColor: #9acedf; position: absolute; height: 10px; width: 10px; - background-color: black; + background-color: white; border-radius: 50%; - // border: 3px solid black; + border: 2px solid black; left: -4px; // top: -30px; top: -10px; @@ -54,7 +65,7 @@ $timelineColor: #9acedf; position: relative; padding: 0px; margin: 0px; - width: 300px; + width: 100%; height: 4px; background-color: $timelineColor; border-radius: 20px; diff --git a/src/client/views/animationtimeline/TimelineOverview.tsx b/src/client/views/animationtimeline/TimelineOverview.tsx index 4741969dc..4907a1ae1 100644 --- a/src/client/views/animationtimeline/TimelineOverview.tsx +++ b/src/client/views/animationtimeline/TimelineOverview.tsx @@ -1,101 +1,159 @@ -import * as React from "react"; -import {observable, action} from "mobx"; -import {observer} from "mobx-react"; -import "./TimelineOverview.scss"; +import * as React from "react"; +import { observable, action, computed, runInAction, reaction, IReactionDisposer } from "mobx"; +import { observer } from "mobx-react"; +import "./TimelineOverview.scss"; +import * as $ from 'jquery'; +import { Timeline } from "./Timeline"; - -interface TimelineOverviewProps{ - totalLength: number; - visibleLength:number; - visibleStart:number; - currentBarX:number; - isAuthoring: boolean; - changeCurrentBarX: (pixel:number) => void; - movePanX: (pixel:number) => any; +interface TimelineOverviewProps { + totalLength: number; + visibleLength: number; + visibleStart: number; + currentBarX: number; + isAuthoring: boolean; + parent: Timeline; + 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(); - private readonly DEFAULT_HEIGHT = 50; - private readonly DEFAULT_WIDTH = 300; + @observable private _visibleRef = React.createRef(); + @observable private _scrubberRef = React.createRef(); + @observable private overviewBarWidth: number = 0; + @observable private _authoringReaction?: IReactionDisposer; + @observable private _resizeReaction?: IReactionDisposer; + private readonly DEFAULT_HEIGHT = 50; + private readonly DEFAULT_WIDTH = 300; + + componentDidMount = () => { + this.setOverviewWidth(); + + this._authoringReaction = reaction( + () => this.props.parent._isAuthoring, + () => { + if (!this.props.parent._isAuthoring) { + runInAction(() => { + this.setOverviewWidth(); + }); + } + }, + ); + // this._resizeReaction = reaction( + // () => this.props.parent.props.PanelWidth, + // () => { + // // if (!this.props.parent._isAuthoring) { + // // runInAction(() => { + // console.log("resizing"); + // this.setOverviewWidth(); + // // }); + // // } + // }, + // ); + } + + componentWillUnmount = () => { + this._authoringReaction && this._authoringReaction(); + this._resizeReaction && this._resizeReaction(); + } @action - onPointerDown = (e:React.PointerEvent) => { - e.stopPropagation(); - e.preventDefault(); - document.removeEventListener("pointermove", this.onPanX); - document.removeEventListener("pointerup", this.onPointerUp); - document.addEventListener("pointermove", this.onPanX); - document.addEventListener("pointerup", this.onPointerUp); + setOverviewWidth() { + let width = $("#timelineOverview").width(); + if (width) this.overviewBarWidth = width; + else this.overviewBarWidth = 0; + } + + @action + onPointerDown = (e: React.PointerEvent) => { + e.stopPropagation(); + e.preventDefault(); + document.removeEventListener("pointermove", this.onPanX); + document.removeEventListener("pointerup", this.onPointerUp); + document.addEventListener("pointermove", this.onPanX); + document.addEventListener("pointerup", this.onPointerUp); } @action onPanX = (e: PointerEvent) => { - e.stopPropagation(); - e.preventDefault(); - let movX = (this.props.visibleStart / this.props.totalLength)* (this.DEFAULT_WIDTH) + e.movementX; - this.props.movePanX((movX / (this.DEFAULT_WIDTH )) * this.props.totalLength); + e.stopPropagation(); + e.preventDefault(); + let movX = (this.props.visibleStart / this.props.totalLength) * (this.DEFAULT_WIDTH) + e.movementX; + // let movX = (this.props.visibleStart / this.props.totalLength) * (this.overviewWidth) + e.movementX; + this.props.movePanX((movX / (this.DEFAULT_WIDTH)) * this.props.totalLength); + // this.props.movePanX((movX / (this.overviewWidth) * this.props.totalLength); + + // console.log(this.props.totalLength); } @action onPointerUp = (e: PointerEvent) => { - e.stopPropagation(); - e.preventDefault(); - document.removeEventListener("pointermove", this.onPanX); - document.removeEventListener("pointerup", this.onPointerUp); + e.stopPropagation(); + e.preventDefault(); + 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); + 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 / (this.DEFAULT_WIDTH) * this.props.totalLength) + this.props.currentBarX); + 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 / (this.DEFAULT_WIDTH) * this.props.totalLength) + this.props.currentBarX); } @action - onScrubberUp = (e:PointerEvent) => { - e.preventDefault(); - e.stopPropagation(); - document.removeEventListener("pointermove", this.onScrubberMove); + onScrubberUp = (e: PointerEvent) => { + e.preventDefault(); + e.stopPropagation(); + document.removeEventListener("pointermove", this.onScrubberMove); document.removeEventListener("pointerup", this.onScrubberUp); } - render(){ + render() { + // calculates where everything should fall based on its size + let percentVisible = this.props.visibleLength / this.props.totalLength; + let visibleBarWidth = percentVisible * this.overviewBarWidth; + + let percentScrubberStart = this.props.currentBarX / this.props.totalLength; + let scrubberStart = percentScrubberStart * this.overviewBarWidth; + + let percentBarStart = this.props.visibleStart / this.props.totalLength; + let barStart = percentBarStart * this.overviewBarWidth; + let timeline = this.props.isAuthoring ? [ -
-
, -
+ +
+
, +
-
+
] : [ -
-
-
, -
- ]; - return( -
+
+
+
, +
+ ]; + return ( +
{timeline}
- ); + ); } } -- cgit v1.2.3-70-g09d2 From 78810a40e22510eefe747c099e73fa3f2c4860a9 Mon Sep 17 00:00:00 2001 From: monikahedman Date: Sat, 1 Feb 2020 15:03:15 -0500 Subject: ui changes cl.ose to done --- src/client/views/animationtimeline/Keyframe.scss | 138 ++++++++++----------- src/client/views/animationtimeline/Keyframe.tsx | 79 ++++++------ src/client/views/animationtimeline/Timeline.scss | 24 ++-- src/client/views/animationtimeline/Timeline.tsx | 24 +--- .../views/animationtimeline/TimelineOverview.tsx | 51 ++++---- src/client/views/animationtimeline/Track.tsx | 2 +- 6 files changed, 153 insertions(+), 165 deletions(-) (limited to 'src/client/views/animationtimeline/Timeline.scss') diff --git a/src/client/views/animationtimeline/Keyframe.scss b/src/client/views/animationtimeline/Keyframe.scss index b1e8b0b65..8ff1c53f5 100644 --- a/src/client/views/animationtimeline/Keyframe.scss +++ b/src/client/views/animationtimeline/Keyframe.scss @@ -1,94 +1,94 @@ -@import "./../globalCssVariables.scss"; +@import "./../globalCssVariables.scss"; + + +$timelineColor: #9acedf; +$timelineDark: #77a1aa; .bar { height: 100%; width: 5px; position: absolute; - + // pointer-events: none; .menubox { - width: 200px; - height:200px; + width: 200px; + height: 200px; top: 50%; - position: relative; - background-color: $light-color; - .menutable{ - tr:nth-child(odd){ - background-color:$light-color-secondary; + position: relative; + background-color: $light-color; + + .menutable { + tr:nth-child(odd) { + background-color: $light-color-secondary; } } } - .leftResize{ - left:-12.5px; - height:25px; - width:25px; - border-radius: 50%; - background-color: white; - border:3px solid black; - top: calc(50% - 12.5px); - z-index: 1000; - position:absolute; + .leftResize { + left: -10px; + border: 3px solid black; + } + + .rightResize { + right: -10px; + border: 3px solid black; } - .rightResize{ - right:-12.5px; - height:25px; - width:25px; - border-radius: 50%; - top:calc(50% - 12.5px); - background-color:white; - border:3px solid black; - z-index: 1000; - position:absolute; + + .keyframe-indicator { + height: 20px; + width: 20px; + top: calc(50% - 10px); + background-color: white; + -ms-transform: rotate(45deg); + -webkit-transform: rotate(45deg); + transform: rotate(45deg); + z-index: 1000; + position: absolute; } - .fadeLeft{ - left:0px; - height:100%; - position:absolute; - pointer-events: none; - background: linear-gradient(to left, #4d9900 10%, $light-color); + + .keyframeCircle { + left: -10px; + border: 3px solid $timelineDark; } - .fadeRight{ - right:0px; - height:100%; - position:absolute; - pointer-events: none; - background: linear-gradient(to right, #4d9900 10%, $light-color); + .fadeLeft { + left: 0px; + height: 100%; + position: absolute; + pointer-events: none; + background: linear-gradient(to left, $timelineColor 10%, $light-color); } - .divider{ - height:100%; - width: 1px; - position: absolute; - background-color:black; - cursor: col-resize; - pointer-events:none; + + .fadeRight { + right: 0px; + height: 100%; + position: absolute; + pointer-events: none; + background: linear-gradient(to right, $timelineColor 10%, $light-color); } - .keyframe{ - height:100%; - position:absolute; + + .divider { + height: 100%; + width: 1px; + position: absolute; + background-color: black; + cursor: col-resize; + pointer-events: none; } - .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; + + .keyframe { + height: 100%; + position: absolute; } - .fadeIn-container, .fadeOut-container, .body-container{ - position:absolute; - height:100%; + .fadeIn-container, + .fadeOut-container, + .body-container { + position: absolute; + height: 100%; background-color: rgba(0, 0, 0, 0.5); - opacity: 0; + opacity: 0; } - - -} - +} \ No newline at end of file diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx index 2f2639c76..9c486a6d6 100644 --- a/src/client/views/animationtimeline/Keyframe.tsx +++ b/src/client/views/animationtimeline/Keyframe.tsx @@ -93,11 +93,11 @@ export namespace KeyframeFunc { regiondata.fadeIn = 1000; regiondata.fadeOut = 1000; regiondata.functions = new List(); - regiondata.hasData = false; + regiondata.hasData = false; return regiondata; }; - export const makeKeyData = async (regiondata:RegionData, time: number, badNode:Doc, type: KeyframeFunc.KeyframeType = KeyframeFunc.KeyframeType.default) => { //Kfpos is mouse offsetX, representing time + export const makeKeyData = async (regiondata: RegionData, time: number, badNode: Doc, type: KeyframeFunc.KeyframeType = KeyframeFunc.KeyframeType.default) => { //Kfpos is mouse offsetX, representing time runInAction(async () => { let doclist = (await DocListCastAsync(regiondata.keyframes))!; let existingkf: (Doc | undefined) = undefined; @@ -155,7 +155,7 @@ export const RegionDataSchema = createSchema({ keyframes: listSpec(Doc), fadeIn: defaultSpec("number", 0), fadeOut: defaultSpec("number", 0), - functions: listSpec(Doc), + functions: listSpec(Doc), hasData: defaultSpec("boolean", false) }); export type RegionData = makeInterface<[typeof RegionDataSchema]>; @@ -212,7 +212,7 @@ export class Keyframe extends React.Component { @computed private get pixelDuration() { return KeyframeFunc.convertPixelTime(this.regiondata.duration, "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement); } @computed private get pixelFadeIn() { return KeyframeFunc.convertPixelTime(this.regiondata.fadeIn, "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement); } @computed private get pixelFadeOut() { return KeyframeFunc.convertPixelTime(this.regiondata.fadeOut, "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement); } - + componentWillMount() { runInAction(async () => { if (!this.regiondata.keyframes) this.regiondata.keyframes = new List(); @@ -228,7 +228,7 @@ export class Keyframe extends React.Component { }); } - + @action @@ -313,10 +313,10 @@ export class Keyframe extends React.Component { } else if (NumCast(this.keyframes[1].time) + offset >= NumCast(this.keyframes[2].time)) { this.regiondata.position = NumCast(this.keyframes[2].time) - this.regiondata.fadeIn; this.regiondata.duration = NumCast(this.keyframes[this.keyframes.length - 1].time) - NumCast(this.keyframes[2].time) + this.regiondata.fadeIn; - } else if (NumCast(this.keyframes[0].time) + offset <= 0){ - this.regiondata.position = 0; - this.regiondata.duration = NumCast(this.keyframes[this.keyframes.length - 1].time); - }else { + } else if (NumCast(this.keyframes[0].time) + offset <= 0) { + this.regiondata.position = 0; + this.regiondata.duration = NumCast(this.keyframes[this.keyframes.length - 1].time); + } else { this.regiondata.duration -= offset; this.regiondata.position += offset; } @@ -353,9 +353,9 @@ export class Keyframe extends React.Component { if (offset > this.regiondata.fadeIn && offset < this.regiondata.duration - this.regiondata.fadeOut) { //make sure keyframe is not created inbetween fades and ends let position = this.regiondata.position; await KeyframeFunc.makeKeyData(this.regiondata, Math.round(position + offset), this.props.node); - this.regiondata.hasData = true; + this.regiondata.hasData = true; this.props.changeCurrentBarX(KeyframeFunc.convertPixelTime(Math.round(position + offset), "mili", "pixel", this.props.tickSpacing, this.props.tickIncrement)); //first move the keyframe to the correct location and make a copy so the correct file gets coppied - + } } @@ -386,15 +386,15 @@ export class Keyframe extends React.Component { }), TimelineMenu.Instance.addItem("input", "Move", (val) => { runInAction(() => { - let cannotMove: boolean = false; - let kfIndex: number = this.keyframes.indexOf(kf); - if (val < 0 || (val < NumCast(this.keyframes[kfIndex - 1].time) || val > NumCast(this.keyframes[kfIndex + 1].time))) { - cannotMove = true; - } - if (!cannotMove) { - this.keyframes[kfIndex].time = parseInt(val, 10); - this.keyframes[1].time = this.regiondata.position + this.regiondata.fadeIn; - } + let cannotMove: boolean = false; + let kfIndex: number = this.keyframes.indexOf(kf); + if (val < 0 || (val < NumCast(this.keyframes[kfIndex - 1].time) || val > NumCast(this.keyframes[kfIndex + 1].time))) { + cannotMove = true; + } + if (!cannotMove) { + this.keyframes[kfIndex].time = parseInt(val, 10); + this.keyframes[1].time = this.regiondata.position + this.regiondata.fadeIn; + } }); }); TimelineMenu.Instance.addMenu("Keyframe"); @@ -406,22 +406,22 @@ export class Keyframe extends React.Component { */ @action makeRegionMenu = (kf: Doc, e: MouseEvent) => { - TimelineMenu.Instance.addItem("button", "Remove Region", () => { - runInAction(() => { - this.regions.splice(this.regions.indexOf(this.props.RegionData), 1); - } - ); - }), + TimelineMenu.Instance.addItem("button", "Remove Region", () => { + runInAction(() => { + this.regions.splice(this.regions.indexOf(this.props.RegionData), 1); + } + ); + }), TimelineMenu.Instance.addItem("input", `fadeIn: ${this.regiondata.fadeIn}ms`, (val) => { runInAction(() => { - let cannotMove: boolean = false; - if (val < 0 || val > NumCast(this.keyframes[2].time) - this.regiondata.position) { - cannotMove = true; - } - if (!cannotMove) { - this.regiondata.fadeIn = parseInt(val, 10); - this.keyframes[1].time = this.regiondata.position + this.regiondata.fadeIn; - } + let cannotMove: boolean = false; + if (val < 0 || val > NumCast(this.keyframes[2].time) - this.regiondata.position) { + cannotMove = true; + } + if (!cannotMove) { + this.regiondata.fadeIn = parseInt(val, 10); + this.keyframes[1].time = this.regiondata.position + this.regiondata.fadeIn; + } }); }), TimelineMenu.Instance.addItem("input", `fadeOut: ${this.regiondata.fadeOut}ms`, (val) => { @@ -507,7 +507,7 @@ export class Keyframe extends React.Component { div.style.opacity = "0"; Doc.UnBrushDoc(this.props.node); } - + ///////////////////////UI STUFF ///////////////////////// @@ -524,7 +524,7 @@ export class Keyframe extends React.Component { keyframeDivs.push(
-
{ e.preventDefault(); e.stopPropagation(); this.moveKeyframe(e, kf); }} onContextMenu={(e: React.MouseEvent) => { +
{ e.preventDefault(); e.stopPropagation(); this.moveKeyframe(e, kf); }} onContextMenu={(e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); this.makeKeyframeMenu(kf, e.nativeEvent); @@ -577,18 +577,19 @@ export class Keyframe extends React.Component { /** * rendering that green region */ + //154, 206, 223 render() { return (
-
-
+
+
{this.drawKeyframes()} {this.drawKeyframeDividers()}
diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index a8dd9b9e7..40479559d 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -206,18 +206,18 @@ $timelineDark: #77a1aa; border-right: 2px solid $timelineDark; .datapane { - top: 0px; - width: 100px; - height: 30%; - border: 1px solid $dark-color; - background-color: $intermediate-color; - color: white; - position: relative; - float: left; - border-style: solid; - overflow-y: scroll; - overflow-x: hidden; - } + top: 0px; + width: 100px; + height: 30%; + border: 1px solid $dark-color; + background-color: $intermediate-color; + color: white; + position: relative; + float: left; + border-style: solid; + overflow-y: scroll; + overflow-x: hidden; +} } .resize { diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 8b943f209..5ff721ebb 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -120,18 +120,6 @@ export class Timeline extends React.Component { this.toggleHandle(); }); - this._resizeReaction = reaction( - () => this.props.PanelWidth, - () => { - // if (!this.props.parent._isAuthoring) { - // runInAction(() => { - console.log("resizing"); - // this.setOverviewWidth(); - // }); - // } - }, - ); - } componentWillUnmount() { @@ -443,15 +431,6 @@ export class Timeline extends React.Component { lengthString = ""; } - - // let modeType: string = this.props.Document.isATOn ? "Author" : "Play"; - // let modeString: string = "Mode: " + modeType; - // let overviewString: string = "Overview:"; - // let lengthString: string = "Length: "; - - console.log("visible: " + this._visibleLength) - console.log("total: " + this._totalLength) - return (
@@ -462,7 +441,7 @@ export class Timeline extends React.Component {
{overviewString}
- +
{modeString}
@@ -572,7 +551,6 @@ export class Timeline extends React.Component { runInAction(() => { this._panelWidth = this.props.PanelWidth(); this.changeLenths(); - console.log("changing!!") }); // change visible and total width diff --git a/src/client/views/animationtimeline/TimelineOverview.tsx b/src/client/views/animationtimeline/TimelineOverview.tsx index caa97bb70..9a881264f 100644 --- a/src/client/views/animationtimeline/TimelineOverview.tsx +++ b/src/client/views/animationtimeline/TimelineOverview.tsx @@ -4,6 +4,7 @@ import { observer } from "mobx-react"; import "./TimelineOverview.scss"; import * as $ from 'jquery'; import { Timeline } from "./Timeline"; +import { Keyframe, KeyframeFunc } from "./Keyframe"; interface TimelineOverviewProps { @@ -15,7 +16,9 @@ interface TimelineOverviewProps { parent: Timeline; changeCurrentBarX: (pixel: number) => void; movePanX: (pixel: number) => any; - panelWidth: number; + time: number; + tickSpacing: number; + tickIncrement: number; } @@ -25,7 +28,9 @@ export class TimelineOverview extends React.Component{ @observable private _scrubberRef = React.createRef(); @observable private overviewBarWidth: number = 0; @observable private _authoringReaction?: IReactionDisposer; - @observable private _resizeReaction?: IReactionDisposer; + @observable private visibleTime: number = 0; + @observable private currentX: number = 0; + @observable private visibleStart: number = 0; private readonly DEFAULT_HEIGHT = 50; private readonly DEFAULT_WIDTH = 300; @@ -42,22 +47,10 @@ export class TimelineOverview extends React.Component{ } }, ); - // this._resizeReaction = reaction( - // () => this.props.parent.props.PanelWidth, - // () => { - // // if (!this.props.parent._isAuthoring) { - // // runInAction(() => { - // console.log("resizing"); - // this.setOverviewWidth(); - // // }); - // // } - // }, - // ); } componentWillUnmount = () => { this._authoringReaction && this._authoringReaction(); - this._resizeReaction && this._resizeReaction(); } @action @@ -85,8 +78,6 @@ export class TimelineOverview extends React.Component{ // let movX = (this.props.visibleStart / this.props.totalLength) * (this.overviewWidth) + e.movementX; this.props.movePanX((movX / (this.DEFAULT_WIDTH)) * this.props.totalLength); // this.props.movePanX((movX / (this.overviewWidth) * this.props.totalLength); - - // console.log(this.props.totalLength); } @action @@ -125,18 +116,36 @@ export class TimelineOverview extends React.Component{ document.removeEventListener("pointerup", this.onScrubberUp); } + @action + getTimes() { + let vis = KeyframeFunc.convertPixelTime(this.props.visibleLength, "mili", "time", this.props.tickSpacing, this.props.tickIncrement); + let x = KeyframeFunc.convertPixelTime(this.props.currentBarX, "mili", "time", this.props.tickSpacing, this.props.tickIncrement); + let start = KeyframeFunc.convertPixelTime(this.props.visibleStart, "mili", "time", this.props.tickSpacing, this.props.tickIncrement); + this.visibleTime = vis; + this.currentX = x; + this.visibleStart = start; + } + render() { - console.log("helo") + this.getTimes(); // calculates where everything should fall based on its size - let percentVisible = this.props.visibleLength / this.props.totalLength; - console.log(this.props.visibleLength) + // let percentVisible = this.props.visibleLength / this.props.totalLength; + // let visibleBarWidth = percentVisible * this.overviewBarWidth; + + // let percentScrubberStart = this.props.currentBarX / this.props.totalLength; + // let scrubberStart = percentScrubberStart * this.overviewBarWidth; + + // let percentBarStart = this.props.visibleStart / this.props.totalLength; + // let barStart = percentBarStart * this.overviewBarWidth; + + let percentVisible = this.visibleTime / this.props.time; let visibleBarWidth = percentVisible * this.overviewBarWidth; - let percentScrubberStart = this.props.currentBarX / this.props.totalLength; + let percentScrubberStart = this.currentX / this.props.time; let scrubberStart = percentScrubberStart * this.overviewBarWidth; - let percentBarStart = this.props.visibleStart / this.props.totalLength; + let percentBarStart = this.visibleStart / this.props.time; let barStart = percentBarStart * this.overviewBarWidth; let timeline = this.props.isAuthoring ? [ diff --git a/src/client/views/animationtimeline/Track.tsx b/src/client/views/animationtimeline/Track.tsx index 1ca8022a1..3ea34a2f3 100644 --- a/src/client/views/animationtimeline/Track.tsx +++ b/src/client/views/animationtimeline/Track.tsx @@ -66,7 +66,7 @@ export class Track extends React.Component { runInAction(() => { if (!this.props.node.regions) this.props.node.regions = new List(); //if there is no region, then create new doc to store stuff //these two lines are exactly same from timeline.tsx - let relativeHeight = window.innerHeight / 14; + let relativeHeight = window.innerHeight / 20; this._trackHeight = relativeHeight < this.MAX_TITLE_HEIGHT ? relativeHeight : this.MAX_TITLE_HEIGHT; //for responsiveness }); } -- cgit v1.2.3-70-g09d2 From 4fd68c0ec41f2871ae24a87d8e5316d093bdb505 Mon Sep 17 00:00:00 2001 From: monikahedman Date: Sun, 2 Feb 2020 15:10:34 -0500 Subject: changes --- src/client/views/animationtimeline/Keyframe.scss | 15 +++++++++++ src/client/views/animationtimeline/Keyframe.tsx | 8 +++++- src/client/views/animationtimeline/Timeline.scss | 32 +++++++++++++++--------- src/client/views/animationtimeline/Timeline.tsx | 2 +- src/client/views/animationtimeline/Track.scss | 17 +++++++------ 5 files changed, 52 insertions(+), 22 deletions(-) (limited to 'src/client/views/animationtimeline/Timeline.scss') diff --git a/src/client/views/animationtimeline/Keyframe.scss b/src/client/views/animationtimeline/Keyframe.scss index 8ff1c53f5..f0685943b 100644 --- a/src/client/views/animationtimeline/Keyframe.scss +++ b/src/client/views/animationtimeline/Keyframe.scss @@ -46,6 +46,21 @@ $timelineDark: #77a1aa; position: absolute; } + .keyframe:hover~.keyframe-information { + display: flex; + } + + .keyframe-information { + display: none; + position: relative; + // z-index: 100000; + // background: $timelineDark; + width: 100px; + // left: -50px; + height: 100px; + // top: 40px; + } + .keyframeCircle { left: -10px; border: 3px solid $timelineDark; diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx index 9c486a6d6..2348da813 100644 --- a/src/client/views/animationtimeline/Keyframe.tsx +++ b/src/client/views/animationtimeline/Keyframe.tsx @@ -522,14 +522,18 @@ export class Keyframe extends React.Component { DocListCast(this.regiondata.keyframes).forEach(kf => { if (kf.type as KeyframeFunc.KeyframeType !== KeyframeFunc.KeyframeType.end) { keyframeDivs.push( -
+ <>
{ e.preventDefault(); e.stopPropagation(); this.moveKeyframe(e, kf); }} onContextMenu={(e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); this.makeKeyframeMenu(kf, e.nativeEvent); }} onDoubleClick={(e) => { e.preventDefault(); e.stopPropagation(); }}>
+
+
+ + ); } else { keyframeDivs.push( @@ -589,7 +593,9 @@ export class Keyframe extends React.Component { onPointerDown={this.onBarPointerDown }>
+ {/*
*/}
+ {/*
*/} {this.drawKeyframes()} {this.drawKeyframeDividers()}
diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index 40479559d..dbdade03f 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -206,18 +206,26 @@ $timelineDark: #77a1aa; border-right: 2px solid $timelineDark; .datapane { - top: 0px; - width: 100px; - height: 30%; - border: 1px solid $dark-color; - background-color: $intermediate-color; - color: white; - position: relative; - float: left; - border-style: solid; - overflow-y: scroll; - overflow-x: hidden; -} + top: 0px; + width: 100px; + height: 30%; + border: 1px solid $dark-color; + font-size: 12px; + line-height: 11px; + background-color: $timelineDark; + color: white; + position: relative; + float: left; + padding: 3px; + border-style: solid; + overflow-y: scroll; + overflow-x: hidden; + + p { + hyphens: auto; + } + + } } .resize { diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 5ff721ebb..f0ca1c0ab 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -100,7 +100,7 @@ export class Timeline extends React.Component { /////////lifecycle functions//////////// componentWillMount() { - let relativeHeight = window.innerHeight / 14; //sets height to arbitrary size, relative to innerHeight + let relativeHeight = window.innerHeight / 20; //sets height to arbitrary size, relative to innerHeight this._titleHeight = relativeHeight < this.MAX_TITLE_HEIGHT ? relativeHeight : this.MAX_TITLE_HEIGHT; //check if relHeight is less than Maxheight. Else, just set relheight to max this.MIN_CONTAINER_HEIGHT = this._titleHeight + 130; //offset this.DEFAULT_CONTAINER_HEIGHT = this._titleHeight * 2 + 130; //twice the titleheight + offset diff --git a/src/client/views/animationtimeline/Track.scss b/src/client/views/animationtimeline/Track.scss index 61a8e0b88..aec587a79 100644 --- a/src/client/views/animationtimeline/Track.scss +++ b/src/client/views/animationtimeline/Track.scss @@ -1,14 +1,15 @@ -@import "./../globalCssVariables.scss"; +@import "./../globalCssVariables.scss"; -.track-container{ +.track-container { .track { - .inner { - top:0px; - width: calc(100%); - background-color: $light-color; - border: 1px solid $dark-color; - position:relative; + .inner { + top: 0px; + width: calc(100%); + background-color: $light-color; + border: 1px solid $dark-color; + position: relative; + z-index: 100; } } } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 9e4d644c5977c781b4822ba065cec6e92977de10 Mon Sep 17 00:00:00 2001 From: monikahedman Date: Wed, 5 Feb 2020 10:16:42 -0500 Subject: about to pull --- src/client/views/animationtimeline/Timeline.scss | 28 ++++++++++++++++++++-- src/client/views/animationtimeline/Timeline.tsx | 21 +++++++++++++--- .../views/animationtimeline/TimelineOverview.scss | 9 ++++++- .../views/animationtimeline/TimelineOverview.tsx | 19 +++++++-------- 4 files changed, 61 insertions(+), 16 deletions(-) (limited to 'src/client/views/animationtimeline/Timeline.scss') diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index dbdade03f..ce8c845df 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -43,6 +43,8 @@ $timelineDark: #77a1aa; .time-box { margin-left: 5px; display: flex; + justify-content: center; + align-items: center; } .mode-box { @@ -61,6 +63,12 @@ $timelineDark: #77a1aa; } } + .overview-tool { + display: flex; + justify-content: center; + align-items: center; + } + .animation-text { // font-size: 16px; height: auto; @@ -179,13 +187,14 @@ $timelineDark: #77a1aa; .trackbox { top: 30px; - // TODO: where is this 30px coming from? height: calc(100% - 30px); // height: 100%; + // height: 100%; width: 100%; border-top: 2px solid black; border-bottom: 2px solid black; overflow: hidden; + // overflow-y: scroll; background-color: white; position: absolute; // box-shadow: -10px 0px 10px 10px red; @@ -193,10 +202,25 @@ $timelineDark: #77a1aa; } + .currentTime { + // background: red; + font-size: 12px; + display: flex; + justify-content: center; + align-items: center; + height: 40px; + top: 40px; + position: relative; + width: 100px; + margin-left: 20px; + } + .title-container { - margin-top: 80px; + // margin-top: 80px; + margin-top: 40px; margin-left: 20px; height: calc(100% - 100px - 30px); + // height: 100%; width: 100px; background-color: white; overflow: hidden; diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index f0ca1c0ab..ae2dfafc9 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -312,6 +312,7 @@ export class Timeline extends React.Component { e.preventDefault(); e.stopPropagation(); let offset = e.clientY - this._timelineContainer.current!.getBoundingClientRect().bottom; + // let offset = 0; if (this._containerHeight + offset <= this.MIN_CONTAINER_HEIGHT) { this._containerHeight = this.MIN_CONTAINER_HEIGHT; } else if (this._containerHeight + offset >= this.MAX_CONTAINER_HEIGHT) { @@ -326,7 +327,10 @@ export class Timeline extends React.Component { */ @action toReadTime = (time: number): string => { - const inSeconds = time / 1000; + time = time / 1000; + var inSeconds = Math.round((time * 100)) / 100; + // var inSeconds = parseFloat(time.toFixed(2)); + // const inSeconds = (Math.floor(time) / 1000); let min: (string | number) = Math.floor(inSeconds / 60); let sec: (string | number) = inSeconds % 60; @@ -451,7 +455,8 @@ export class Timeline extends React.Component {
{lengthString}
- + +
Hello there
@@ -541,13 +546,22 @@ export class Timeline extends React.Component { } } + // @computed + getCurrentTime = () => { + let current = KeyframeFunc.convertPixelTime(this._currentBarX, "mili", "time", this._tickSpacing, this._tickIncrement); + // console.log(this._currentBarX) + return this.toReadTime(current); `` + // return (Math.floor(current) / 1000) + // return current / 1000.0; + } + /** * if you have any question here, just shoot me an email or text. * basically the only thing you need to edit besides render methods in track (individual track lines) and keyframe (green region) */ render() { - // console.log(this.props.PanelWidth()); + console.log(this.props.Document.isATOn); runInAction(() => { this._panelWidth = this.props.PanelWidth(); this.changeLenths(); @@ -568,6 +582,7 @@ export class Timeline extends React.Component { {DocListCast(this.children).map(doc => )}
+
Current: {this.getCurrentTime()}
{DocListCast(this.children).map(doc =>
{ Doc.BrushDoc(doc); }} onPointerOut={() => { Doc.UnBrushDoc(doc); }}>

{doc.title}

)}
diff --git a/src/client/views/animationtimeline/TimelineOverview.scss b/src/client/views/animationtimeline/TimelineOverview.scss index a0b9d462b..283163ea7 100644 --- a/src/client/views/animationtimeline/TimelineOverview.scss +++ b/src/client/views/animationtimeline/TimelineOverview.scss @@ -8,6 +8,13 @@ $timelineDark: #77a1aa; margin-right: 10px; } +.timeline-flex { + display: flex; + justify-content: center; + align-items: center; + width: 100%; +} + .timeline-overview-container { // padding: 0px; margin-right: 5px; @@ -93,7 +100,7 @@ $timelineDark: #77a1aa; height: 4px; width: 0px; z-index: 1000; - background-color: $timelineColor; + background-color: $timelineDark; border-radius: 20px; margin-top: -4px; cursor: pointer; diff --git a/src/client/views/animationtimeline/TimelineOverview.tsx b/src/client/views/animationtimeline/TimelineOverview.tsx index 9a881264f..65fd8ff62 100644 --- a/src/client/views/animationtimeline/TimelineOverview.tsx +++ b/src/client/views/animationtimeline/TimelineOverview.tsx @@ -56,8 +56,11 @@ export class TimelineOverview extends React.Component{ @action setOverviewWidth() { let width = $("#timelineOverview").width(); + // console.log($("timelineOverview")) if (width) this.overviewBarWidth = width; else this.overviewBarWidth = 0; + + // console.log(this.overviewBarWidth) } @action @@ -124,20 +127,14 @@ export class TimelineOverview extends React.Component{ this.visibleTime = vis; this.currentX = x; this.visibleStart = start; + // console.log("getting times") + // console.log(x) + // console.log(start) } render() { - + this.setOverviewWidth(); this.getTimes(); - // calculates where everything should fall based on its size - // let percentVisible = this.props.visibleLength / this.props.totalLength; - // let visibleBarWidth = percentVisible * this.overviewBarWidth; - - // let percentScrubberStart = this.props.currentBarX / this.props.totalLength; - // let scrubberStart = percentScrubberStart * this.overviewBarWidth; - - // let percentBarStart = this.props.visibleStart / this.props.totalLength; - // let barStart = percentBarStart * this.overviewBarWidth; let percentVisible = this.visibleTime / this.props.time; let visibleBarWidth = percentVisible * this.overviewBarWidth; @@ -163,9 +160,11 @@ export class TimelineOverview extends React.Component{
]; return ( +
{timeline}
+
); } -- cgit v1.2.3-70-g09d2 From 79f70eebe0a29f8f3d759eff82dd3446ac3d5ed1 Mon Sep 17 00:00:00 2001 From: monikahedman Date: Sun, 9 Feb 2020 16:14:04 -0500 Subject: done with ui bugs --- src/client/views/animationtimeline/Timeline.scss | 3 ++ src/client/views/animationtimeline/Timeline.tsx | 11 +++--- .../views/animationtimeline/TimelineOverview.tsx | 45 +++++++++++----------- 3 files changed, 30 insertions(+), 29 deletions(-) (limited to 'src/client/views/animationtimeline/Timeline.scss') diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index ce8c845df..a99d017f4 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -42,14 +42,17 @@ $timelineDark: #77a1aa; .time-box { margin-left: 5px; + min-width: 140px; display: flex; justify-content: center; align-items: center; + // grid-column-start: line2; } .mode-box { display: flex; margin-left: 5px; + // grid-column-start: line3; } .overview-box { diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index e0f70dd43..3c4c5c93f 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -458,7 +458,6 @@ export class Timeline extends React.Component {
{this.timeIndicator(lengthString)} - {/* {rightInfo} */}
@@ -470,13 +469,16 @@ export class Timeline extends React.Component { return ( <>
{lengthString}
- +
1:40.07
); } else { return ( -
Current: {this.getCurrentTime()}
+
+
{`Current: ${this.getCurrentTime()}`}
+
{`Total: 1:40.07`}
+
); } } @@ -543,10 +545,7 @@ export class Timeline extends React.Component { // @computed getCurrentTime = () => { const current = KeyframeFunc.convertPixelTime(this._currentBarX, "mili", "time", this._tickSpacing, this._tickIncrement); - // console.log(this._currentBarX) return this.toReadTime(current); - // return (Math.floor(current) / 1000) - // return current / 1000.0; } diff --git a/src/client/views/animationtimeline/TimelineOverview.tsx b/src/client/views/animationtimeline/TimelineOverview.tsx index 66f6a9482..94bbe7074 100644 --- a/src/client/views/animationtimeline/TimelineOverview.tsx +++ b/src/client/views/animationtimeline/TimelineOverview.tsx @@ -27,6 +27,8 @@ export class TimelineOverview extends React.Component{ @observable private _visibleRef = React.createRef(); @observable private _scrubberRef = React.createRef(); @observable private overviewBarWidth: number = 0; + @observable private playbarWidth: number = 0; + @observable private activeOverviewWidth: number = 0; @observable private _authoringReaction?: IReactionDisposer; @observable private visibleTime: number = 0; @observable private currentX: number = 0; @@ -55,12 +57,17 @@ export class TimelineOverview extends React.Component{ @action setOverviewWidth() { - const width = $("#timelineOverview").width(); - // console.log($("timelineOverview")) - if (width) this.overviewBarWidth = width; - // else this.overviewBarWidth = 0; - - // console.log(this.overviewBarWidth) + const width1 = $("#timelineOverview").width(); + const width2 = $("#timelinePlay").width(); + if (width1 && width1 !== 0) this.overviewBarWidth = width1; + if (width2 && width2 !== 0) this.playbarWidth = width2; + + if (this.props.isAuthoring) { + this.activeOverviewWidth = this.overviewBarWidth; + } + else { + this.activeOverviewWidth = this.playbarWidth; + } } @action @@ -78,9 +85,7 @@ export class TimelineOverview extends React.Component{ e.stopPropagation(); e.preventDefault(); const movX = (this.props.visibleStart / this.props.totalLength) * (this.DEFAULT_WIDTH) + e.movementX; - // let movX = (this.props.visibleStart / this.props.totalLength) * (this.overviewWidth) + e.movementX; this.props.movePanX((movX / (this.DEFAULT_WIDTH)) * this.props.totalLength); - // this.props.movePanX((movX / (this.overviewWidth) * this.props.totalLength); } @action @@ -95,12 +100,10 @@ export class TimelineOverview extends React.Component{ onScrubberDown = (e: React.PointerEvent) => { e.preventDefault(); e.stopPropagation(); - // if (!this.props.isAuthoring) { document.removeEventListener("pointermove", this.onScrubberMove); document.removeEventListener("pointerup", this.onScrubberUp); document.addEventListener("pointermove", this.onScrubberMove); document.addEventListener("pointerup", this.onScrubberUp); - // } } @action @@ -110,7 +113,7 @@ export class TimelineOverview extends React.Component{ const scrubberRef = this._scrubberRef.current!; const left = scrubberRef.getBoundingClientRect().left; const offsetX = Math.round(e.clientX - left); - this.props.changeCurrentBarX((((offsetX) / this.overviewBarWidth) * this.props.totalLength) + this.props.currentBarX); + this.props.changeCurrentBarX((((offsetX) / this.activeOverviewWidth) * this.props.totalLength) + this.props.currentBarX); } @action @@ -129,38 +132,34 @@ export class TimelineOverview extends React.Component{ this.visibleTime = vis; this.currentX = x; this.visibleStart = start; - // console.log("getting times") - // console.log(x) - // console.log(start) } render() { - console.log("RERENDERED!"); this.setOverviewWidth(); this.getTimes(); const percentVisible = this.visibleTime / this.props.time; - const visibleBarWidth = percentVisible * this.overviewBarWidth; + const visibleBarWidth = percentVisible * this.activeOverviewWidth; const percentScrubberStart = this.currentX / this.props.time; - const scrubberStart = percentScrubberStart * this.overviewBarWidth; + const scrubberStart = this.props.currentBarX / this.props.totalLength * this.activeOverviewWidth; const percentBarStart = this.visibleStart / this.props.time; - const barStart = percentBarStart * this.overviewBarWidth; + const barStart = percentBarStart * this.activeOverviewWidth; const timeline = this.props.isAuthoring ? [ -
+
, -
+
] : [ -
-
+
+
, -
+
]; return (
-- cgit v1.2.3-70-g09d2 From d3f9765c98595788eaeb8b5c0ef52af1cd3adab3 Mon Sep 17 00:00:00 2001 From: monikahedman Date: Sun, 9 Feb 2020 17:01:37 -0500 Subject: reset view done --- src/client/views/animationtimeline/Keyframe.scss | 4 ---- src/client/views/animationtimeline/Timeline.scss | 27 +++++++++++++++++----- src/client/views/animationtimeline/Timeline.tsx | 11 +++++---- .../collectionFreeForm/CollectionFreeFormView.tsx | 25 ++++++++++++++++---- src/new_fields/Doc.ts | 19 +++++++++++++++ 5 files changed, 68 insertions(+), 18 deletions(-) (limited to 'src/client/views/animationtimeline/Timeline.scss') diff --git a/src/client/views/animationtimeline/Keyframe.scss b/src/client/views/animationtimeline/Keyframe.scss index 8dcf71994..84c8de287 100644 --- a/src/client/views/animationtimeline/Keyframe.scss +++ b/src/client/views/animationtimeline/Keyframe.scss @@ -46,10 +46,6 @@ $timelineDark: #77a1aa; position: absolute; } - // .keyframe:hover~.keyframe-information { - // display: flex; - // } - .keyframe-information { display: none; position: relative; diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss index a99d017f4..f90249771 100644 --- a/src/client/views/animationtimeline/Timeline.scss +++ b/src/client/views/animationtimeline/Timeline.scss @@ -34,29 +34,44 @@ $timelineDark: #77a1aa; } .grid-box { - display: grid; - grid-template-columns: [first] 50% [line2] 25% [line3] 25%; + display: flex; + // grid-template-columns: [first] 20% [line2] 20% [line3] 60%; width: calc(100% - 150px); // width: 100%; margin-left: 10px; .time-box { - margin-left: 5px; + margin-left: 10px; min-width: 140px; display: flex; justify-content: center; align-items: center; - // grid-column-start: line2; + + .resetView-tool { + width: 30px; + height: 30px; + display: flex; + justify-content: center; + align-items: center; + margin: 3px; + color: $timelineDark; + } + + .resetView-tool:hover { + -webkit-transform: scale(1.1); + -ms-transform: scale(1.1); + transform: scale(1.1); + transition: .2s ease; + } } .mode-box { display: flex; margin-left: 5px; - // grid-column-start: line3; } .overview-box { - width: 100%; + width: 80%; display: flex; } diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 3942499c9..256b98ffa 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -459,6 +459,9 @@ export class Timeline extends React.Component {
{this.timeIndicator(lengthString)} +
Doc.resetView(this.props.Document)}>
+
Doc.setView(this.props.Document)}>
+
@@ -477,8 +480,8 @@ export class Timeline extends React.Component { else { return (
-
{`Current: ${this.getCurrentTime()}`}
-
{`Total: 1:40.07`}
+
{`Current: ${this.getCurrentTime()}`}
+
{`Total: 1:40.07`}
); } @@ -539,7 +542,7 @@ export class Timeline extends React.Component { @action.bound - changeLenths() { + changeLengths() { if (this._infoContainer.current) { this._visibleLength = this._infoContainer.current!.getBoundingClientRect().width; //the visible length of the timeline (the length that you current see) this._visibleStart = this._infoContainer.current!.scrollLeft; //where the div starts @@ -572,7 +575,7 @@ export class Timeline extends React.Component { render() { runInAction(() => { this._panelWidth = this.props.PanelWidth(); - this.changeLenths(); + this.changeLengths(); }); // change visible and total width diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index ef1ec5e78..81fca3b54 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -966,7 +966,24 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { onContextMenu = (e: React.MouseEvent) => { const layoutItems: ContextMenuProps[] = []; - layoutItems.push({ description: "reset view", event: () => { this.props.Document._panX = this.props.Document._panY = 0; this.props.Document.scale = 1; }, icon: "compress-arrows-alt" }); + const { Document } = this.props; + + layoutItems.push({ + description: "reset view", event: () => { + Doc.resetView(Document); + }, icon: "compress-arrows-alt" + }); + layoutItems.push({ + description: "set view origin", event: () => { + Doc.setView(Document); + }, icon: "expand-arrows-alt" + }); + layoutItems.push({ + description: "reset view to origin", event: () => { + Doc.resetViewToOrigin(Document); + }, icon: "expand-arrows-alt" + }); + layoutItems.push({ description: `${this.Document._LODdisable ? "Enable LOD" : "Disable LOD"}`, event: () => this.Document._LODdisable = !this.Document._LODdisable, icon: "table" }); layoutItems.push({ description: `${this.fitToContent ? "Unset" : "Set"} Fit To Container`, event: () => this.Document._fitToBox = !this.fitToContent, icon: !this.fitToContent ? "expand-arrows-alt" : "compress-arrows-alt" }); layoutItems.push({ description: `${this.Document.useClusters ? "Uncluster" : "Use Clusters"}`, event: () => this.updateClusters(!this.Document.useClusters), icon: "braille" }); @@ -1018,7 +1035,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { icon: "eye" }); ContextMenu.Instance.addItem({ description: "Freeform Options ...", subitems: layoutItems, icon: "eye" }); - this._timelineRef.current!.timelineContextMenu(e); + this._timelineRef.current!.timelineContextMenu(e); } @@ -1081,12 +1098,12 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { transformOrigin: this.contentScaling ? "left top" : "", width: this.contentScaling ? `${100 / this.contentScaling}%` : "", height: this.contentScaling ? `${100 / this.contentScaling}%` : this.isAnnotationOverlay ? (this.props.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight() - }}> + }}> {/* */} {!this.Document._LODdisable && !this.props.active() && !this.props.isAnnotationOverlay && !this.props.annotationsKey && this.props.renderDepth > 0 ? // && this.props.CollectionView && lodarea < NumCast(this.Document.LODarea, 100000) ? this.placeholder : this.marqueeView} -
+
; } diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index f230abaf4..216005697 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -255,6 +255,25 @@ export namespace Doc { // return Cast(field, ctor); // }); // } + + export function resetView(doc: Doc) { + doc._panX = doc._customOriginX ?? 0; + doc._panY = doc._customOriginY ?? 0; + doc.scale = doc._customOriginScale ?? 1; + } + + export function resetViewToOrigin(doc: Doc) { + doc._panX = 0; + doc._panY = 0; + doc.scale = 1; + } + + export function setView(doc: Doc) { + doc._customOriginX = doc._panX; + doc._customOriginY = doc._panY; + doc._customOriginScale = doc.scale; + } + export function RunCachedUpdate(doc: Doc, field: string) { const update = doc[CachedUpdates][field]; if (update) { -- cgit v1.2.3-70-g09d2