@remotion/studio 4.0.444 → 4.0.445

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -35,9 +35,21 @@ export declare const getFrameFromX: ({ clientX, durationInFrames, width, extrapo
35
35
  width: number;
36
36
  extrapolate: "clamp" | "extend";
37
37
  }) => number;
38
- export declare const zoomAndPreserveCursor: ({ oldZoom, newZoom, currentFrame, currentDurationInFrames, }: {
38
+ /**
39
+ * Horizontal position inside the scrollable timeline content (0 … scrollWidth)
40
+ * for a viewport `clientX`, so pinch-anchoring matches the pointer (not a
41
+ * rounded frame index).
42
+ */
43
+ export declare const viewportClientXToScrollContentX: ({ clientX, scrollEl, }: {
44
+ clientX: number;
45
+ scrollEl: HTMLDivElement;
46
+ }) => number;
47
+ export declare const zoomAndPreserveCursor: ({ oldZoom, newZoom, currentFrame, currentDurationInFrames, anchorFrame, anchorContentX, }: {
39
48
  oldZoom: number;
40
49
  newZoom: number;
41
50
  currentFrame: number;
42
51
  currentDurationInFrames: number;
52
+ anchorFrame: number | null;
53
+ /** Prefer this over `anchorFrame` when not null (subpixel-accurate anchor). */
54
+ anchorContentX: number | null;
43
55
  }) => void;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.zoomAndPreserveCursor = exports.getFrameFromX = exports.getFrameWhileScrollingRight = exports.getFrameIncrementFromWidth = exports.getScrollPositionForCursorOnRightEdge = exports.getScrollPositionForCursorOnLeftEdge = exports.scrollToTimelineXOffset = exports.ensureFrameIsInViewport = exports.isCursorInViewport = exports.getFrameWhileScrollingLeft = exports.canScrollTimelineIntoDirection = void 0;
3
+ exports.zoomAndPreserveCursor = exports.viewportClientXToScrollContentX = exports.getFrameFromX = exports.getFrameWhileScrollingRight = exports.getFrameIncrementFromWidth = exports.getScrollPositionForCursorOnRightEdge = exports.getScrollPositionForCursorOnLeftEdge = exports.scrollToTimelineXOffset = exports.ensureFrameIsInViewport = exports.isCursorInViewport = exports.getFrameWhileScrollingLeft = exports.canScrollTimelineIntoDirection = void 0;
4
4
  const remotion_1 = require("remotion");
5
5
  const timeline_layout_1 = require("../../helpers/timeline-layout");
6
6
  const timeline_refs_1 = require("./timeline-refs");
@@ -200,9 +200,18 @@ const getFrameFromX = ({ clientX, durationInFrames, width, extrapolate, }) => {
200
200
  return frame;
201
201
  };
202
202
  exports.getFrameFromX = getFrameFromX;
203
- const zoomAndPreserveCursor = ({ oldZoom, newZoom, currentFrame, currentDurationInFrames, }) => {
204
- var _a, _b;
205
- var _c;
203
+ /**
204
+ * Horizontal position inside the scrollable timeline content (0 … scrollWidth)
205
+ * for a viewport `clientX`, so pinch-anchoring matches the pointer (not a
206
+ * rounded frame index).
207
+ */
208
+ const viewportClientXToScrollContentX = ({ clientX, scrollEl, }) => {
209
+ const rect = scrollEl.getBoundingClientRect();
210
+ const clampedClientX = Math.min(Math.max(clientX, rect.left), rect.right);
211
+ return clampedClientX + scrollEl.scrollLeft - rect.left;
212
+ };
213
+ exports.viewportClientXToScrollContentX = viewportClientXToScrollContentX;
214
+ const zoomAndPreserveCursor = ({ oldZoom, newZoom, currentFrame, currentDurationInFrames, anchorFrame, anchorContentX, }) => {
206
215
  const ratio = newZoom / oldZoom;
207
216
  if (ratio === 1) {
208
217
  return;
@@ -212,9 +221,14 @@ const zoomAndPreserveCursor = ({ oldZoom, newZoom, currentFrame, currentDuration
212
221
  return;
213
222
  }
214
223
  const frameIncrement = getFrameIncrement(currentDurationInFrames);
215
- const prevCursorPosition = frameIncrement * currentFrame + timeline_layout_1.TIMELINE_PADDING;
224
+ const frameForScroll = anchorFrame !== null && anchorFrame !== void 0 ? anchorFrame : currentFrame;
225
+ const prevCursorPosition = anchorContentX !== null
226
+ ? Math.min(Math.max(anchorContentX, 0), current.scrollWidth)
227
+ : frameIncrement * frameForScroll + timeline_layout_1.TIMELINE_PADDING;
216
228
  const newCursorPosition = ratio * (prevCursorPosition - timeline_layout_1.TIMELINE_PADDING) + timeline_layout_1.TIMELINE_PADDING;
217
229
  current.scrollLeft += newCursorPosition - prevCursorPosition;
218
- (_a = TimelineSlider_1.redrawTimelineSliderFast.current) === null || _a === void 0 ? void 0 : _a.draw(currentFrame, ((_c = (_b = timeline_refs_1.scrollableRef.current) === null || _b === void 0 ? void 0 : _b.clientWidth) !== null && _c !== void 0 ? _c : 0) * ratio);
230
+ // Playhead position is synced in `TimelineSlider` `useLayoutEffect` using
231
+ // measured `sliderAreaRef.clientWidth` so it matches layout after zoom
232
+ // (avoids fighting React `style` with stale `timelineWidth` during pinch).
219
233
  };
220
234
  exports.zoomAndPreserveCursor = zoomAndPreserveCursor;