trailer.html: show the story the writer worked out, above the script
The writer now reads the book and commits to what the story IS before writing a single shot - premise, protagonist, the emotional engine stated as a moment, what a viewer must understand, which moments have to be SHOWN rather than narrated, and how it ends so it knows what it is withholding. That document is worth more to an author than the script is. It is where a misreading of the book is visible and cheap to fix; by the time it is twenty-six shots and a storyboard it is neither. So it sits above the shots, collapsed, and the two lists that decide whether the trailer works - what a viewer must understand, and what must be dramatised - are open by default. "What a viewer must understand" is also literally the checklist the comprehension test measures against, so the two panels now read as a pair: here is what it must convey, and here is what three readers actually took away.
This commit is contained in:
parent
50157f0d5b
commit
c900dce0aa
1 changed files with 51 additions and 5 deletions
56
trailer.html
56
trailer.html
|
|
@ -60,6 +60,16 @@
|
|||
border-radius:999px;padding:0 6px}
|
||||
.vobadge{color:var(--muted);font-size:11px;border:1px solid var(--line);
|
||||
border-radius:999px;padding:0 6px}
|
||||
.spine{border:1px solid var(--line);border-radius:10px;padding:14px 16px;margin:0 0 14px}
|
||||
.spine h4{margin:0 0 8px;font-size:15px}
|
||||
.spine .eng{font-size:14px;border-left:2px solid var(--accent);padding-left:11px;margin:0 0 12px}
|
||||
.spine .kv{font-size:13px;margin:3px 0;color:var(--muted)}
|
||||
.spine .kv b{color:var(--ink);font-weight:600}
|
||||
.spine h5{margin:12px 0 4px;font-size:12px;letter-spacing:.06em;text-transform:uppercase;
|
||||
color:var(--muted)}
|
||||
.spine ul{margin:0;padding-left:18px;font-size:13px}
|
||||
.spine details{margin-top:10px}
|
||||
.spine summary{cursor:pointer;color:var(--muted);font-size:13px}
|
||||
.gaps{border:1px solid var(--accent);border-radius:10px;padding:14px 16px;margin:0 0 14px}
|
||||
.gaps h4{margin:0 0 4px;font-size:15px;color:var(--accent)}
|
||||
.gaps .verdict{font-size:14px;margin:0 0 10px}
|
||||
|
|
@ -214,7 +224,8 @@
|
|||
return;
|
||||
}
|
||||
if (meta.state === "writing") {
|
||||
pane.innerHTML = '<p class="empty">Working. Reading the whole book takes a few minutes.</p>';
|
||||
pane.innerHTML = '<p class="empty">Working. It reads the whole book, works out what the '
|
||||
+ 'story is, and then writes the trailer from that. Several minutes.</p>';
|
||||
return;
|
||||
}
|
||||
var r = await api("get_draft", { draft_id: id });
|
||||
|
|
@ -224,6 +235,43 @@
|
|||
pane.innerHTML = paneHtml(meta, r.draft);
|
||||
}
|
||||
|
||||
// The story the writer committed to before writing a shot. This is where a
|
||||
// misreading of the book is visible and cheap to fix; by the time it is
|
||||
// twenty-six shots and a storyboard, it is neither.
|
||||
function spineHtml() {
|
||||
var sp = PKG.spine;
|
||||
if (!sp || typeof sp !== "object") return "";
|
||||
var p = sp.protagonist || {};
|
||||
function ul(items) {
|
||||
return (!items || !items.length) ? ""
|
||||
: '<ul>' + items.map(function (x) {
|
||||
return '<li>' + esc(typeof x === "string" ? x : JSON.stringify(x)) + '</li>';
|
||||
}).join("") + '</ul>';
|
||||
}
|
||||
var beats = (sp.beats || []).map(function (b) {
|
||||
return '<li>' + esc(b.what || "")
|
||||
+ (b.is_ending ? ' <b>(the ending)</b>' : '')
|
||||
+ (b.why_it_matters ? ' <span class="kv">' + esc(b.why_it_matters) + '</span>' : '')
|
||||
+ '</li>'; }).join("");
|
||||
|
||||
return '<div class="spine"><h4>The story, as the writer worked it out from the book</h4>'
|
||||
+ (sp.the_engine ? '<p class="eng">' + esc(sp.the_engine) + '</p>' : '')
|
||||
+ (p.who ? '<div class="kv"><b>who</b> ' + esc(p.who) + '</div>' : '')
|
||||
+ (p.wants ? '<div class="kv"><b>wants</b> ' + esc(p.wants) + '</div>' : '')
|
||||
+ (p.obstacle ? '<div class="kv"><b>in the way</b> ' + esc(p.obstacle) + '</div>' : '')
|
||||
+ (p.cost ? '<div class="kv"><b>cost</b> ' + esc(p.cost) + '</div>' : '')
|
||||
+ (sp.what_a_viewer_must_understand && sp.what_a_viewer_must_understand.length
|
||||
? '<h5>A viewer must come away knowing</h5>' + ul(sp.what_a_viewer_must_understand) : '')
|
||||
+ (sp.moments_to_dramatise && sp.moments_to_dramatise.length
|
||||
? '<h5>Must be shown, not narrated</h5>' + ul(sp.moments_to_dramatise) : '')
|
||||
+ (sp.premise ? '<details><summary>the premise in full</summary><p>'
|
||||
+ esc(sp.premise) + '</p></details>' : '')
|
||||
+ (beats ? '<details><summary>the beats of the book</summary><ol>' + beats + '</ol></details>' : '')
|
||||
+ (sp.withhold ? '<details><summary>what the trailer is withholding</summary><p>'
|
||||
+ esc(sp.withhold) + '</p></details>' : '')
|
||||
+ '</div>';
|
||||
}
|
||||
|
||||
function barHtml(meta) {
|
||||
var shots = (PKG.shots || []), cast = (PKG.characters || []);
|
||||
var undrawn = shots.filter(function (s) { return !s.opening_url; }).length;
|
||||
|
|
@ -273,7 +321,6 @@
|
|||
return out.join("");
|
||||
}
|
||||
|
||||
// What readers understood, and what the writer says it failed to say.
|
||||
function reviewsHtml(meta) {
|
||||
var mine = REVIEWS.filter(function (r) {
|
||||
return r.subject === meta.writer && Number(r.iteration) === Number(meta.iteration); });
|
||||
|
|
@ -359,7 +406,7 @@
|
|||
shots.forEach(function (s) { body += shotHtml(s, voice) + insertHtml(s.id); });
|
||||
|
||||
return head + probs + '<div class="bar">' + barHtml(meta) + '</div>'
|
||||
+ reviewsHtml(meta) + castHtml + body;
|
||||
+ spineHtml() + reviewsHtml(meta) + castHtml + body;
|
||||
}
|
||||
|
||||
function insertHtml(after) {
|
||||
|
|
@ -456,11 +503,10 @@
|
|||
+ '</div></div>';
|
||||
}
|
||||
|
||||
async function act(name, payload, msg) {
|
||||
async function act(name, payload) {
|
||||
var r = await api(name, payload);
|
||||
if (!r.ok) { showMsg("msg", r.error || "That did not work."); return null; }
|
||||
hideMsg("msg");
|
||||
if (msg) showMsg("msg", msg(r), "ok");
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue