diff options
author | Michael Foiani <sotech117@michaels-mbp-5.devices.brown.edu> | 2022-06-01 14:01:06 -0400 |
---|---|---|
committer | Michael Foiani <sotech117@michaels-mbp-5.devices.brown.edu> | 2022-06-01 14:01:06 -0400 |
commit | 22d39de00ed9a246c520c4c9b1d049a151465d73 (patch) | |
tree | 6c1097bed5321bc3a2f218859c9dd8bc018ab259 | |
parent | f792c3573aec834bb5540d1d2ceb4486a92e03ef (diff) |
now tracks and replays scaling accurately
-rw-r--r-- | src/client/util/RecordingApi.ts | 83 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 10 | ||||
-rw-r--r-- | src/client/views/nodes/VideoBox.tsx | 5 |
3 files changed, 49 insertions, 49 deletions
diff --git a/src/client/util/RecordingApi.ts b/src/client/util/RecordingApi.ts index 7d8df0bfc..87f44bec4 100644 --- a/src/client/util/RecordingApi.ts +++ b/src/client/util/RecordingApi.ts @@ -3,11 +3,14 @@ import { IReactionDisposer, observable, reaction } from "mobx"; import { NumCast } from "../../fields/Types"; import { Doc } from "../../fields/Doc"; import { VideoBox } from "../views/nodes/VideoBox"; +import { scaleDiverging } from "d3-scale"; +import { Transform } from "./Transform"; type Movement = { time: number, panX: number, panY: number, + scale: number, } type Presentation = { @@ -120,7 +123,7 @@ export class RecordingApi { this.absoluteStart = new Date().getTime() - this.absoluteStart } - private trackMovements = (panX: number, panY: number): Error | undefined => { + private trackMovements = (panX: number, panY: number, scale: number = 0): Error | undefined => { // ensure we are recording if (!this.isRecording) { return new Error('[recordingApi.ts] trackMovements()') @@ -133,8 +136,7 @@ export class RecordingApi { // get the time const time = new Date().getTime() - this.absoluteStart // make new movement object - console.log(time) - const movement: Movement = { time, panX, panY } + const movement: Movement = { time, panX, panY, scale } // add that movement to the current presentation data's movement array this.currentPresentation.movements && this.currentPresentation.movements.push(movement) @@ -147,13 +149,16 @@ export class RecordingApi { // set the FFView that will be used in a reaction to track the movements public setRecordingFFView = (view: CollectionFreeFormView): void => { // set the view to the current view - if (view === this.recordingFFView || view === null) return; + if (view === this.recordingFFView || view == null) return; // this.recordingFFView = view; // set the reaction to track the movements this.disposeFunc = reaction( - () => ({ x: NumCast(view.Document.panX, -1), y: NumCast(view.Document.panY, -1) }), - (res) => (res.x !== -1 && res.y !== -1) && this.trackMovements(res.x, res.y) + () => ({ x: NumCast(view.Document.panX, -1), y: NumCast(view.Document.panY, -1), scale: NumCast(view.Document.viewScale, -1) }), + (res) => { + console.log('scale', res.scale); + (res.x !== -1 && res.y !== -1 && this.isRecording) && this.trackMovements(res.x, res.y, res.scale); + } ) // for now, set the most recent recordingFFView to the playFFView @@ -175,6 +180,8 @@ export class RecordingApi { this.playFFView = view } + // pausing movements will dispose all timers that are planned to replay the movements + // play movemvents will recreate them when the user resumes the presentation public pauseMovements = (): undefined | Error => { if (this.playFFView === null) { return new Error('[recordingApi.ts] pauseMovements() failed: no view') @@ -196,7 +203,9 @@ export class RecordingApi { // by calling pause on the VideoBox, the pauseMovements will be called public pauseVideoAndMovements = (): boolean => { this.videoBox?.Pause() - return this.videoBox === null + + this.pauseMovements() + return this.videoBox == null } public _isPlaying = false; @@ -215,48 +224,36 @@ export class RecordingApi { Doc.UserDoc().presentationMode = 'watching'; // TODO: consider this bug at the end of the clip on seek - // console.log(timeViewed) this.videoBox = videoBox || null; - const document = this.playFFView.Document - const { movements } = presentation + // only get the movements that are remaining in the video time left + const filteredMovements = presentation.movements.filter(movement => movement.time > timeViewed * 1000) - const filteredMovements = movements.filter(movement => movement.time > timeViewed * 1000) - - document._panX = filteredMovements[0].panX; - document._panY = filteredMovements[0].panY; - + // helper to replay a movement + const document = this.playFFView + let preScale = -1; + const zoomAndPan = (movement: Movement) => { + const { panX, panY, scale } = movement; + (scale !== -1 && preScale !== scale) && document.zoomSmoothlyAboutPt([panX, panY], scale, 0); + document.Document._panX = panX; + document.Document._panY = panY; + + preScale = scale; + } + + // set the first frame to be at the start of the pres + zoomAndPan(filteredMovements[0]); + + // make timers that will execute each movement at the correct replay time this.timers = filteredMovements.map(movement => { - const { panX, panY, time } = movement - const timeDiff = time - timeViewed*1000 + const timeDiff = movement.time - timeViewed*1000 return setTimeout(() => { - document._panX = panX; - document._panY = panY; - if (movement === movements[movements.length - 1]) { - // stuff for recording API - RecordingApi.Instance._isPlaying = false; - } + // replay the movement + zoomAndPan(movement) + // if last movement, presentation is done -> set the instance var + if (movement === filteredMovements[filteredMovements.length - 1]) RecordingApi.Instance._isPlaying = false; }, timeDiff) - }, []) - - // this.timers = movements.reduce((arr: NodeJS.Timeout[], movement) => { - // const { panX, panY, time } = movement - - // const timeDiff = time - timeViewed*1000 - // if (timeDiff < 0) return arr; - - // // set the pan to what was stored - // arr.push(setTimeout(() => { - // document._panX = panX; - // document._panY = panY; - // if (movement === movements[movements.length - 1]) { - // // stuff for recording API - // RecordingApi.Instance._isPlaying = false; - // } - // }, timeDiff)) - // return arr; - // }, []) - + }) } // Unfinished code for tracing multiple free form views diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index aa2e0c417..19ae99743 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -942,6 +942,12 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection deltaScale = NumCast(this.rootDoc._viewScaleMin, 1) / invTransform.Scale; } + // console.log('zoom scaling', this.zoomScaling()) + console.log('delta scaling', deltaScale) + + // console.log('transform abt zoomScaling', this.getLocalTransform().inverse().scaleAbout(this.zoomScaling(), x, y)); + + const localTransform = this.getLocalTransform().inverse().scaleAbout(deltaScale, x, y); if (localTransform.Scale >= 0.05 || localTransform.Scale > this.zoomScaling()) { const safeScale = Math.min(Math.max(0.05, localTransform.Scale), 20); @@ -966,9 +972,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection @action setPan(panX: number, panY: number, panTime: number = 0, clamp: boolean = false) { // set the current respective FFview to the tab being panned. - Doc.UserDoc()?.presentationMode === 'recording' && RecordingApi.Instance.setRecordingFFView(this); + (Doc.UserDoc()?.presentationMode === 'recording') && RecordingApi.Instance.setRecordingFFView(this); // TODO: make this based off the specific recording FFView - Doc.UserDoc()?.presentationMode === 'none' && RecordingApi.Instance.setPlayFFView(this); + (Doc.UserDoc()?.presentationMode === 'none') && RecordingApi.Instance.setPlayFFView(this); if (Doc.UserDoc()?.presentationMode === 'watching') { RecordingApi.Instance.pauseVideoAndMovements(); Doc.UserDoc().presentationMode = 'none'; diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 902f19716..baa0ae709 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -365,10 +365,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp // vref.onfullscreenchange = action((e) => this._fullScreen = vref.webkitDisplayingFullscreen); this._disposers.reactionDisposer?.(); this._disposers.reactionDisposer = reaction(() => NumCast(this.layoutDoc._currentTimecode), - time => { - !this._playing && (vref.currentTime = time); - console.log("vref time = " + vref.currentTime) - }, { fireImmediately: true }); + time => !this._playing && (vref.currentTime = time), { fireImmediately: true }); } } |