Cast page: use your own picture of the character

This commit is contained in:
gator 2026-09-22 15:06:56 +00:00
parent 0b9de99303
commit bb7d9b5304

View file

@ -49,6 +49,10 @@
<input id="wardrobe" placeholder="What they wear in this chapter">
<div class="row" style="margin:0"><button type="button" class="btn small ghost" id="save">Save the description</button><span class="tiny" id="saved"></span></div>
</div>
<div class="look" style="margin:0 0 14px"><h4>Or use your own picture of them</h4>
<span class="tiny">A picture you made or a photograph you hold the rights to. A side-by-side (two looks in one picture) is split into its halves and both are used. The reference sheets are drawn from it at once (about $0.27).</span>
<div class="row" style="margin:8px 0 0"><input type="file" id="own" accept="image/*" style="width:auto;font-size:14px"><span class="tiny" id="ownstate"></span></div>
</div>
<div class="looks" id="looks"></div>
<div class="row">
<label class="tiny">Candidates <select id="n"><option>2</option><option selected>3</option><option>4</option></select></label>
@ -136,10 +140,10 @@
: (lc.error ? lc.error : (items.length ? items.length + " candidates, drawn " + new Date(lc.made_at).toLocaleString() : ""));
$("grid").innerHTML = items.map(function (it, i) {
var chosen = lc.chosen === i;
return '<div class="cand' + (chosen ? ' chosen' : '') + '"><b>Candidate ' + (i + 1) + '</b>' + (chosen ? ' <span class="tiny" style="color:#5fd38d">— cast</span>' : '')
return '<div class="cand' + (chosen ? ' chosen' : '') + '"><b>Candidate ' + (i + 1) + '</b>' + (it.supplied ? ' <span class="tiny">— your own picture' + (it.note ? ' (' + esc(it.note) + ')' : '') + '</span>' : '') + (chosen ? ' <span class="tiny" style="color:#5fd38d">— cast</span>' : '')
+ '<div class="pics">' + (it.urls || []).map(function (u, k) {
return '<div class="pic">' + (u ? '<img src="' + esc(u) + '" data-zoom="1" alt="">' : '<div class="tiny">not drawn</div>')
+ '<div class="cap">' + esc((looks[k] || {}).name || ("Look " + (k + 1))) + '</div></div>'; }).join("")
+ '<div class="cap">' + esc(it.supplied ? (u ? "as supplied" : "") : ((looks[k] || {}).name || ("Look " + (k + 1)))) + '</div></div>'; }).join("")
+ '</div><div class="foot"><button type="button" class="btn small" data-pick="' + i + '"' + (lc.state === "choosing" ? ' disabled' : '') + '>'
+ (chosen ? 'Cast again from this one' : 'Cast this one') + '</button>'
+ '<span class="tiny">Draws the head, front, side and back sheets from this face (about $' + (4 * PER_PICTURE).toFixed(2) + ').</span></div>'
@ -159,6 +163,22 @@
return true;
}
$("save").addEventListener("click", saveWho);
$("own").addEventListener("change", async function () {
var file = $("own").files[0];
if (!file) return;
if (!/^image\//.test(file.type)) { msg("Please choose an image file."); $("own").value = ""; return; }
$("ownstate").textContent = "preparing…";
var img;
try { img = await resizeImage(file, 2400, 0.92); }
catch (err) { $("ownstate").textContent = ""; msg(err.message || "Could not read that picture."); $("own").value = ""; return; }
if (!(await saveWho())) return;
$("ownstate").textContent = "uploading…";
var r = await api("cast_from_picture", { draft_id: DID, character_id: CID, data_b64: img.b64, note: file.name });
$("own").value = ""; $("ownstate").textContent = "";
if (!r.ok) { msg(r.error || "That upload did not work."); return; }
msg("Your picture is candidate " + (r.index + 1) + (r.pieces > 1 ? " (split in " + r.pieces + ")" : "") + "; drawing the reference sheets from it (about $" + r.usd + ").", "ok");
load();
});
$("draw").addEventListener("click", async function () {
var looks = readLooks();
if (!looks.length) { msg("Say what they wear in at least one look."); return; }