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/TimelineMenu.scss | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/client/views/animationtimeline/TimelineMenu.scss (limited to 'src/client/views/animationtimeline/TimelineMenu.scss') diff --git a/src/client/views/animationtimeline/TimelineMenu.scss b/src/client/views/animationtimeline/TimelineMenu.scss new file mode 100644 index 000000000..e69de29bb -- cgit v1.2.3-70-g09d2 From 2c86a6958186c020ce7fbe99555f07ffe9f9f821 Mon Sep 17 00:00:00 2001 From: andrewdkim Date: Tue, 6 Aug 2019 12:25:09 -0400 Subject: timeline contextmenu --- src/client/views/MainView.tsx | 5 ++ src/client/views/animationtimeline/Keyframe.tsx | 4 +- .../views/animationtimeline/TimelineMenu.scss | 7 ++ .../views/animationtimeline/TimelineMenu.tsx | 79 +++++++++++++++++++++- 4 files changed, 92 insertions(+), 3 deletions(-) (limited to 'src/client/views/animationtimeline/TimelineMenu.scss') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 669b8f018..589fcc409 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -39,6 +39,7 @@ import { FilterBox } from './search/FilterBox'; import { CollectionTreeView } from './collections/CollectionTreeView'; import { ClientUtils } from '../util/ClientUtils'; import { SchemaHeaderField, RandomPastel } from '../../new_fields/SchemaHeaderField'; +import { TimelineMenu } from './animationtimeline/TimelineMenu'; @observer export class MainView extends React.Component { @@ -148,6 +149,9 @@ export class MainView extends React.Component { const targets = document.elementsFromPoint(e.x, e.y); if (targets && targets.length && targets[0].className.toString().indexOf("contextMenu") === -1) { ContextMenu.Instance.closeMenu(); + } + if (targets && targets.length && targets[0].className.toString().indexOf("timeline-menu-container") === -1){ + TimelineMenu.Instance.closeMenu(); } }), true); } @@ -461,6 +465,7 @@ export class MainView extends React.Component { {this.nodesMenu()} {this.miscButtons} + diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx index 995a5b402..9dae3896f 100644 --- a/src/client/views/animationtimeline/Keyframe.tsx +++ b/src/client/views/animationtimeline/Keyframe.tsx @@ -12,6 +12,7 @@ import { FlyoutProps } from "./Timeline"; import { Transform } from "../../util/Transform"; import { InkField, StrokeData } from "../../../new_fields/InkField"; import { number } from "prop-types"; +import { TimelineMenu } from "./TimelineMenu"; export namespace KeyframeFunc { export enum KeyframeType { @@ -389,6 +390,7 @@ export class Keyframe extends React.Component {
{ this.moveKeyframe(e, kf as Doc); }} onContextMenu={(e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); + TimelineMenu.Instance.openMenu("keyframe", e.clientX, e.clientY); }}>
); } @@ -538,7 +540,7 @@ export class Keyframe extends React.Component {
{ this.onContainerOver(e, bodyRef); }} onPointerOut={(e) => { this.onContainerOut(e, bodyRef); }} - onContextMenu={(e) => { this.onContainerDown(e, kf); }}> + onContextMenu={(e) => {TimelineMenu.Instance.openMenu("region", e.clientX, e.clientY);}}>
); } diff --git a/src/client/views/animationtimeline/TimelineMenu.scss b/src/client/views/animationtimeline/TimelineMenu.scss index e69de29bb..458c1eda1 100644 --- a/src/client/views/animationtimeline/TimelineMenu.scss +++ b/src/client/views/animationtimeline/TimelineMenu.scss @@ -0,0 +1,7 @@ +.timeline-menu-container{ + position: absolute; + z-index: 10000; + width: 500px; + height: 500px; + background-color: black; +} \ No newline at end of file diff --git a/src/client/views/animationtimeline/TimelineMenu.tsx b/src/client/views/animationtimeline/TimelineMenu.tsx index 7768f51df..adbd21e62 100644 --- a/src/client/views/animationtimeline/TimelineMenu.tsx +++ b/src/client/views/animationtimeline/TimelineMenu.tsx @@ -1,6 +1,8 @@ import * as React from "react"; import {observable, action, runInAction} from "mobx"; import {observer} from "mobx-react"; +import "./TimelineMenu.scss"; +import { jSXAttribute } from "babel-types"; /** * TimelineMenu: @@ -32,7 +34,7 @@ import {observer} from "mobx-react"; export class TimelineMenu extends React.Component { public static Instance:TimelineMenu; - @observable private _opacity = 1; + @observable private _opacity = 0; @observable private _x = 0; @observable private _y = 0; @observable private _type: "timeline" | "keyframe" | "region" | "" = ""; @@ -42,13 +44,86 @@ export class TimelineMenu extends React.Component { super(props); TimelineMenu.Instance = this; } + @action + pointerDown = (e: React.PointerEvent) => { + e.preventDefault(); + e.stopPropagation(); + document.removeEventListener("pointerup", this.pointerUp); + document.addEventListener("pointerup", this.pointerUp); + document.removeEventListener("pointermove", this.pointerMove); + document.addEventListener("pointermove", this.pointerMove); + + + } + @action + pointerMove = (e: PointerEvent) => { + e.preventDefault(); + e.stopPropagation(); + } + @action + pointerUp = (e: PointerEvent) => { + document.removeEventListener("pointermove", this.pointerMove); + document.removeEventListener("pointerup", this.pointerUp); + } + + @action + openMenu = (type: "timeline" | "keyframe" | "region", x?:number, y?:number) => { + this._type = type; + this._opacity = 1; + x ? this._x = x : this._x = 0; + y ? this._y = y : this._y = 0; + } + + @action + closeMenu = () => { + this._opacity = 0; + } + @action + addEase = (e: React.MouseEvent) => { + + } + @action + addPath = (e:React.MouseEvent) => { + + } render() { + let menu: (JSX.Element[] | undefined); + switch(this._type){ + case "keyframe": + menu = [ + , + , + + + ]; + break; + case "region" : + menu = [ + , + , + , + , + , + , + ]; + break; + case "timeline": + menu = [ + + ]; + break; + default: + break; + + } return ( -
+
+ {menu} +
); } -- cgit v1.2.3-70-g09d2 From a4b5fa0273bb7bc872699f0f0ce047ec0fbc7d43 Mon Sep 17 00:00:00 2001 From: andrewdkim Date: Tue, 6 Aug 2019 16:02:35 -0400 Subject: debug and context menu --- src/client/views/MainView.tsx | 3 +++ src/client/views/animationtimeline/Keyframe.tsx | 4 ---- src/client/views/animationtimeline/TimelineMenu.scss | 13 +++++++++++-- src/client/views/animationtimeline/TimelineMenu.tsx | 18 +++++++++--------- src/client/views/animationtimeline/Track.tsx | 2 ++ src/new_fields/Doc.ts | 3 ++- 6 files changed, 27 insertions(+), 16 deletions(-) (limited to 'src/client/views/animationtimeline/TimelineMenu.scss') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index f38367d98..270e9b183 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -149,6 +149,9 @@ export class MainView extends React.Component { if (targets && targets.length && targets[0].className.toString().indexOf("contextMenu") === -1) { ContextMenu.Instance.closeMenu(); } + if (targets && targets.length && targets[0].className.toString().indexOf("timeline-menu-container") === -1) { + TimelineMenu.Instance.closeMenu(); + } }); globalPointerUp = () => this.isPointerDown = false; diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx index 9dae3896f..b27cb6d98 100644 --- a/src/client/views/animationtimeline/Keyframe.tsx +++ b/src/client/views/animationtimeline/Keyframe.tsx @@ -231,10 +231,6 @@ export class Keyframe extends React.Component { return; } }); - - let index = this.regiondata.keyframes!.indexOf(TK); - console.log(toJS(this.regiondata.keyframes!)); - return TK; } diff --git a/src/client/views/animationtimeline/TimelineMenu.scss b/src/client/views/animationtimeline/TimelineMenu.scss index 458c1eda1..ed047e52d 100644 --- a/src/client/views/animationtimeline/TimelineMenu.scss +++ b/src/client/views/animationtimeline/TimelineMenu.scss @@ -1,7 +1,16 @@ .timeline-menu-container{ position: absolute; z-index: 10000; - width: 500px; - height: 500px; + width: 150px; + height: auto; background-color: black; + .timeline-menu-button{ + width:100%; + height: 30px; + + } + .timeline-menu-input{ + width:100%; + height: 30px; + } } \ No newline at end of file diff --git a/src/client/views/animationtimeline/TimelineMenu.tsx b/src/client/views/animationtimeline/TimelineMenu.tsx index adbd21e62..52f6f6535 100644 --- a/src/client/views/animationtimeline/TimelineMenu.tsx +++ b/src/client/views/animationtimeline/TimelineMenu.tsx @@ -95,20 +95,20 @@ export class TimelineMenu extends React.Component { switch(this._type){ case "keyframe": menu = [ - , - , - + , + , + ]; break; case "region" : menu = [ - , - , - , - , - , - , + , + , + , + , + , + , ]; break; case "timeline": diff --git a/src/client/views/animationtimeline/Track.tsx b/src/client/views/animationtimeline/Track.tsx index fc2cacba8..363ab4074 100644 --- a/src/client/views/animationtimeline/Track.tsx +++ b/src/client/views/animationtimeline/Track.tsx @@ -128,8 +128,10 @@ export class Track extends React.Component { private applyKeys = async (kf: Doc) => { let kfNode = await Cast(kf.key, Doc) as Doc; let docFromApply = kfNode; + console.log(Doc.allKeys(docFromApply)); 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 => { + console.log(key); if (!kfNode[key]) { this.props.node[key] = undefined; } else { diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index c01f4e8cf..b272bc1b9 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -425,12 +425,13 @@ export namespace Doc { export function MakeCopy(doc: Doc, copyProto: boolean = false): Doc { const copy = new Doc; Object.keys(doc).forEach(key => { - const field = ProxyField.WithoutProxy(() => doc[key]); if (key === "proto" && copyProto) { + const field = doc[key]; if (field instanceof Doc) { copy[key] = Doc.MakeCopy(field); } } else { + const field = ProxyField.WithoutProxy(() => doc[key]); if (field instanceof RefField) { copy[key] = field; } else if (field instanceof ObjectField) { -- cgit v1.2.3-70-g09d2 From 300aff743835dfd1c021609fd005819c8f2fd584 Mon Sep 17 00:00:00 2001 From: andrewdkim Date: Wed, 7 Aug 2019 14:56:48 -0400 Subject: working timelinemenu --- src/client/views/ContextMenu.scss | 1 + src/client/views/MainView.tsx | 6 +- src/client/views/animationtimeline/Keyframe.tsx | 73 +++++++++-------- .../views/animationtimeline/TimelineMenu.scss | 94 ++++++++++++++++++++-- .../views/animationtimeline/TimelineMenu.tsx | 85 ++++++++++++------- 5 files changed, 185 insertions(+), 74 deletions(-) (limited to 'src/client/views/animationtimeline/TimelineMenu.scss') diff --git a/src/client/views/ContextMenu.scss b/src/client/views/ContextMenu.scss index e2c0de8af..6c619fbe1 100644 --- a/src/client/views/ContextMenu.scss +++ b/src/client/views/ContextMenu.scss @@ -7,6 +7,7 @@ box-shadow: $intermediate-color 0.2vw 0.2vw 0.4vw; flex-direction: column; background: whitesmoke; + padding-top: 10px; padding-bottom: 10px; border-radius: 15px; border: solid #BBBBBBBB 1px; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 270e9b183..3941c9c20 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -149,9 +149,9 @@ export class MainView extends React.Component { if (targets && targets.length && targets[0].className.toString().indexOf("contextMenu") === -1) { ContextMenu.Instance.closeMenu(); } - if (targets && targets.length && targets[0].className.toString().indexOf("timeline-menu-container") === -1) { - TimelineMenu.Instance.closeMenu(); - } + // if (targets && targets.length && targets[0].className.toString().indexOf("timeline-menu-container") === -1) { + // TimelineMenu.Instance.closeMenu(); + // } }); globalPointerUp = () => this.isPointerDown = false; diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx index b27cb6d98..d1975d847 100644 --- a/src/client/views/animationtimeline/Keyframe.tsx +++ b/src/client/views/animationtimeline/Keyframe.tsx @@ -386,7 +386,7 @@ export class Keyframe extends React.Component {
{ this.moveKeyframe(e, kf as Doc); }} onContextMenu={(e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); - TimelineMenu.Instance.openMenu("keyframe", e.clientX, e.clientY); + TimelineMenu.Instance.openMenu(e.clientX, e.clientY); }}>
); } @@ -418,29 +418,21 @@ export class Keyframe extends React.Component { private _type: string = ""; @action - onContainerDown = (e: React.MouseEvent, kf: Doc) => { - e.preventDefault(); - e.stopPropagation(); + onContainerDown = (kf: Doc, type: string) => { let listenerCreated = false; - let type = prompt("Type? (interpolate or path)"); - if (type) { - if (type !== "interpolate" && type !=="path") { - alert("Wrong type. Try again."); - return; + this._type = type; + this.props.collection.backgroundColor = "rgb(0,0,0)"; + this._reac = reaction(() => { + return this.inks; + }, data => { + if (!listenerCreated) { + this._plotList = Array.from(data!)[data!.size - 1]!; + this._interpolationKeyframe = kf; + document.addEventListener("pointerup", this.onReactionListen); + listenerCreated = true; } - this._type = type; - this.props.collection.backgroundColor = "rgb(0,0,0)"; - this._reac = reaction(() => { - return this.inks; - }, data => { - if (!listenerCreated) { - this._plotList = Array.from(data!)[data!.size - 1]!; - this._interpolationKeyframe = kf; - document.addEventListener("pointerup", this.onReactionListen); - listenerCreated = true; - } - }); - } + }); + } @@ -508,20 +500,26 @@ export class Keyframe extends React.Component { } + + /** + * + * + * TEMPORARY + * let items = [ + TimelineMenu.Instance.addItem("button", "Show Data", () => {console.log(toJS(this.props.node));}), + TimelineMenu.Instance.addItem("button", "Delete", () => {}), + TimelineMenu.Instance.addItem("input", "Move", (val) => {console.log(val);}) + ]; + TimelineMenu.Instance.addMenu("Keyframe", items); + TimelineMenu.Instance.openMenu(e.clientX, e.clientY); + * + */ render() { return (
{ - e.preventDefault(); - e.stopPropagation(); - console.log("has been clicked!"); - let offsetLeft = this._bar.current!.getBoundingClientRect().left - this._bar.current!.parentElement!.getBoundingClientRect().left; - let offsetTop = this._bar.current!.getBoundingClientRect().top; //+ this._bar.current!.parentElement!.getBoundingClientRect().top; - this.props.setFlyout({ x: offsetLeft * this.props.transform.Scale, y: offsetTop * this.props.transform.Scale, display: "block", regiondata: this.regiondata, regions: this.regions }); - })}> + onDoubleClick={this.createKeyframe}>
{this.regiondata.keyframes!.map(kf => { @@ -536,7 +534,18 @@ export class Keyframe extends React.Component {
{ this.onContainerOver(e, bodyRef); }} onPointerOut={(e) => { this.onContainerOut(e, bodyRef); }} - onContextMenu={(e) => {TimelineMenu.Instance.openMenu("region", e.clientX, e.clientY);}}> + onContextMenu={(e) => { + let items = [ + TimelineMenu.Instance.addItem("button", "Add Ease", () => {this.onContainerDown(kf, "interpolate");}), + TimelineMenu.Instance.addItem("button", "Add Path", () => {this.onContainerDown(kf, "path");}), + TimelineMenu.Instance.addItem("input", "fadeIn", (val) => {this.regiondata.fadeIn = parseInt(val, 10);}), + TimelineMenu.Instance.addItem("input", "fadeOut", (val) => {this.regiondata.fadeOut = parseInt(val, 10);}), + TimelineMenu.Instance.addItem("input", "position", (val) => {this.regiondata.position = parseInt(val, 10);}), + TimelineMenu.Instance.addItem("input", "duration", (val) => {this.regiondata.duration = parseInt(val, 10);}), + ]; + TimelineMenu.Instance.addMenu("Region", items); + TimelineMenu.Instance.openMenu(e.clientX, e.clientY); + }}>
); } diff --git a/src/client/views/animationtimeline/TimelineMenu.scss b/src/client/views/animationtimeline/TimelineMenu.scss index ed047e52d..90cc53b4c 100644 --- a/src/client/views/animationtimeline/TimelineMenu.scss +++ b/src/client/views/animationtimeline/TimelineMenu.scss @@ -1,16 +1,94 @@ +@import "./../globalCssVariables.scss"; + + .timeline-menu-container{ position: absolute; + display: flex; + box-shadow: $intermediate-color 0.2vw 0.2vw 0.4vw; + flex-direction: column; + background: whitesmoke; z-index: 10000; width: 150px; - height: auto; - background-color: black; - .timeline-menu-button{ - width:100%; - height: 30px; + padding-bottom: 10px; + border-radius: 15px; + + border: solid #BBBBBBBB 1px; + + - } .timeline-menu-input{ - width:100%; - height: 30px; + font: $sans-serif; + font-size: 13px; + width:100%; + text-transform: uppercase; + letter-spacing: 2px; + margin-left: 10px; + background-color: transparent; + border-width: 0px; + transition: border-width 500ms; + } + + .timeline-menu-input:hover{ + border-width: 2px; + } + + + + + .timeline-menu-header{ + border-top-left-radius: 15px; + border-top-right-radius: 15px; + text-transform: uppercase; + background: $dark-color; + letter-spacing: 2px; + + .timeline-menu-header-desc{ + font:$sans-serif; + font-size: 13px; + text-align: center; + color: whitesmoke; + } + } + + + .timeline-menu-item { + // width: 11vw; //10vw + height: 30px; //2vh + background: whitesmoke; + display: flex; //comment out to allow search icon to be inline with search text + justify-content: left; + align-items: center; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + transition: all .1s; + border-style: none; + // padding: 10px 0px 10px 0px; + white-space: nowrap; + font-size: 13px; + color: grey; + letter-spacing: 2px; + text-transform: uppercase; + padding-right: 20px; + padding-left: 10px; + } + + .timeline-menu-item:hover { + border-width: .11px; + border-style: none; + border-color: $intermediate-color; + border-bottom-style: solid; + border-top-style: solid; + background: $darker-alt-accent; + } + + .timeline-menu-desc { + padding-left: 10px; + font:$sans-serif; + font-size: 13px; } + } \ No newline at end of file diff --git a/src/client/views/animationtimeline/TimelineMenu.tsx b/src/client/views/animationtimeline/TimelineMenu.tsx index 52f6f6535..8b47448f2 100644 --- a/src/client/views/animationtimeline/TimelineMenu.tsx +++ b/src/client/views/animationtimeline/TimelineMenu.tsx @@ -3,6 +3,10 @@ import {observable, action, runInAction} from "mobx"; import {observer} from "mobx-react"; import "./TimelineMenu.scss"; import { jSXAttribute } from "babel-types"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faChartLine, faRoad, faClipboard, faPen, faTrash, faTable } from "@fortawesome/free-solid-svg-icons"; +import { AddComparisonResult } from "../../northstar/model/idea/idea"; + /** * TimelineMenu: @@ -38,8 +42,7 @@ export class TimelineMenu extends React.Component { @observable private _x = 0; @observable private _y = 0; @observable private _type: "timeline" | "keyframe" | "region" | "" = ""; - - + @observable private _currentMenu:JSX.Element[] = []; constructor (props:Readonly<{}>){ super(props); TimelineMenu.Instance = this; @@ -67,8 +70,7 @@ export class TimelineMenu extends React.Component { } @action - openMenu = (type: "timeline" | "keyframe" | "region", x?:number, y?:number) => { - this._type = type; + openMenu = (x?:number, y?:number) => { this._opacity = 1; x ? this._x = x : this._x = 0; y ? this._y = y : this._y = 0; @@ -88,41 +90,62 @@ export class TimelineMenu extends React.Component { } + addItem = (type: "input" | "button", title: string, event: (e:any) => void) => { + if (type === "input"){ + let ref = React.createRef(); + let text = ""; + return
{text = e.target.value;}} onKeyDown={(e:React.KeyboardEvent) => { + if(e.keyCode === 13){ + event(text); + }}}/>
; + } else if (type === "button") { + let ref = React.createRef(); + return

{title}

; + } + return
; + } + @action + addMenu = (title:string, items: JSX.Element[]) => { + items.unshift(

{title}

); + this._currentMenu = items; + } render() { - let menu: (JSX.Element[] | undefined); - switch(this._type){ - case "keyframe": - menu = [ - , - , - + // let menu: (JSX.Element[] | undefined); + // switch(this._type){ + // case "keyframe": + // menu = [ + //

Keyframe

, + //

Show Data

, + //

Delete

, + //
- ]; - break; - case "region" : - menu = [ - , - , - , - , - , - , - ]; - break; - case "timeline": - menu = [ + // ]; + // break; + // case "region" : + // menu = [ + //

Region

, + //

Add Ease

, + //

Add Path

, + //
, + //
, + //
, + //
, + // ]; + // break; + // case "timeline": + // menu = [ - ]; - break; - default: - break; + // ]; + // break; + // default: + // break; - } + // } return (
- {menu} + {this._currentMenu}
); } -- cgit v1.2.3-70-g09d2 From 4ae11ac54b25a5bfe935a934d3ce37084906ccdb Mon Sep 17 00:00:00 2001 From: andrewdkim Date: Sat, 21 Sep 2019 16:55:18 -0400 Subject: changed boundaries --- src/client/views/animationtimeline/Keyframe.tsx | 36 ++++++++++++++++------ .../views/animationtimeline/TimelineMenu.scss | 2 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 2 +- 4 files changed, 30 insertions(+), 12 deletions(-) (limited to 'src/client/views/animationtimeline/TimelineMenu.scss') diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx index 253515dfd..20fc8470d 100644 --- a/src/client/views/animationtimeline/Keyframe.tsx +++ b/src/client/views/animationtimeline/Keyframe.tsx @@ -412,7 +412,7 @@ export class Keyframe extends React.Component { makeKeyframeMenu = (kf :Doc, e:MouseEvent) => { TimelineMenu.Instance.addItem("button", "Show Data", () => { runInAction(() => {let kvp = Docs.Create.KVPDocument(Cast(kf.key, Doc) as Doc, { width: 300, height: 300 }); - CollectionDockingView.Instance.AddRightSplit(kvp, (kf.key as Doc).data as Doc); }); + CollectionDockingView.AddRightSplit(kvp, (kf.key as Doc).data as Doc); }); }), TimelineMenu.Instance.addItem("button", "Delete", () => { runInAction(() => { @@ -430,16 +430,34 @@ export class Keyframe extends React.Component { TimelineMenu.Instance.addItem("button", "Add Ease", () => {this.onContainerDown(kf, "interpolate");}), TimelineMenu.Instance.addItem("button", "Add Path", () => {this.onContainerDown(kf, "path");}), TimelineMenu.Instance.addItem("button", "Remove Region", ()=>{this.regions.splice(this.regions.indexOf(this.regiondata), 1);}), - TimelineMenu.Instance.addItem("input", "fadeIn", (val) => {this.regiondata.fadeIn = parseInt(val, 10);}), - TimelineMenu.Instance.addItem("input", "fadeOut", (val) => {this.regiondata.fadeOut = parseInt(val, 10);}), - TimelineMenu.Instance.addItem("input", "position", (val) => {this.regiondata.position = parseInt(val, 10);}), - TimelineMenu.Instance.addItem("input", "duration", (val) => {this.regiondata.duration = parseInt(val, 10);}), + TimelineMenu.Instance.addItem("input", `fadeIn: ${this.regiondata.fadeIn}ms`, (val) => {runInAction(() => { + this.regiondata.fadeIn = parseInt(val, 10); + });}), + TimelineMenu.Instance.addItem("input", `fadeOut: ${this.regiondata.fadeOut}ms`, (val) => {runInAction(() => { + this.regiondata.fadeOut = parseInt(val, 10); + });}), + TimelineMenu.Instance.addItem("input", `position: ${this.regiondata.position}ms`, (val) => {runInAction(() => { + if (this.checkInput(val)){ + DocListCast(this.regions).forEach(region => { + if (region !== this.regiondata){ + if (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))){ + return undefined; + } + } + }); + this.regiondata.position = val; + } + this.regiondata.position = parseInt(val, 10); + });}), + TimelineMenu.Instance.addItem("input", `duration: ${this.regiondata.duration}ms`, (val) => {runInAction(() => { + this.regiondata.duration = parseInt(val, 10); + });}), TimelineMenu.Instance.addMenu("Region"); TimelineMenu.Instance.openMenu(e.clientX, e.clientY); } - @action - private createKeyframeJSX = (kf: Doc, type = KeyframeFunc.KeyframeType.default) => { - + + checkInput = (val: any) => { + return typeof(val === "number") } onContainerOver = (e: React.PointerEvent, ref: React.RefObject) => { @@ -544,7 +562,7 @@ export class Keyframe extends React.Component {
diff --git a/src/client/views/animationtimeline/TimelineMenu.scss b/src/client/views/animationtimeline/TimelineMenu.scss index 90cc53b4c..7ee0a43d5 100644 --- a/src/client/views/animationtimeline/TimelineMenu.scss +++ b/src/client/views/animationtimeline/TimelineMenu.scss @@ -8,7 +8,7 @@ flex-direction: column; background: whitesmoke; z-index: 10000; - width: 150px; + width: 200px; padding-bottom: 10px; border-radius: 15px; diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 9685f9bca..fcf483659 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -110,7 +110,7 @@ export class CollectionFreeFormDocumentView extends DocComponent(Docu