diff options
-rw-r--r-- | src/client/views/MainView.tsx | 1 | ||||
-rw-r--r-- | src/client/views/animationtimeline/Timeline.tsx | 3 | ||||
-rw-r--r-- | src/client/views/animationtimeline/TimelineMenu.tsx | 12 | ||||
-rw-r--r-- | src/client/views/animationtimeline/Track.tsx | 124 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 4 | ||||
-rw-r--r-- | src/client/views/nodes/FormattedTextBox.tsx | 2 | ||||
-rw-r--r-- | src/new_fields/RichTextField.ts | 1 |
7 files changed, 85 insertions, 62 deletions
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index f5a6715e5..669b8f018 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -400,6 +400,7 @@ export class MainView extends React.Component { <ul id="add-options-list"> <li key="search"><button className="add-button round-button" title="Search" onClick={this.toggleSearch}><FontAwesomeIcon icon="search" size="sm" /></button></li> <li key="presentation"><button className="add-button round-button" title="Open Presentation View" onClick={() => PresentationView.Instance.toggle(undefined)}><FontAwesomeIcon icon="table" size="sm" /></button></li> + <li key="timeline"><button className="add-button round-button" title="Add Timeline"><FontAwesomeIcon icon="times" size="sm"/></button></li> <li key="undo"><button className="add-button round-button" title="Undo" style={{ opacity: UndoManager.CanUndo() ? 1 : 0.5, transition: "0.4s ease all" }} onClick={() => UndoManager.Undo()}><FontAwesomeIcon icon="undo-alt" size="sm" /></button></li> <li key="redo"><button className="add-button round-button" title="Redo" style={{ opacity: UndoManager.CanRedo() ? 1 : 0.5, transition: "0.4s ease all" }} onClick={() => UndoManager.Redo()}><FontAwesomeIcon icon="redo-alt" size="sm" /></button></li> {btns.map(btn => diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index d2714592e..7a6d9fa52 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -34,6 +34,9 @@ export interface FlyoutProps { @observer export class Timeline extends CollectionSubView(Document) { + static Instance:Timeline; + + private readonly DEFAULT_CONTAINER_HEIGHT: number = 300; private readonly DEFAULT_TICK_SPACING: number = 50; private readonly MIN_CONTAINER_HEIGHT: number = 205; diff --git a/src/client/views/animationtimeline/TimelineMenu.tsx b/src/client/views/animationtimeline/TimelineMenu.tsx index e82075f6a..7768f51df 100644 --- a/src/client/views/animationtimeline/TimelineMenu.tsx +++ b/src/client/views/animationtimeline/TimelineMenu.tsx @@ -1,6 +1,6 @@ - import * as React from "react"; - +import {observable, action, runInAction} from "mobx"; +import {observer} from "mobx-react"; /** * TimelineMenu: @@ -27,9 +27,17 @@ import * as React from "react"; * - duration region * - */ + +@observer export class TimelineMenu extends React.Component { public static Instance:TimelineMenu; + @observable private _opacity = 1; + @observable private _x = 0; + @observable private _y = 0; + @observable private _type: "timeline" | "keyframe" | "region" | "" = ""; + + constructor (props:Readonly<{}>){ super(props); TimelineMenu.Instance = this; diff --git a/src/client/views/animationtimeline/Track.tsx b/src/client/views/animationtimeline/Track.tsx index 4f78f86b8..fc2cacba8 100644 --- a/src/client/views/animationtimeline/Track.tsx +++ b/src/client/views/animationtimeline/Track.tsx @@ -9,10 +9,6 @@ import { List } from "../../../new_fields/List"; import { Keyframe, KeyframeFunc, RegionData } from "./Keyframe"; import { FlyoutProps } from "./Timeline"; import { Transform } from "../../util/Transform"; -import { AddComparisonParameters } from "../../northstar/model/idea/idea"; -import { CollectionSchemaBooleanCell } from "../collections/CollectionSchemaCells"; -import { DocumentManager } from "../../util/DocumentManager"; -import { DocumentView } from "../nodes/DocumentView"; import { RichTextField } from "../../../new_fields/RichTextField"; interface IProps { @@ -28,8 +24,11 @@ interface IProps { export class Track extends React.Component<IProps> { @observable private _inner = React.createRef<HTMLDivElement>(); @observable private _reactionDisposers: IReactionDisposer[] = []; - @observable private _keyReaction: any; //reaction that is used to dispose when necessary - @observable private _currentBarXReaction: any; + @observable private _currentBarXReaction: any; + @observable private _isOnKeyframe: boolean = false; + @observable private _onKeyframe: (Doc | undefined) = undefined; + @observable private _onRegionData : ( Doc | undefined) = undefined; + @observable private _leftCurrKeyframe: (Doc | undefined) = undefined; @computed private get regions() { @@ -53,53 +52,44 @@ export class Track extends React.Component<IProps> { componentWillUnmount() { runInAction(() => { - if (this._keyReaction) this._keyReaction(); if (this._currentBarXReaction) this._currentBarXReaction(); }); } @action - keyReaction = () => { - return reaction( () => { - return Doc.allKeys(this.props.node).map(key => FieldValue(this.props.node[key])); - }, async () => { - console.log("rAN"); - let regiondata: (Doc | undefined) = await this.findRegion(this.props.currentBarX) ; - if (regiondata) { - let keyframes = await DocListCastAsync((regiondata as Doc).keyframes!); - keyframes!.forEach( async (kf) => { - if (kf.type === KeyframeFunc.KeyframeType.default && kf.time === this.props.currentBarX) { - console.log("full keychange triggered"); - //for this specific keyframe - kf.key = Doc.MakeCopy(this.props.node, true); - - //for fades - let leftkf: (Doc | undefined) = await KeyframeFunc.calcMinLeft(regiondata!, this.props.currentBarX, kf); // lef keyframe, if it exists - let rightkf: (Doc | undefined) = await KeyframeFunc.calcMinRight(regiondata!, this.props.currentBarX, kf); //right keyframe, if it exists - if (leftkf!.type === KeyframeFunc.KeyframeType.fade) { //replicating this keyframe to fades - let edge:(Doc | undefined) = await KeyframeFunc.calcMinLeft(regiondata!, this.props.currentBarX, leftkf!); - edge!.key = Doc.MakeCopy(kf.key as Doc, true); - leftkf!.key = Doc.MakeCopy(kf.key as Doc, true); - (Cast(edge!.key, Doc)! as Doc).opacity = 0.1; - (Cast(leftkf!.key, Doc)! as Doc).opacity = 1; - } - if (rightkf!.type === KeyframeFunc.KeyframeType.fade) { - let edge:(Doc | undefined) = await KeyframeFunc.calcMinRight(regiondata!,this.props.currentBarX, rightkf!); - edge!.key = Doc.MakeCopy(kf.key as Doc, true); - rightkf!.key = Doc.MakeCopy(kf.key as Doc, true); - (Cast(edge!.key, Doc)! as Doc).opacity = 0.1; - (Cast(rightkf!.key, Doc)! as Doc).opacity = 1; - } - } - }); + saveKeyframe = async (ref:Doc, regiondata:Doc) => { + let keyframes:List<Doc> = (Cast(regiondata.keyframes, listSpec(Doc)) as List<Doc>); + let kfIndex:number = keyframes.indexOf(ref); + let kf = keyframes[kfIndex] as Doc; + if (kf.type === KeyframeFunc.KeyframeType.default) { // only save for fades + console.log("full keychange triggered"); + kf.key = Doc.MakeCopy(this.props.node, true); + let leftkf: (Doc | undefined) = await KeyframeFunc.calcMinLeft(regiondata!, this.props.currentBarX, kf); // lef keyframe, if it exists + let rightkf: (Doc | undefined) = await KeyframeFunc.calcMinRight(regiondata!, this.props.currentBarX, kf); //right keyframe, if it exists + if (leftkf!.type === KeyframeFunc.KeyframeType.fade) { //replicating this keyframe to fades + let edge:(Doc | undefined) = await KeyframeFunc.calcMinLeft(regiondata!, this.props.currentBarX, leftkf!); + edge!.key = Doc.MakeCopy(kf.key as Doc, true); + leftkf!.key = Doc.MakeCopy(kf.key as Doc, true); + (Cast(edge!.key, Doc)! as Doc).opacity = 0.1; + (Cast(leftkf!.key, Doc)! as Doc).opacity = 1; } - }, {fireImmediately: true}); + if (rightkf!.type === KeyframeFunc.KeyframeType.fade) { + let edge:(Doc | undefined) = await KeyframeFunc.calcMinRight(regiondata!,this.props.currentBarX, rightkf!); + edge!.key = Doc.MakeCopy(kf.key as Doc, true); + rightkf!.key = Doc.MakeCopy(kf.key as Doc, true); + (Cast(edge!.key, Doc)! as Doc).opacity = 0.1; + (Cast(rightkf!.key, Doc)! as Doc).opacity = 1; + } + } + keyframes[kfIndex] = kf; + this._onKeyframe = undefined; + this._onRegionData = undefined; + this._isOnKeyframe = false; } - + @action currentBarXReaction = () => { return reaction(() => this.props.currentBarX, async () => { - if (this._keyReaction) this._keyReaction(); //dispose previous reaction first let regiondata: (Doc | undefined) = await this.findRegion(this.props.currentBarX); if (regiondata) { this.props.node.hidden = false; @@ -113,6 +103,10 @@ export class Track extends React.Component<IProps> { @action timeChange = async (time: number) => { + if (this._isOnKeyframe && this._onKeyframe && this._onRegionData) { + console.log("saving"); + await this.saveKeyframe(this._onKeyframe, this._onRegionData); + } let regiondata = await this.findRegion(Math.round(time)); //finds a region that the scrubber is on if (regiondata) { let leftkf: (Doc | undefined) = await KeyframeFunc.calcMinLeft(regiondata, this.props.currentBarX); // lef keyframe, if it exists @@ -120,7 +114,10 @@ export class Track extends React.Component<IProps> { let currentkf: (Doc | undefined) = await this.calcCurrent(regiondata); //if the scrubber is on top of the keyframe if (currentkf) { await this.applyKeys(currentkf); - this._keyReaction = this.keyReaction(); //reactivates reaction. + this._leftCurrKeyframe = currentkf; + this._isOnKeyframe = true; + this._onKeyframe = currentkf; + this._onRegionData = regiondata; } else if (leftkf && rightkf) { await this.interpolate(leftkf, rightkf, regiondata); } @@ -133,17 +130,21 @@ export class Track extends React.Component<IProps> { 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 (key === "type") { - if (this.props.node[key] === "text") { - this.props.node.dataDocTest = new RichTextField(StrCast(kfNode.stateData)); - console.log("updated"); - } - } if (!kfNode[key]) { this.props.node[key] = undefined; } else { - this.props.node[key] = kfNode[key]; + if (key === "data") { + if (this.props.node.type === "text"){ + let nodeData = (kfNode[key] as RichTextField).Data; + this.props.node[key] = new RichTextField(nodeData); + } + } else if (key === "creationDate") { + } else { + this.props.node[key] = kfNode[key]; + } + } + }); } @@ -151,7 +152,7 @@ export class Track extends React.Component<IProps> { @action private filterKeys = (keys: string[]): string[] => { return keys.reduce((acc: string[], key: string) => { - if (key !== "regions" && key !== "data" && key !== "creationDate" && key !== "cursors" && key !== "hidden" && key !== "nativeHeight" && key !== "nativeWidth" && key !== "schemaColumns") acc.push(key); + if (key !== "regions" && key !== "cursors" && key !== "hidden" && key !== "nativeHeight" && key !== "nativeWidth" && key !== "schemaColumns") acc.push(key); return acc; }, []) as string[]; } @@ -205,22 +206,31 @@ export class Track extends React.Component<IProps> { } } - - this.filterKeys(Doc.allKeys(leftNode)).forEach(key => { if (leftNode[key] && rightNode[key] && typeof (leftNode[key]) === "number" && typeof (rightNode[key]) === "number") { //if it is number, interpolate if ((key === "x" || key === "y") && pathX.length !== 0){ if (key === "x") this.props.node[key] = proposedX; if (key === "y") this.props.node[key] = proposedY; - console.log(pathX.length); - } else { const diff = NumCast(rightNode[key]) - NumCast(leftNode[key]); const adjusted = diff * finalRatio; this.props.node[key] = NumCast(leftNode[key]) + adjusted; } } else { - this.props.node[key] = leftNode[key]; + if (key === "data") { + if (this.props.node.type === "text"){ + let nodeData = StrCast((leftNode[key] as RichTextField).Data); + let currentNodeData = StrCast((this.props.node[key] as RichTextField).Data); + if (nodeData !== currentNodeData) { + this.props.node[key] = new RichTextField(nodeData); + } + } + + } else if (key === "creationDate") { + + } else { + this.props.node[key] = leftNode[key]; + } } }); } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 676a49288..71329f166 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -573,7 +573,9 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { addOverlay("arrangeScript", { x: 400, y: 500, width: 400, height: 300, title: "Layout Script" }, { doc: "Doc", index: "number", collection: "Doc", state: "any", docs: "Doc[]" }, "{x: number, y: number, width?: number, height?: number}"); }; } - + private _timeline = <Timeline {...this.props}/>; + se = () => { + } render() { const easing = () => this.props.Document.panTransformType === "Ease"; Doc.UpdateDocumentExtensionForField(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey); diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 9b37a6491..03fa7f0cd 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -166,8 +166,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe if (this.extensionDoc) this.extensionDoc.text = state.doc.textBetween(0, state.doc.content.size, "\n\n"); if (this.extensionDoc) this.extensionDoc.lastModified = new DateField(new Date(Date.now())); this.dataDoc[this.props.fieldKey] = new RichTextField(JSON.stringify(state.toJSON())); - this.props.Document.stateData = JSON.stringify(state.toJSON()); - this.props.Document.dataDocTest = this.dataDoc[this.props.fieldKey]; this._applyingChange = false; let title = StrCast(this.dataDoc.title); if (title && title.startsWith("-") && this._editorView && !this.Document.customTitle) { diff --git a/src/new_fields/RichTextField.ts b/src/new_fields/RichTextField.ts index 78a3a4067..0095eb31f 100644 --- a/src/new_fields/RichTextField.ts +++ b/src/new_fields/RichTextField.ts @@ -15,6 +15,7 @@ export class RichTextField extends ObjectField { this.Data = data; } + [Copy]() { return new RichTextField(this.Data); } |