aboutsummaryrefslogtreecommitdiffhomepage
path: root/bluebey-studio/src/exporter.js
diff options
context:
space:
mode:
Diffstat (limited to 'bluebey-studio/src/exporter.js')
-rw-r--r--bluebey-studio/src/exporter.js72
1 files changed, 4 insertions, 68 deletions
diff --git a/bluebey-studio/src/exporter.js b/bluebey-studio/src/exporter.js
index b34b6f6..ea9356e 100644
--- a/bluebey-studio/src/exporter.js
+++ b/bluebey-studio/src/exporter.js
@@ -1,7 +1,6 @@
import { traceAlphaContours, contoursToPathData } from './trace.js';
import { roughenContours } from './handDrawn.js';
-import { captionToSvg } from './caption.js';
-import { EYE_LAYOUT, MOUTH_LAYOUT, HAIR_WRAP_LAYOUT } from './faceArt.js';
+import { EYE_LAYOUT, MOUTH_LAYOUT } from './faceArt.js';
/**
* Export helpers.
@@ -67,8 +66,8 @@ export async function capturePNG(view, { scale = 2, background, width, height })
/**
* Encode a canvas as a PNG blob. Exported because the caller composites the
- * backdrop and the caption onto the rendered canvas afterwards, and then has to
- * re-encode it.
+ * backdrop and the 擬音 stamps onto the rendered canvas afterwards, and then has
+ * to re-encode it.
*/
export function canvasToBlob(canvas) {
return new Promise((resolve) => canvas.toBlob(resolve, 'image/png'));
@@ -97,8 +96,6 @@ export function buildSVG(view, {
lineWidth = null,
background = null,
handDrawn = null,
- captions = [],
- captionFont = null,
outlinePixels = 2,
} = {}) {
const previousStyle = styles.style;
@@ -167,27 +164,13 @@ export function buildSVG(view, {
: '';
const widthAttr = lineWidth ? ` stroke="${lineColor}" stroke-width="${lineWidth}"` : '';
- // The caption is authored against the viewport size, so it scales with the
- // requested SVG width. Its bubble and text are emitted as real vector shapes.
- // Every bubble is emitted as its own real vector shapes, one after the other.
- let captionSvg = '';
- let captionUsedOutlines = captions.some(Boolean);
- for (const caption of captions) {
- if (!caption) continue;
- const scale = width / Math.max(1, view.width || 1280);
- const result = captionToSvg(caption, { width, height, scale, font: captionFont });
- captionSvg += result.svg;
- if (result.usedOutlines === false) captionUsedOutlines = false;
- }
-
return {
contours: contours.length,
- captionUsedOutlines,
svg: `<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">
<title>ぶるべー 線画</title>
${rect}<path fill="${lineColor}"${widthAttr} fill-rule="evenodd" d="${d}"/>
-${captionSvg}</svg>
+</svg>
`,
};
}
@@ -275,53 +258,6 @@ export function buildFaceMap(face, kind) {
return canvas;
}
-/**
- * The 髪の下地 (a base to draw hair on).
- *
- * The hair plate is a cylinder unrolled: `x` is the angle round the head, with
- * the face at the middle of the artwork window and the seam at the back at the
- * two edges, and `y` is the height, top of the head first. The current hair is
- * copied in as a faint reference, and guides mark the window, the front centre
- * and the height the default まえがみ hairline reaches.
- *
- * @param {import('./face.js').Face} face
- * @returns {HTMLCanvasElement|null}
- */
-export function buildHairMap(face) {
- const layout = face.hairLayout;
- const plate = face.hairCanvas;
- if (!layout || !plate) return null;
- // The plate's UVs were rewritten to fill 0..1, so the whole canvas is the
- // texture (unlike the eye/mouth maps, which keep a window inside a wider
- // canvas). Every guide is therefore measured straight against the canvas.
- const canvas = document.createElement('canvas');
- canvas.width = plate.width;
- canvas.height = plate.height;
- const ctx = canvas.getContext('2d');
- ctx.drawImage(plate, 0, 0);
-
- // White paper under the copy, so a redraw starts from an opaque base.
- ctx.globalCompositeOperation = 'destination-over';
- ctx.fillStyle = '#ffffff';
- ctx.fillRect(0, 0, canvas.width, canvas.height);
- ctx.globalCompositeOperation = 'source-over';
-
- ctx.strokeStyle = FACE_MAP_GUIDE;
- ctx.fillStyle = FACE_MAP_GUIDE;
- ctx.lineWidth = 3;
-
- // The front of the head sits at the middle of the artwork window, which is
- // where `drawHeadCoverWrap` puts the face, so this vertical line is the
- // nose-to-backbone plane. The canvas's own left/right edges are the seam at
- // the back of the head.
- const fx = (layout.offsetX + layout.window.width * 0.5) * (canvas.width / layout.width);
- guideLine(ctx, fx, 0, fx, canvas.height);
- // The default hairline (大きさ 1) runs across the whole wrap at this height.
- guideLine(ctx, 0, HAIR_WRAP_LAYOUT.base * canvas.height, canvas.width, HAIR_WRAP_LAYOUT.base * canvas.height);
-
- return canvas;
-}
-
/** One guide segment, kept out of the map builders so the placements stay readable. */
function guideLine(ctx, x0, y0, x1, y1) {
ctx.beginPath();