From 43818b137486f3d4431e1c3b9f4de0b0aefba9ca Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sat, 23 May 2020 14:59:01 -0400 Subject: several fixes to progressivization and added UI for editing by suspending transparency --- src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx') diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index a4120f958..88fbdd589 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -77,6 +77,8 @@ export class CollectionFreeFormDocumentView extends DocComponent docs.forEach(doc => doc.transition = undefined), 1010); } - public static setupKeyframes(docs: Doc[], timecode: number, collection: Doc) { + public static setupKeyframes(docs: Doc[], timecode: number, progressivize: boolean = false) { docs.forEach((doc, i) => { + const curTimecode = progressivize ? i : timecode; const xlist = new List(numberRange(timecode + 1).map(i => undefined) as any as number[]); const ylist = new List(numberRange(timecode + 1).map(i => undefined) as any as number[]); - xlist[Math.max(i - 1)] = xlist[timecode + 1] = NumCast(doc.x); - ylist[Math.max(i - 1)] = ylist[timecode + 1] = NumCast(doc.y); + const olist = new List(numberRange(timecode + 1).map(t => progressivize && t < i ? 0 : 1)); + xlist[Math.max(curTimecode - 1, 0)] = xlist[curTimecode] = NumCast(doc.x); + ylist[Math.max(curTimecode - 1, 0)] = ylist[curTimecode] = NumCast(doc.y); doc["x-indexed"] = xlist; doc["y-indexed"] = ylist; - doc["opacity-indexed"] = new List(numberRange(timecode).map(i => 1)); - doc.displayTimecode = ComputedField.MakeFunction("collection ? collection.currentTimecode : 0", {}, { collection }); + doc["opacity-indexed"] = olist; + doc.displayTimecode = ComputedField.MakeFunction("self.context ? (self.context.currentTimecode||0) : 0"); doc.x = ComputedField.MakeInterpolated("x", "displayTimecode"); doc.y = ComputedField.MakeInterpolated("y", "displayTimecode"); doc.opacity = ComputedField.MakeInterpolated("opacity", "displayTimecode"); -- cgit v1.2.3-70-g09d2 From 2ba063ff94a04e89ee1fa1fde7d71a839f5d6856 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sat, 23 May 2020 23:25:22 -0400 Subject: switched frame animations to use currentFrame and activeFrame to fix aliasing issue of progressive slides at different frame codes --- src/client/documents/Documents.ts | 2 ++ src/client/views/MainView.tsx | 6 +--- .../collectionFreeForm/CollectionFreeFormView.tsx | 41 +++++++++++----------- .../views/nodes/CollectionFreeFormDocumentView.tsx | 25 +++++++------ src/client/views/nodes/PresBox.tsx | 6 ++-- .../views/presentationview/PresElementBox.tsx | 2 +- src/fields/documentSchemas.ts | 6 ++-- 7 files changed, 46 insertions(+), 42 deletions(-) (limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 6b17b4303..2be961108 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -126,6 +126,8 @@ export interface DocumentOptions { curPage?: number; currentTimecode?: number; // the current timecode of a time-based document (e.g., current time of a video) value is in seconds displayTimecode?: number; // the time that a document should be displayed (e.g., time an annotation should be displayed on a video) + currentFrame?: number; // the current frame of a frame-based collection (e.g., progressive slide) + activeFrame?: number; // the active frame of a document in a frame base collection borderRounding?: string; boxShadow?: string; dontRegisterChildViews?: boolean; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index b7a75dfb9..358de2333 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -139,10 +139,7 @@ export class MainView extends React.Component { initEventListeners = () => { window.addEventListener("drop", (e) => { e.preventDefault(); }, false); // drop event handler - window.addEventListener("dragover", (e) => { - console.log("MDRAG"); - e.preventDefault(); - }, false); // drag event handler + window.addEventListener("dragover", (e) => { e.preventDefault(); }, false); // drag event handler // click interactions for the context menu document.addEventListener("pointerdown", this.globalPointerDown); document.addEventListener("pointerup", this.globalPointerUp); @@ -246,7 +243,6 @@ export class MainView extends React.Component { onDrop = (e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); - console.log("Drop"); } @action diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index d0415f77d..91e257f80 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -56,6 +56,7 @@ export const panZoomSchema = createSchema({ scale: "number", currentTimecode: "number", displayTimecode: "number", + currentFrame: "number", arrangeScript: ScriptField, arrangeInit: ScriptField, useClusters: "boolean", @@ -140,7 +141,7 @@ export class CollectionFreeFormView extends CollectionSubView { - const currentTimecode = this.Document.currentTimecode; - if (currentTimecode === undefined) { - this.Document.currentTimecode = 0; + const currentFrame = this.Document.currentFrame; + if (currentFrame === undefined) { + this.Document.currentFrame = 0; CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0); } - CollectionFreeFormDocumentView.updateKeyframe(this.childDocs, currentTimecode || 0); - this.Document.currentTimecode = Math.max(0, (currentTimecode || 0) + 1); - this.Document.lastTimecode = Math.max(NumCast(this.Document.currentTimecode), NumCast(this.Document.lastTimecode)); + CollectionFreeFormDocumentView.updateKeyframe(this.childDocs, currentFrame || 0); + this.Document.currentFrame = Math.max(0, (currentFrame || 0) + 1); + this.Document.lastTimecode = Math.max(NumCast(this.Document.currentFrame), NumCast(this.Document.lastTimecode)); } @undoBatch @action prevKeyframe = (): void => { - const currentTimecode = this.Document.currentTimecode; - if (currentTimecode === undefined) { - this.Document.currentTimecode = 0; + const currentFrame = this.Document.currentFrame; + if (currentFrame === undefined) { + this.Document.currentFrame = 0; CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0); } CollectionFreeFormDocumentView.gotoKeyframe(this.childDocs.slice()); - this.Document.currentTimecode = Math.max(0, (currentTimecode || 0) - 1); + this.Document.currentFrame = Math.max(0, (currentFrame || 0) - 1); } private selectDocuments = (docs: Doc[]) => { @@ -232,9 +233,9 @@ export class CollectionFreeFormView extends CollectionSubView
this.Document.editing = !this.Document.editing)} > - {NumCast(this.Document.currentTimecode)} + {NumCast(this.Document.currentFrame)}
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 88fbdd589..682aed8f5 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -69,21 +69,24 @@ export class CollectionFreeFormDocumentView extends DocComponent (i <= time && x !== undefined) || p === undefined ? x : p, undefined as any as number), - y: Cast(doc["y-indexed"], listSpec("number"), []).reduce((p, y, i) => (i <= time && y !== undefined) || p === undefined ? y : p, undefined as any as number), - opacity: Cast(doc["opacity-indexed"], listSpec("number"), []).reduce((p, o, i) => i <= time || p === undefined ? o : p, undefined as any as number), + x: Cast(doc["x-indexed"], listSpec("number"), []).reduce((p, x, i) => (i <= timecode && x !== undefined) || p === undefined ? x : p, undefined as any as number), + y: Cast(doc["y-indexed"], listSpec("number"), []).reduce((p, y, i) => (i <= timecode && y !== undefined) || p === undefined ? y : p, undefined as any as number), + opacity: Cast(doc["opacity-indexed"], listSpec("number"), []).reduce((p, o, i) => i <= timecode || p === undefined ? o : p, undefined as any as number), }); } - public static setValues(timecode: number, d: Doc, x?: number, y?: number, opacity?: number) { + public static setValues(time: number, d: Doc, x?: number, y?: number, opacity?: number) { + const timecode = Math.round(time); Cast(d["x-indexed"], listSpec("number"), [])[Math.max(0, timecode - 1)] = x as any as number; - Cast(d["y-indexed"], listSpec("number"), null)[Math.max(0, timecode - 1)] = y as any as number; + Cast(d["y-indexed"], listSpec("number"), [])[Math.max(0, timecode - 1)] = y as any as number; Cast(d["x-indexed"], listSpec("number"), [])[timecode] = x as any as number; - Cast(d["y-indexed"], listSpec("number"), null)[timecode] = y as any as number; + Cast(d["y-indexed"], listSpec("number"), [])[timecode] = y as any as number; Cast(d["opacity-indexed"], listSpec("number"), null)[timecode] = opacity as any as number; } - public static updateKeyframe(docs: Doc[], timecode: number) { + public static updateKeyframe(docs: Doc[], time: number) { + const timecode = Math.round(time); docs.forEach(doc => { const xindexed = Cast(doc['x-indexed'], listSpec("number"), null); const yindexed = Cast(doc['y-indexed'], listSpec("number"), null); @@ -112,10 +115,10 @@ export class CollectionFreeFormDocumentView extends DocComponent this.updateCurrentPresentation(); const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null); const lastFrame = Cast(presTargetDoc.lastTimecode, "number", null); - const curFrame = NumCast(presTargetDoc.currentTimecode); + const curFrame = NumCast(presTargetDoc.currentFrame); if (lastFrame !== undefined && curFrame < lastFrame) { - presTargetDoc.currentTimecode = curFrame + 1; + presTargetDoc.currentFrame = curFrame + 1; } else if (this.childDocs[this.itemIndex + 1] !== undefined) { let nextSelected = this.itemIndex + 1; @@ -200,7 +200,7 @@ export class PresBox extends ViewBoxBaseComponent this.rootDoc._itemIndex = index; const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null); if (presTargetDoc.lastTimecode !== undefined) { - presTargetDoc.currentTimecode = 0; + presTargetDoc.currentFrame = 0; } if (!this.layoutDoc.presStatus) { diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index 364c1d060..31ffde8af 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -102,7 +102,7 @@ export class PresElementBox extends ViewBoxBaseComponent Date: Thu, 28 May 2020 18:43:14 -0400 Subject: added aimated transitions to presentations of frame animations --- .../collectionFreeForm/CollectionFreeFormView.tsx | 14 +++++++++++--- src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 5 +++-- src/client/views/nodes/PresBox.tsx | 5 +++++ 3 files changed, 19 insertions(+), 5 deletions(-) (limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 9d10ff158..cb1228fed 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1350,8 +1350,14 @@ export class CollectionFreeFormView extends CollectionSubView - + {this.children} {this._timelineVisible ? : (null)} @@ -1445,6 +1451,7 @@ interface CollectionFreeFormViewPannableContentsProps { viewDefDivClick?: ScriptField; children: () => JSX.Element[]; shifted: boolean; + transition?: string; } @observer @@ -1459,7 +1466,8 @@ class CollectionFreeFormViewPannableContents extends React.Component {this.props.children()}
; diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 682aed8f5..697111ac8 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -96,12 +96,12 @@ export class CollectionFreeFormDocumentView extends DocComponent docs.forEach(doc => doc.transition = undefined), 1010); + setTimeout(() => docs.forEach(doc => doc.transition = "inherit"), 1010); } public static gotoKeyframe(docs: Doc[]) { docs.forEach(doc => doc.transition = "all 1s"); - setTimeout(() => docs.forEach(doc => doc.transition = undefined), 1010); + setTimeout(() => docs.forEach(doc => doc.transition = "inherit"), 1010); } public static setupKeyframes(docs: Doc[], timecode: number, progressivize: boolean = false) { @@ -119,6 +119,7 @@ export class CollectionFreeFormDocumentView extends DocComponent const lastFrame = Cast(presTargetDoc.lastFrame, "number", null); const curFrame = NumCast(presTargetDoc.currentFrame); if (lastFrame !== undefined && curFrame < lastFrame) { + //const docs = DocListCast(presTargetDoc[Doc.LayoutFieldKey(presTargetDoc)]); + presTargetDoc.transition = "all 1s"; + setTimeout(() => presTargetDoc.transition = undefined, 1010); + // docs.forEach(doc => doc.transition = "all 1s"); + // setTimeout(() => docs.forEach(doc => doc.transition = undefined), 1010); presTargetDoc.currentFrame = curFrame + 1; } else if (this.childDocs[this.itemIndex + 1] !== undefined) { -- cgit v1.2.3-70-g09d2 From e23602188d575c3f2303bfc85114ac82561c7bbe Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Fri, 29 May 2020 13:14:59 -0400 Subject: added toggle to switch from fade to default keyframe. added mixBlendMode for collections --- src/client/views/animationtimeline/Keyframe.tsx | 60 +++++++++------------- .../views/nodes/CollectionFreeFormDocumentView.tsx | 1 + 2 files changed, 26 insertions(+), 35 deletions(-) (limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx') diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx index 92b0f05b3..e3274fb35 100644 --- a/src/client/views/animationtimeline/Keyframe.tsx +++ b/src/client/views/animationtimeline/Keyframe.tsx @@ -12,11 +12,9 @@ import { Transform } from "../../util/Transform"; import { TimelineMenu } from "./TimelineMenu"; import { Docs } from "../../documents/Documents"; import { CollectionDockingView } from "../collections/CollectionDockingView"; -import { undoBatch, UndoManager } from "../../util/UndoManager"; import { emptyPath } from "../../../Utils"; - /** * Useful static functions that you can use. Mostly for logic, but you can also add UI logic here also */ @@ -100,16 +98,11 @@ export namespace KeyframeFunc { export const convertPixelTime = (pos: number, unit: "mili" | "sec" | "min" | "hr", dir: "pixel" | "time", tickSpacing: number, tickIncrement: number) => { const time = dir === "pixel" ? (pos * tickSpacing) / tickIncrement : (pos / tickSpacing) * tickIncrement; switch (unit) { - case "mili": - return time; - case "sec": - return dir === "pixel" ? time / 1000 : time * 1000; - case "min": - return dir === "pixel" ? time / 60000 : time * 60000; - case "hr": - return dir === "pixel" ? time / 3600000 : time * 3600000; - default: - return time; + case "mili": return time; + case "sec": return dir === "pixel" ? time / 1000 : time * 1000; + case "min": return dir === "pixel" ? time / 60000 : time * 60000; + case "hr": return dir === "pixel" ? time / 3600000 : time * 3600000; + default: return time; } }; } @@ -333,31 +326,28 @@ export class Keyframe extends React.Component { */ @action makeKeyframeMenu = (kf: Doc, e: MouseEvent) => { - TimelineMenu.Instance.addItem("button", "Show Data", () => { - runInAction(() => { + TimelineMenu.Instance.addItem("button", "Toggle Fade Only", () => { + kf.type = kf.type === KeyframeFunc.KeyframeType.fade ? KeyframeFunc.KeyframeType.default : KeyframeFunc.KeyframeType.fade; + }), + TimelineMenu.Instance.addItem("button", "Show Data", action(() => { const kvp = Docs.Create.KVPDocument(kf, { _width: 300, _height: 300 }); CollectionDockingView.AddRightSplit(kvp, emptyPath); - }); - }), - TimelineMenu.Instance.addItem("button", "Delete", () => { - runInAction(() => { - (this.regiondata.keyframes as List).splice(this.keyframes.indexOf(kf), 1); - this.forceUpdate(); - }); - }), - TimelineMenu.Instance.addItem("input", "Move", (val) => { - runInAction(() => { - let cannotMove: boolean = false; - const 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.addItem("button", "Delete", action(() => { + (this.regiondata.keyframes as List).splice(this.keyframes.indexOf(kf), 1); + this.forceUpdate(); + })), + TimelineMenu.Instance.addItem("input", "Move", action((val) => { + let cannotMove: boolean = false; + const 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"); TimelineMenu.Instance.openMenu(e.clientX, e.clientY); } diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 697111ac8..910aa744d 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -154,6 +154,7 @@ export class CollectionFreeFormDocumentView extends DocComponent -- cgit v1.2.3-70-g09d2