diff options
| author | Yasutake Yohei <61961825+yasutakeyohei@users.noreply.github.com> | 2026-10-23 09:24:54 +0900 |
|---|---|---|
| committer | Yasutake Yohei <61961825+yasutakeyohei@users.noreply.github.com> | 2026-10-23 09:24:54 +0900 |
| commit | 09ab25113c299b8f3208a717cee9e9b8c7b07fe9 (patch) | |
| tree | 3124aef01815fdf4484d5d2cc8e735b50d1d2969 /public/bluebey-studio/src/exporter.js | |
| parent | 2ced83398189ac47588ddde87fdbf5cae106aa4d (diff) | |
bluebey-studio: ドラッグの役割を入れ替え、回転中心をぶるべーに固定
Diffstat (limited to 'public/bluebey-studio/src/exporter.js')
| -rw-r--r-- | public/bluebey-studio/src/exporter.js | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/public/bluebey-studio/src/exporter.js b/public/bluebey-studio/src/exporter.js index cc9c1ca..cad9ef0 100644 --- a/public/bluebey-studio/src/exporter.js +++ b/public/bluebey-studio/src/exporter.js @@ -10,13 +10,22 @@ import { roughenContours } from './handDrawn.js'; */ /** Render the current view into an offscreen 2D canvas at an arbitrary size. */ -export function renderStill(view, { width, height, background }) { +export function renderStill(view, { width, height, background, viewOffset = null }) { const { renderer, scene, camera } = view; const previousAspect = camera.aspect; + // The live camera may already carry a projection shift (the pan). It is stored + // in CSS pixels against the viewport, so it has to be re-applied for the + // export's own pixel size - and restored afterwards. + const previousView = camera.view ? { ...camera.view } : null; renderer.setPixelRatio(1); renderer.setSize(width, height, false); camera.aspect = width / height; + if (viewOffset && (viewOffset.x || viewOffset.y)) { + camera.setViewOffset(width, height, -viewOffset.x * width, -viewOffset.y * height, width, height); + } else { + camera.clearViewOffset(); + } camera.updateProjectionMatrix(); applyBackground(renderer, background); @@ -37,6 +46,8 @@ export function renderStill(view, { width, height, background }) { canvas.getContext('2d').drawImage(renderer.domElement, 0, 0); camera.aspect = previousAspect; + if (previousView) camera.view = previousView; + else camera.clearViewOffset(); camera.updateProjectionMatrix(); view.restore?.(); @@ -53,12 +64,12 @@ export function applyBackground(renderer, background) { } /** A PNG data URL of the current view, scaled up by `scale`. */ -export async function capturePNG(view, { scale = 2, background, width, height }) { +export async function capturePNG(view, { scale = 2, background, width, height, viewOffset = null }) { const baseWidth = view.width || view.renderer.domElement.clientWidth || 1280; const baseHeight = view.height || view.renderer.domElement.clientHeight || 800; const outWidth = Math.min(8192, Math.max(64, Math.round((width ?? baseWidth) * scale))); const outHeight = Math.min(8192, Math.max(64, Math.round((height ?? baseHeight) * scale))); - const canvas = renderStill(view, { width: outWidth, height: outHeight, background }); + const canvas = renderStill(view, { width: outWidth, height: outHeight, background, viewOffset }); const blob = await canvasToBlob(canvas); return { blob, canvas, width: outWidth, height: outHeight }; } |
