drawface-live / dev /authoring_test.html
ingon1's picture
sync from a4623ed60bfdc48500dc98de93020c59fe69bf34
4635d45 verified
Raw
History Blame Contribute Delete
3.64 kB
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>authoring test</title>
<style>
body { font: 13px system-ui, sans-serif; margin: 16px; background: #f4f4f4; }
#result { font-weight: bold; margin: 8px 0; }
#grid { display: flex; flex-wrap: wrap; gap: 10px; }
figure { margin: 0; background: #fff; border: 1px solid #ccc; padding: 4px; }
figure canvas { display: block; image-rendering: pixelated; }
figcaption { font-size: 11px; text-align: center; margin-top: 2px; }
pre { background: #fff; border: 1px solid #ccc; padding: 8px; max-width: 640px; overflow: auto; }
/* checkerboard so sprite transparency is visible */
.cell { background-image: linear-gradient(45deg, #ddd 25%, transparent 25%),
linear-gradient(-45deg, #ddd 25%, transparent 25%),
linear-gradient(45deg, transparent 75%, #ddd 75%),
linear-gradient(-45deg, transparent 75%, #ddd 75%);
background-size: 16px 16px; background-position: 0 0, 0 8px, 8px -8px, -8px 0; }
</style>
</head>
<body>
<h3>authoring pipeline test</h3>
<div id="result">running…</div>
<div id="grid"></div>
<pre id="manifest"></pre>
<script type="module">
import { fit512, newCanvas, rad } from "../js/imageops.js";
import { buildCharacter } from "../js/onboard.js";
import { deriveAll } from "../js/derive.js";
// (a) synthetic 200x200 drawing: white bg, two dark eye dots, a dark mouth arc.
function syntheticDrawing() {
const c = newCanvas(200, 200);
const g = c.getContext("2d");
g.fillStyle = "#ffffff";
g.fillRect(0, 0, 200, 200);
g.fillStyle = "#202020";
for (const cx of [72, 128]) { g.beginPath(); g.arc(cx, 78, 7, 0, 2 * Math.PI); g.fill(); }
g.strokeStyle = "#202020";
g.lineWidth = 3;
g.beginPath();
g.ellipse(100, 136, 22, 10, 0, rad(20), rad(160), false);
g.stroke();
return c;
}
function cell(label, base, sprite) {
const fig = document.createElement("figure");
const cv = newCanvas(140, 140);
cv.className = "cell";
const ctx = cv.getContext("2d");
ctx.imageSmoothingEnabled = false;
ctx.drawImage(base, 0, 0, 140, 140);
if (sprite !== base) ctx.drawImage(sprite, 0, 0, 140, 140);
fig.appendChild(cv);
const cap = document.createElement("figcaption");
cap.textContent = label;
fig.appendChild(cap);
return fig;
}
try {
// 200x200 square maps to the full 512 canvas (scale 2.56, no offset), so
// feature coords below are the 200-space dots/arc times 2.56.
const drawing = syntheticDrawing();
const canvas512 = fit512(drawing);
const eyes = { L: [184, 200], R: [328, 200] };
const mouthBox = [205, 328, 307, 371];
const { manifest, canvases } = buildCharacter(canvas512, "테스트", eyes, 20, mouthBox);
deriveAll(canvases, manifest);
const base = canvases["base.png"];
const grid = document.getElementById("grid");
for (const [name, sprite] of Object.entries(canvases)) {
grid.appendChild(cell(name, base, sprite));
}
document.getElementById("manifest").textContent = JSON.stringify(manifest, null, 2);
const n = Object.keys(canvases).length;
const msg = `AUTHORING OK ${n}`;
document.title = msg;
document.getElementById("result").textContent = msg;
} catch (err) {
const msg = `AUTHORING FAIL ${err && err.message ? err.message : err}`;
document.title = msg;
document.getElementById("result").textContent = msg;
console.error(err);
}
</script>
</body>
</html>