aboutsummaryrefslogtreecommitdiffhomepage
path: root/public/bluebey-studio/src/exporter.js
diff options
context:
space:
mode:
Diffstat (limited to 'public/bluebey-studio/src/exporter.js')
-rw-r--r--public/bluebey-studio/src/exporter.js17
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 };
}