multiplane 0.3.1 → 0.3.3
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/README.en.md +2 -0
- package/README.md +2 -0
- package/package.json +1 -1
- package/skills/multiplane/SKILL.md +1 -1
- package/src/doctor.mjs +2 -2
- package/src/server.mjs +2 -1
- package/src/three-package.mjs +26 -0
package/README.en.md
CHANGED
|
@@ -254,6 +254,8 @@ npx multiplane stills shot.html --every 0.5
|
|
|
254
254
|
|
|
255
255
|
## 3D layer
|
|
256
256
|
|
|
257
|
+
The desktop app and its bundled command already include three.js (pinned at 0.180.0) for the 3D layer; nothing else to install. With the npm package, three.js is an optional dependency that projects using the 3D layer install themselves:
|
|
258
|
+
|
|
257
259
|
```sh
|
|
258
260
|
npm install three@0.180.0
|
|
259
261
|
```
|
package/README.md
CHANGED
package/package.json
CHANGED
|
@@ -117,7 +117,7 @@ Use `/* multiplane-disable-next-line css_animation */` in CSS and `<!-- multipla
|
|
|
117
117
|
|
|
118
118
|
## 3D layer (optional)
|
|
119
119
|
|
|
120
|
-
Use `multiplane/three` when you need 3D cards or depth of field.
|
|
120
|
+
Use `multiplane/three` when you need 3D cards or depth of field. When the renderer is the desktop app's bundled command, three.js 0.180.0 is already included. With the npm package, install `three@0.180.0` in the project (`npm install three@0.180.0`). `multiplane doctor` reports whether three.js is available, its version and where it comes from.
|
|
121
121
|
|
|
122
122
|
```html
|
|
123
123
|
<script type="importmap">{"imports":{
|
package/src/doctor.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import { runCommand } from './events.mjs';
|
|
|
3
3
|
import { launchBrowser, environment, warnGpuFallback } from './environment.mjs';
|
|
4
4
|
import { inspectFFmpeg, ffmpegOutput } from './ffmpeg.mjs';
|
|
5
5
|
import { MultiplaneError } from './errors.mjs';
|
|
6
|
+
import { threeCheck } from './three-package.mjs';
|
|
6
7
|
|
|
7
8
|
export function benchmarkCheck(record, machine) {
|
|
8
9
|
const current = validBenchmark(record, machine);
|
|
@@ -48,8 +49,7 @@ export const doctor = (options = {}) => runCommand('doctor', null, options, asyn
|
|
|
48
49
|
for (const name of ['libvpx-vp9', 'prores_ks']) checks.push({ name, ok: false, detail: `${name} is optional; encoder availability could not be inspected.` });
|
|
49
50
|
}
|
|
50
51
|
if (info) events.emit('environment', { ...info, ffmpeg: ffmpeg ?? null });
|
|
51
|
-
|
|
52
|
-
catch { checks.push({ name: 'three', ok: false, detail: 'Optional three.js is not installed.' }); }
|
|
52
|
+
checks.push(await threeCheck());
|
|
53
53
|
if (failure && checks.some(c => ['ffmpeg', 'libx264'].includes(c.name) && !c.ok)) failure.hint = (failure.hint ? failure.hint + ' ' : '') + 'Run multiplane config set ffmpeg <path> to save an FFmpeg executable.';
|
|
54
54
|
if (failure) { failure.result = { data: { checks, config: events.config } }; throw failure; }
|
|
55
55
|
return { checks, config: events.config };
|
package/src/server.mjs
CHANGED
|
@@ -5,6 +5,7 @@ import { stat, readdir } from 'node:fs/promises';
|
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
7
|
import { MultiplaneError, invalidOption } from './errors.mjs';
|
|
8
|
+
import { resolveThree } from './three-package.mjs';
|
|
8
9
|
|
|
9
10
|
export const root = process.cwd();
|
|
10
11
|
const packageRoot = fileURLToPath(new URL('../', import.meta.url));
|
|
@@ -52,7 +53,7 @@ export async function startServer(port = 0, root = process.cwd()) {
|
|
|
52
53
|
if (pathname.startsWith('/multiplane/runtime/')) { resourceRoot = path.join(packageRoot, 'src/runtime'); resourcePath = pathname.slice('/multiplane/runtime'.length); }
|
|
53
54
|
else if (pathname === '/multiplane/three.js') { resourceRoot = path.join(packageRoot, 'src/three'); resourcePath = '/index.js'; }
|
|
54
55
|
else if (pathname.startsWith('/multiplane/vendor/three/')) {
|
|
55
|
-
resourceRoot =
|
|
56
|
+
resourceRoot = (await resolveThree()).root;
|
|
56
57
|
resourcePath = pathname.slice('/multiplane/vendor/three'.length);
|
|
57
58
|
if (!/^\/(build|examples\/jsm)\/.*\.js$/.test(resourcePath)) { res.writeHead(403); return res.end(); }
|
|
58
59
|
} else { res.writeHead(404); return res.end(); }
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
|
|
5
|
+
// Desktop bundles keep the tested subset separate from optional npm peers.
|
|
6
|
+
export async function resolveThree() {
|
|
7
|
+
let root = fileURLToPath(new URL('../vendor/three/', import.meta.url));
|
|
8
|
+
let source = 'bundled';
|
|
9
|
+
let pkg;
|
|
10
|
+
try { pkg = JSON.parse(await readFile(path.join(root, 'package.json'), 'utf8')); }
|
|
11
|
+
catch (error) {
|
|
12
|
+
if (error.code !== 'ENOENT') throw error;
|
|
13
|
+
root = path.dirname(path.dirname(fileURLToPath(import.meta.resolve('three'))));
|
|
14
|
+
pkg = JSON.parse(await readFile(path.join(root, 'package.json'), 'utf8'));
|
|
15
|
+
source = 'project';
|
|
16
|
+
}
|
|
17
|
+
return { root, version: pkg.version, source };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export async function threeCheck() {
|
|
21
|
+
try {
|
|
22
|
+
const { root, version, source } = await resolveThree();
|
|
23
|
+
await readFile(path.join(root, 'build/three.module.js'));
|
|
24
|
+
return { name: 'three', ok: true, detail: `three.js ${version} is available (${source === 'bundled' ? 'bundled with software' : 'installed by project'}).` };
|
|
25
|
+
} catch { return { name: 'three', ok: false, detail: 'Optional three.js is not installed.' }; }
|
|
26
|
+
}
|