Things that must look the same: tracked objects with reference pictures; the picture check folds small things away

This commit is contained in:
gator 2026-09-19 19:06:34 +00:00
parent 5a54104005
commit 25e1fd462b

View file

@ -265,6 +265,8 @@
&& (Date.now() - (Date.parse(PKG.pics_started || "") || 0)) < 15 * 60 * 1000) return true; && (Date.now() - (Date.parse(PKG.pics_started || "") || 0)) < 15 * 60 * 1000) return true;
if (String(PKG.look_state || "") if (String(PKG.look_state || "")
&& (Date.now() - (Date.parse(PKG.look_started || "") || 0)) < 15 * 60 * 1000) return true; && (Date.now() - (Date.parse(PKG.look_started || "") || 0)) < 15 * 60 * 1000) return true;
if (String(PKG.props_state || "")
&& (Date.now() - (Date.parse(PKG.props_started || "") || 0)) < 15 * 60 * 1000) return true;
return (PKG.shots || []).some(function (s) { return (PKG.shots || []).some(function (s) {
return s.writing || s.drawing || s.fixing || s.varying || stillFilming(s); }); return s.writing || s.drawing || s.fixing || s.varying || stillFilming(s); });
} }
@ -862,7 +864,42 @@
DRAFTNOW = draft; DRAFTNOW = draft;
return head + guideHtml(meta) + probs + '<div class="bar">' + barHtml(meta) + '</div>' return head + guideHtml(meta) + probs + '<div class="bar">' + barHtml(meta) + '</div>'
+ '<div id="reelhost">' + reelHtml() + '</div>' + '<div id="reelhost">' + reelHtml() + '</div>'
+ spineHtml() + cutsHtml(meta) + reviewsHtml(meta) + wholeHtml() + castHtml + body; + spineHtml() + cutsHtml(meta) + reviewsHtml(meta) + wholeHtml() + castHtml + propsHtml() + body;
}
// THINGS THAT MUST STAY THE SAME. A face is held steady by a reference
// picture; so is an urn, and so is a car. Without one, the object the whole
// story is about was three different objects in three shots.
function propsHtml() {
var props = PKG.props, busy = String(PKG.props_state || "");
var head = '<div class="props"><h3 style="margin:18px 0 4px">Things that must look the same in every shot</h3>';
if (busy) head += '<p class="busy">' + esc(busy) + '\u2026 about a minute.</p>';
if (PKG.props_note) head += '<p class="cont" style="color:#b4531f">' + esc(PKG.props_note) + '</p>';
if (!props || !props.length)
return head + '<p class="cont">An object or a car that appears in more than one shot needs a reference '
+ 'picture, the way each character has one - otherwise it is drawn differently every time. '
+ (busy ? '' : '<button type="button" class="btn" data-findprops="1">Find them in this script &middot; about $0.30</button>')
+ '</p></div>';
return head + '<div class="cast">' + props.map(function (p) {
var pics = [["url", p.kind === "vehicle" ? "outside" : ""], ["interior_url", "inside"]].map(function (f) {
return p[f[0]] ? '<img data-zoom="' + esc(p.name + (f[1] ? " \u2014 " + f[1] : "")) + '" src="' + esc(p[f[0]]) + '" alt="">' : ''; }).join("");
var where = (p.shots || []).map(function (x) { return x.id; }).join(", ");
var drawn = (p.shots || []).filter(function (x) {
return (PKG.shots || []).some(function (q) { return String(q.id) === String(x.id) && q.opening_url; }); }).length;
return '<div class="ch"><div class="sheets">' + (pics || '<i class="lw">not drawn yet</i>') + '</div>'
+ '<b>' + esc(p.name || p.id) + '</b><span class="vo">in shots ' + esc(where) + '</span>'
+ '<textarea rows="5" style="width:100%;font-size:12px;margin-top:6px" data-propdesc="' + esc(p.id) + '">'
+ esc(p.description || "") + '</textarea>'
+ (busy ? '' : '<div class="tools" style="margin-top:6px">'
+ '<button type="button" class="btn" data-propsave="' + esc(p.id) + '">Draw it from this description &middot; $'
+ (p.kind === "vehicle" ? "0.14" : "0.07") + '</button>'
+ (drawn ? '<button type="button" class="btn" data-propshots="' + esc(p.id) + '">Redraw the ' + drawn
+ ' shot' + (drawn === 1 ? '' : 's') + ' that show it &middot; $' + (drawn * 0.14).toFixed(2) + '</button>' : '')
+ '<button type="button" class="btn" data-propdel="' + esc(p.id) + '">Stop tracking it</button></div>')
+ '</div>';
}).join("") + '</div>'
+ (busy ? '' : '<p class="cont"><button type="button" class="btn" data-findprops="1">Look through the script again &middot; about $0.10</button></p>')
+ '</div>';
} }
// Every look a character has, in the order the story reaches them: the // Every look a character has, in the order the story reaches them: the
@ -976,16 +1013,24 @@
var rows = dup.map(function (d) { var rows = dup.map(function (d) {
return { what: "The same person appears twice: " + d, serious: true }; }) return { what: "The same person appears twice: " + d, serious: true }; })
.concat(faults.map(function (f) { return { what: f.what, serious: f.severity === "serious", zoom: f.zoom_url || "" }; })); .concat(faults.map(function (f) { return { what: f.what, serious: f.severity === "serious", zoom: f.zoom_url || "" }; }));
return '<div class="fchk ' + (fc.verdict === "broken" ? 'bad' : '') + '">' var line = function (r, i) {
+ '<b>The checker looked at this picture and sees:</b>' + retried
+ rows.map(function (r, i) {
// The close-up the checker was looking at. Nobody should have to // The close-up the checker was looking at. Nobody should have to
// take "six fingers" on trust - and sometimes it is simply wrong. // take "six fingers" on trust - and sometimes it is simply wrong.
var zm = r.zoom ? '<img data-zoom="' + esc("what the checker zoomed in on") + '" src="' + esc(r.zoom) var zm = r.zoom ? '<img data-zoom="' + esc("what the checker zoomed in on") + '" src="' + esc(r.zoom)
+ '" alt="" style="height:54px;border-radius:5px;vertical-align:middle;margin-right:6px;border:1px solid var(--line)">' : ''; + '" alt="" style="height:54px;border-radius:5px;vertical-align:middle;margin-right:6px;border:1px solid var(--line)">' : '';
return '<span class="w' + (r.serious ? ' serious' : '') + '">' + zm + esc(r.what) return '<span class="w' + (r.serious ? ' serious' : '') + '">' + zm + esc(r.what)
+ ' <button type="button" class="btn go" data-fixfault="' + esc(s.id) + '|' + i + '">Fix this</button></span>'; + ' <button type="button" class="btn go" data-fixfault="' + esc(s.id) + '|' + i + '">Fix this</button></span>';
}).join("") };
// What matters is said out loud. What merely differs from the description
// is there for anyone who wants it, and is not an alarm.
var big = "", small = "", nsmall = 0;
rows.forEach(function (r, i) { if (r.serious) big += line(r, i); else { small += line(r, i); nsmall++; } });
return '<div class="fchk ' + (fc.verdict === "broken" ? 'bad' : '') + '">'
+ (big ? '<b>The checker looked at this picture and sees:</b>' + retried + big
: '<span style="color:#1f7a3a">\u2713 picture checked - nothing that needs fixing</span>' + retried)
+ (nsmall ? '<details style="margin-top:4px"><summary style="cursor:pointer;color:var(--muted)">'
+ nsmall + ' small thing' + (nsmall === 1 ? '' : 's') + ' it noticed \u2014 look only if the picture bothers you</summary>'
+ small + '</details>' : '')
+ '</div>'; + '</div>';
} }
@ -1467,6 +1512,32 @@
+ "automatically. This takes a few minutes." : (r.note || "Already checked."), "ok"); await refresh(); } + "automatically. This takes a few minutes." : (r.note || "Already checked."), "ok"); await refresh(); }
return; return;
} }
if ((el = hit("data-findprops"))) {
el.disabled = true;
r = await act("find_props", { draft_id: CUR });
if (r) { showMsg("msg", "Reading the script for objects that appear more than once, then drawing a reference for each. About two minutes.", "ok"); await refresh(); }
return;
}
if ((el = hit("data-propsave"))) {
var ppid = el.getAttribute("data-propsave");
var pta = document.querySelector('[data-propdesc="' + ppid + '"]');
el.disabled = true;
r = await act("set_prop", { draft_id: CUR, prop_id: ppid, description: pta ? pta.value : "", force: true });
if (r) { showMsg("msg", "Drawing the reference picture, about $" + r.usd + ". When it looks right, redraw the shots that show it.", "ok"); await refresh(); }
return;
}
if ((el = hit("data-propshots"))) {
el.disabled = true;
r = await act("redraw_prop_shots", { draft_id: CUR, prop_id: el.getAttribute("data-propshots") });
if (r) { showMsg("msg", "Redrawing those shots one after another, about $" + r.usd + ". A few minutes.", "ok"); await refresh(); }
return;
}
if ((el = hit("data-propdel"))) {
if (!confirm("Stop keeping this object the same from shot to shot?")) return;
el.disabled = true;
r = await act("remove_prop", { draft_id: CUR, prop_id: el.getAttribute("data-propdel") });
if (r) await refresh(); return;
}
if ((el = hit("data-fixfault"))) { if ((el = hit("data-fixfault"))) {
var ff = el.getAttribute("data-fixfault").split("|"); var ff = el.getAttribute("data-fixfault").split("|");
var fs = (PKG.shots || []).filter(function (x) { return String(x.id) === ff[0]; })[0] || {}; var fs = (PKG.shots || []).filter(function (x) { return String(x.id) === ff[0]; })[0] || {};