@pixerate/editor-react 0.59.0 → 0.61.0
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.
- package/dist/{chunk-SYTV33TW.js → chunk-OSOGA2OJ.js} +90 -18
- package/dist/chunk-OSOGA2OJ.js.map +1 -0
- package/dist/image-editor/index.cjs +77 -8
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +9 -3
- package/dist/image-editor/index.d.ts +9 -3
- package/dist/image-editor/index.js +1 -1
- package/dist/index.cjs +77 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/video-editor/index.cjs +36 -0
- package/dist/video-editor/index.cjs.map +1 -1
- package/dist/video-editor/index.d.cts +1 -11
- package/dist/video-editor/index.d.ts +1 -11
- package/dist/video-editor/index.js +37 -1
- package/dist/video-editor/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-SYTV33TW.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -205,6 +205,18 @@ function VideoTransport({ controller, editable = true, className = "" }) {
|
|
|
205
205
|
" / ",
|
|
206
206
|
(0, import_video_editor4.formatVideoTimecode)(duration, project.fps)
|
|
207
207
|
] }),
|
|
208
|
+
(0, import_video_editor4.videoProjectHasProxies)(project) && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
209
|
+
"select",
|
|
210
|
+
{
|
|
211
|
+
className: "rounded border border-border bg-transparent px-1 py-0.5 text-xs",
|
|
212
|
+
value: String(state.previewScale),
|
|
213
|
+
onChange: (e) => controller.setPreviewScale((0, import_video_editor4.parseVideoPreviewScale)(e.target.value)),
|
|
214
|
+
"aria-label": "Preview size",
|
|
215
|
+
title: "Play proxies in the preview (the export always uses the originals)",
|
|
216
|
+
"data-preview-scale": "",
|
|
217
|
+
children: import_video_editor4.VIDEO_PREVIEW_SCALE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: o.value, children: o.label }, o.value))
|
|
218
|
+
}
|
|
219
|
+
),
|
|
208
220
|
editable && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
209
221
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-1 h-4 w-px bg-border" }),
|
|
210
222
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: btn, onClick: () => controller.splitAtPlayhead(), disabled: !canEdit, title: "Split at the playhead (S)", "data-split": "", children: "Split" }),
|
|
@@ -253,6 +265,27 @@ function ClipWaveform({ controller, clip, asset, width, height }) {
|
|
|
253
265
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "pointer-events-none absolute inset-0", width, height, "aria-hidden": "true", "data-waveform": clip.id, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d, fill: "currentColor", fillOpacity: 0.45 }) });
|
|
254
266
|
}
|
|
255
267
|
var isField = (el) => el instanceof HTMLElement && /^(INPUT|TEXTAREA|SELECT)$/.test(el.tagName);
|
|
268
|
+
function useCachedRanges(controller, project, px) {
|
|
269
|
+
const [ranges, setRanges] = (0, import_react4.useState)([]);
|
|
270
|
+
(0, import_react4.useEffect)(() => {
|
|
271
|
+
const cache = controller.frameCache;
|
|
272
|
+
if (!cache) return setRanges([]);
|
|
273
|
+
let timer = null;
|
|
274
|
+
const read = () => {
|
|
275
|
+
timer = null;
|
|
276
|
+
setRanges(cache.cachedRanges(project, { step: 2e3 / px }));
|
|
277
|
+
};
|
|
278
|
+
read();
|
|
279
|
+
const off = cache.subscribe(() => {
|
|
280
|
+
timer ??= setTimeout(read, 250);
|
|
281
|
+
});
|
|
282
|
+
return () => {
|
|
283
|
+
off();
|
|
284
|
+
if (timer) clearTimeout(timer);
|
|
285
|
+
};
|
|
286
|
+
}, [controller, project, px]);
|
|
287
|
+
return ranges;
|
|
288
|
+
}
|
|
256
289
|
function VideoTimeline({ controller, pxPerSecond, onPxPerSecondChange, editable = true, waveforms = "audio", className = "" }) {
|
|
257
290
|
const state = useVideoEditorState(controller);
|
|
258
291
|
const { project, duration, time, selection, readOnly, error } = state;
|
|
@@ -268,6 +301,7 @@ function VideoTimeline({ controller, pxPerSecond, onPxPerSecondChange, editable
|
|
|
268
301
|
const span = Math.max(duration + 5e3, 1e4);
|
|
269
302
|
const width = msToPx(span);
|
|
270
303
|
const ticks = (0, import_video_editor5.videoRulerTicks)(span, px, project.fps);
|
|
304
|
+
const cached = useCachedRanges(controller, project, px);
|
|
271
305
|
const seekAt = (clientX) => {
|
|
272
306
|
const box = ruler.current.getBoundingClientRect();
|
|
273
307
|
controller.seek(Math.max(0, (clientX - box.left) * 1e3 / px));
|
|
@@ -429,6 +463,7 @@ function VideoTimeline({ controller, pxPerSecond, onPxPerSecondChange, editable
|
|
|
429
463
|
},
|
|
430
464
|
children: [
|
|
431
465
|
ticks.map((t) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: `absolute bottom-0 w-px ${t.major ? "h-2.5 bg-muted-foreground/70" : "h-1 bg-muted-foreground/40"}`, style: { left: t.x }, "data-tick": t.time, children: t.label && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "absolute -top-3.5 left-1 whitespace-nowrap tabular-nums", children: t.label }) }, t.time)),
|
|
466
|
+
cached.map((r) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "pointer-events-none absolute bottom-0 h-[3px] bg-emerald-500/70", style: { left: msToPx(r.start), width: Math.max(1, msToPx(r.end - r.start)) }, title: "Frames cached: plays and scrubs without waiting", "data-cached-range": "" }, r.start)),
|
|
432
467
|
(project.markers ?? []).map((m) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
433
468
|
"div",
|
|
434
469
|
{
|
|
@@ -933,6 +968,7 @@ function MediaBin({ controller, editable = true, fileToUrl, probe = import_video
|
|
|
933
968
|
project.assets.length ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("ul", { className: "flex flex-col gap-1", "aria-label": "Media assets", children: project.assets.map((asset) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("li", { className: "flex items-center gap-2 text-xs", "data-asset": asset.id, children: [
|
|
934
969
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "rounded bg-muted px-1 text-[10px] uppercase text-muted-foreground", "data-asset-kind": "", children: asset.kind }),
|
|
935
970
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "min-w-0 flex-1 truncate", title: asset.src, children: asset.name ?? asset.id }),
|
|
971
|
+
asset.proxies?.length ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "rounded bg-muted px-1 text-[10px] text-muted-foreground", title: `Proxies: ${asset.proxies.map((p) => `${p.scale * 100}%`).join(", ")} (the preview can play these; exports use the original)`, "data-asset-proxies": "", children: "proxy" }) : null,
|
|
936
972
|
asset.duration !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "tabular-nums text-muted-foreground", children: (0, import_video_editor7.formatVideoSeconds)(asset.duration) }),
|
|
937
973
|
editable && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: btn3, disabled: !canEdit, onClick: () => addToTimeline(asset), "data-add-to-timeline": "", children: "Add to timeline" })
|
|
938
974
|
] }, asset.id)) }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { className: "text-xs text-muted-foreground", children: [
|