@hyperframes/studio 0.8.185 → 0.8.186
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/assets/{hyperframes-player-CoOdf435.js → hyperframes-player-B_skzvYC.js} +1 -1
- package/dist/assets/{index-CR85xg2x.js → index-CgLbvCUo.js} +1 -1
- package/dist/assets/{index-C_6rTpaB.js → index-Dn5FAk2e.js} +99 -99
- package/dist/index.html +1 -1
- package/dist/index.js +6 -1
- package/package.json +8 -8
- package/src/components/renders/useRenderQueue.ts +8 -0
- package/src/components/renders/useRenderQueueMotionBlur.test.tsx +61 -0
package/dist/index.html
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
document.documentElement.dataset.theme = "paper";
|
|
15
15
|
}
|
|
16
16
|
</script>
|
|
17
|
-
<script type="module" crossorigin src="/assets/index-
|
|
17
|
+
<script type="module" crossorigin src="/assets/index-Dn5FAk2e.js"></script>
|
|
18
18
|
<link rel="stylesheet" crossorigin href="/assets/index-CESvLzz0.css">
|
|
19
19
|
</head>
|
|
20
20
|
<body>
|
package/dist/index.js
CHANGED
|
@@ -72983,6 +72983,7 @@ function useRightPanelIntent() {
|
|
|
72983
72983
|
}
|
|
72984
72984
|
|
|
72985
72985
|
// src/components/renders/useRenderQueue.ts
|
|
72986
|
+
import { htmlInCanvasForm } from "@hyperframes/core/html-in-canvas";
|
|
72986
72987
|
import { useState as useState109, useEffect as useEffect106, useCallback as useCallback95, useRef as useRef119, useMemo as useMemo69 } from "react";
|
|
72987
72988
|
|
|
72988
72989
|
// src/components/renders/serverError.ts
|
|
@@ -73206,6 +73207,9 @@ function markFeedbackDismissed() {
|
|
|
73206
73207
|
}
|
|
73207
73208
|
|
|
73208
73209
|
// src/components/renders/useRenderQueue.ts
|
|
73210
|
+
function canPreviewMotionBlur() {
|
|
73211
|
+
return typeof document !== "undefined" && htmlInCanvasForm() !== null;
|
|
73212
|
+
}
|
|
73209
73213
|
function hiddenIdsKey(projectId) {
|
|
73210
73214
|
return `hf-studio-hidden-renders:${projectId}`;
|
|
73211
73215
|
}
|
|
@@ -73320,7 +73324,8 @@ function useRenderQueue(projectId, activeCompPathRef) {
|
|
|
73320
73324
|
const body = {
|
|
73321
73325
|
fps,
|
|
73322
73326
|
quality,
|
|
73323
|
-
format
|
|
73327
|
+
format,
|
|
73328
|
+
previewMotionBlur: canPreviewMotionBlur()
|
|
73324
73329
|
};
|
|
73325
73330
|
if (browserTelemetryAllowed()) {
|
|
73326
73331
|
body.telemetryDistinctId = getAnonymousId();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperframes/studio",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.186",
|
|
4
4
|
"description": "",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -59,12 +59,12 @@
|
|
|
59
59
|
"dockview-react": "8.3.1",
|
|
60
60
|
"gsap": "^3.13.0",
|
|
61
61
|
"mediabunny": "^1.45.3",
|
|
62
|
-
"@hyperframes/core": "0.8.
|
|
63
|
-
"@hyperframes/
|
|
64
|
-
"@hyperframes/shader-transitions": "0.8.
|
|
65
|
-
"@hyperframes/
|
|
66
|
-
"@hyperframes/
|
|
67
|
-
"@hyperframes/
|
|
62
|
+
"@hyperframes/core": "0.8.186",
|
|
63
|
+
"@hyperframes/player": "0.8.186",
|
|
64
|
+
"@hyperframes/shader-transitions": "0.8.186",
|
|
65
|
+
"@hyperframes/studio-server": "0.8.186",
|
|
66
|
+
"@hyperframes/sdk": "0.8.186",
|
|
67
|
+
"@hyperframes/parsers": "0.8.186"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
70
|
"@tailwindcss/vite": "^4.3.3",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"vite": "^6.4.2",
|
|
82
82
|
"vitest": "^4.1.11",
|
|
83
83
|
"zustand": "^5.0.0",
|
|
84
|
-
"@hyperframes/producer": "0.8.
|
|
84
|
+
"@hyperframes/producer": "0.8.186"
|
|
85
85
|
},
|
|
86
86
|
"peerDependencies": {
|
|
87
87
|
"react": "19",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { htmlInCanvasForm } from "@hyperframes/core/html-in-canvas";
|
|
1
2
|
import { buildProjectApiPath } from "../../utils/projectRouting";
|
|
2
3
|
import { useState, useEffect, useCallback, useRef, useMemo } from "react";
|
|
3
4
|
import type { CanvasResolution } from "@hyperframes/parsers";
|
|
@@ -10,6 +11,11 @@ import { ffmpegInstallMessage, useFfmpegStatus } from "./useFfmpegStatus";
|
|
|
10
11
|
import { requestStudioFeedback, type FeedbackContext } from "../feedback/feedbackTrigger";
|
|
11
12
|
import { studioApiFetch } from "../../utils/studioApiFetch";
|
|
12
13
|
|
|
14
|
+
// WYSIWYG: the preview iframe runs in this browser, so a render blurs only if this one can.
|
|
15
|
+
function canPreviewMotionBlur(): boolean {
|
|
16
|
+
return typeof document !== "undefined" && htmlInCanvasForm() !== null;
|
|
17
|
+
}
|
|
18
|
+
|
|
13
19
|
export interface RenderJob {
|
|
14
20
|
id: string;
|
|
15
21
|
status: "rendering" | "complete" | "failed" | "cancelled";
|
|
@@ -238,10 +244,12 @@ export function useRenderQueue(
|
|
|
238
244
|
gpu?: boolean;
|
|
239
245
|
telemetryDistinctId?: string;
|
|
240
246
|
telemetryOptOut?: boolean;
|
|
247
|
+
previewMotionBlur: boolean;
|
|
241
248
|
} = {
|
|
242
249
|
fps,
|
|
243
250
|
quality,
|
|
244
251
|
format,
|
|
252
|
+
previewMotionBlur: canPreviewMotionBlur(),
|
|
245
253
|
};
|
|
246
254
|
// The id is MINTED by getAnonymousId(), so calling it unconditionally
|
|
247
255
|
// created a telemetry identity for a profile that had opted out — and
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// @vitest-environment happy-dom
|
|
2
|
+
|
|
3
|
+
// WYSIWYG: a render only blurs what the Studio preview could show, and only the browser knows
|
|
4
|
+
// whether it has html-in-canvas. The request body is how it tells the server.
|
|
5
|
+
|
|
6
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
7
|
+
import { startRenderAndReadBody, type MountedQueue } from "./renderQueueTestHarness";
|
|
8
|
+
|
|
9
|
+
vi.mock("../../telemetry/events", () => ({ trackStudioRenderStart: vi.fn() }));
|
|
10
|
+
|
|
11
|
+
const { useRenderQueue } = await import("./useRenderQueue");
|
|
12
|
+
|
|
13
|
+
let queue: MountedQueue | null = null;
|
|
14
|
+
|
|
15
|
+
async function startRenderBody(): Promise<Record<string, unknown>> {
|
|
16
|
+
const started = await startRenderAndReadBody(useRenderQueue, {
|
|
17
|
+
opts: { fps: 30, quality: "standard", format: "mp4" },
|
|
18
|
+
});
|
|
19
|
+
queue = started.queue;
|
|
20
|
+
return started.body;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function stubHtmlInCanvas(members: string[]): void {
|
|
24
|
+
vi.stubGlobal(
|
|
25
|
+
"CanvasRenderingContext2D",
|
|
26
|
+
class {
|
|
27
|
+
drawElementImage(): void {}
|
|
28
|
+
},
|
|
29
|
+
);
|
|
30
|
+
const proto = HTMLCanvasElement.prototype as unknown as Record<string, unknown>;
|
|
31
|
+
for (const name of ["requestPaint", ...members]) proto[name] = () => {};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
afterEach(() => {
|
|
35
|
+
queue?.unmount();
|
|
36
|
+
queue = null;
|
|
37
|
+
document.body.innerHTML = "";
|
|
38
|
+
for (const name of ["requestPaint", "layoutSubtree", "updateElementGeometry"]) {
|
|
39
|
+
delete (HTMLCanvasElement.prototype as unknown as Record<string, unknown>)[name];
|
|
40
|
+
}
|
|
41
|
+
vi.unstubAllGlobals();
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
describe("render request previewMotionBlur", () => {
|
|
45
|
+
it("is false in a browser without html-in-canvas", async () => {
|
|
46
|
+
expect((await startRenderBody())["previewMotionBlur"]).toBe(false);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it.each([
|
|
50
|
+
["the layoutsubtree form", "layoutSubtree"],
|
|
51
|
+
["the content=drawable form", "updateElementGeometry"],
|
|
52
|
+
])("is true in a browser with html-in-canvas in %s", async (_name, member) => {
|
|
53
|
+
stubHtmlInCanvas([member]);
|
|
54
|
+
expect((await startRenderBody())["previewMotionBlur"]).toBe(true);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("is false when html-in-canvas has neither known form", async () => {
|
|
58
|
+
stubHtmlInCanvas([]);
|
|
59
|
+
expect((await startRenderBody())["previewMotionBlur"]).toBe(false);
|
|
60
|
+
});
|
|
61
|
+
});
|