diff options
| author | Yasutake Yohei <61961825+yasutakeyohei@users.noreply.github.com> | 2026-10-09 08:33:42 +0900 |
|---|---|---|
| committer | Yasutake Yohei <61961825+yasutakeyohei@users.noreply.github.com> | 2026-10-09 08:33:42 +0900 |
| commit | 9deb6762ef5794b340943e2d2845da79c437dce5 (patch) | |
| tree | 817a24ae56d7b06f5964f68682432ccb9febff02 /bluebey-studio/src/exporter.js | |
| parent | 1b883a70b9d3427e7cb65eaf99d2aa7ca5a1cb1c (diff) | |
bluebey-studio: 準拠版(フキダシ・眉毛・髪・ひげ・ほっぺ・体の色を削除)
ぶるべーはしゃべらない・姿を変えない方針に合わせた準拠版。セリフ/ナレーション/吹き出し・口パク・眉毛(ゴルゴ等)・髪(頭の模様)・ひげ・ほっぺ・体の色/テーマを削除。目・口・眼鏡・帽子・鼻ちょうちん・ポーズ・背景・小物・光・書き出しは維持。caption.js / mouthFlap.js は削除。
Diffstat (limited to 'bluebey-studio/src/exporter.js')
| -rw-r--r-- | bluebey-studio/src/exporter.js | 72 |
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(); |
