diff --git a/trailer.html b/trailer.html index 6fd4e2c..e8e35f2 100644 --- a/trailer.html +++ b/trailer.html @@ -109,6 +109,16 @@ .shot .num{width:40px;flex:none;color:var(--muted);font-variant-numeric:tabular-nums} .shot .body{flex:1;min-width:0} .shot h3{margin:0 0 3px;font-size:15px} + .shot.floor{opacity:.5} + .shot.floor:hover{opacity:.85} + .floorbox{float:right;font-size:12px;color:var(--muted);cursor:pointer;user-select:none} + .floornote{font-size:12px;color:#b4531f;margin:2px 0 4px} + details.fold{margin:10px 0;border:1px solid var(--line,#2a2f3a);border-radius:10px;padding:0 12px} + details.fold>summary{cursor:pointer;padding:10px 0;font-weight:600;list-style:none} + details.fold>summary::-webkit-details-marker{display:none} + details.fold>summary::before{content:"\25B6";display:inline-block;margin-right:8px;font-size:11px;transition:transform .15s} + details.fold[open]>summary::before{transform:rotate(90deg)} + details.fold>summary .tiny{font-weight:400;margin-left:6px} .shot .where{color:var(--muted);font-size:12px;margin-bottom:8px} .shot .act{font-size:14px;margin:0 0 8px} .shot .cam,.shot .cont{color:var(--muted);font-size:12.5px;margin:0 0 5px} @@ -1069,9 +1079,31 @@ DRAFTNOW = draft; return head + partsHtml(draft) + contestHtml() + guideHtml(meta) + probs + '
' + barHtml(meta) + '
' + '
' + reelHtml() + '
' - + spineHtml() + cutsHtml(meta) + reviewsHtml(meta) + wholeHtml() + filmCheckHtml() + speakerNoticeHtml(draft) + viewsHtml(draft) + castHtml + propsHtml() + body; + + fold("spine", "The story, as the writer worked it out", "", spineHtml()) + + cutsHtml(meta) + reviewsHtml(meta) + wholeHtml() + filmCheckHtml() + speakerNoticeHtml(draft) + + fold("views", "Master pictures for each set-up", "", viewsHtml(draft)) + + fold("cast", "The cast", cast.length + " characters - faces, looks, voices", castHtml) + + fold("props", "Things that must look the same in every shot", ((PKG.props || []).length || "no") + " tracked", propsHtml()) + + body; } + // FOLDS. The cast, the props, the story notes and the master pictures are + // reference: open them when needed, otherwise the shots are one scroll + // away. Closed by default; each one remembers being opened. + var FOLD = {}; + try { FOLD = JSON.parse(localStorage.getItem("ptl_folds") || "{}"); } catch (e) { FOLD = {}; } + function fold(key, title, note, html) { + if (!html) return ""; + return '
' + esc(title) + + (note ? '' + esc(String(note)) + '' : '') + '' + html + '
'; + } + document.addEventListener("toggle", function (e) { + var d = e.target; + if (!d || !d.getAttribute || !d.getAttribute("data-fold")) return; + FOLD[d.getAttribute("data-fold")] = d.open; + try { localStorage.setItem("ptl_folds", JSON.stringify(FOLD)); } catch (er) {} + }, true); + // 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. @@ -1472,18 +1504,20 @@ function scenesHtml(shots, voice, draft) { var out = insertHtml("start"); sceneGroups(shots).forEach(function (g, gi) { - var filmed = g.shots.filter(function (x) { return x.clip_url; }).length, done = g.shots.every(shotDone); + // The cutting room floor counts for nothing: not filmed, not seconds, not the link. + var live = g.shots.filter(function (x) { return !x.floor; }), floored = g.shots.length - live.length; + var filmed = live.filter(function (x) { return x.clip_url; }).length, done = live.every(shotDone); var busy = g.shots.some(function (x) { return x.writing || x.drawing || stillFilming(x); }); var id = draft.id + "|" + gi + "|" + g.key, open = !!OPEN[id]; - var secs = g.shots.reduce(function (a, x) { return a + Number(x.edit_seconds || 0); }, 0); + var secs = live.reduce(function (a, x) { return a + Number(x.edit_seconds || 0); }, 0); out += ''; + + 'shots ' + esc(g.shots[0].id) + '–' + esc(g.shots[g.shots.length - 1].id) + ' · ' + live.length + ' shot' + (live.length === 1 ? '' : 's') + (floored ? ' (+' + floored + ' on the floor)' : '') + ' · ' + secs.toFixed(0) + ' s · ' + + (busy ? 'working…' : done ? 'all filmed' : filmed + ' of ' + live.length + ' filmed') + ''; if (open) { - var ids = g.shots.filter(function (x) { return x.clip_url; }).map(function (x) { return x.id; }); + var ids = live.filter(function (x) { return x.clip_url; }).map(function (x) { return x.id; }); out += '
' + (ids.length ? '' : 'Nothing filmed in this scene yet.') + (SHARES["scene:" + ids.join(",")] ? ' ' + esc(SHARES["scene:" + ids.join(",")]) + '' : '') + '
'; g.shots.forEach(function (x) { out += shotHtml(x, voice) + insertHtml(x.id); }); @@ -1497,7 +1531,8 @@ // ball" starts with the ball, the dog and Dorothy exactly where the last // clip left them. function prevShot(s) { - var all = (PKG.shots || []).slice().sort(function (a, b) { return String(a.id).localeCompare(String(b.id)); }); + var all = (PKG.shots || []).filter(function (x) { return x === s || x.id === s.id || !x.floor; }) + .sort(function (a, b) { return String(a.id).localeCompare(String(b.id)); }); var i = all.findIndex(function (x) { return x.id === s.id; }); return i > 0 ? all[i - 1] : null; } @@ -1508,7 +1543,7 @@ var all = (PKG.shots || []).slice().sort(function (a, b) { return String(a.id).localeCompare(String(b.id)); }); var i = all.findIndex(function (x) { return x.id === s.id; }); var opts = all.slice(Math.max(0, i - 12), i).filter(function (x) { - return x.id !== p.id && x.clip_url && (x.scene || "") === (s.scene || ""); + return x.id !== p.id && x.clip_url && !x.floor && (x.scene || "") === (s.scene || ""); }).reverse(); if (!opts.length) return ""; return ' or shot Cutting room floor' + + (s.floor ? '
On the cutting room floor - left out of the film. Untick to put it back.
' : '') + '
' + esc(s.setting || "") + ' · ' + ' s ' + '' @@ -1738,6 +1776,14 @@ if (r) { showMsg("msg", "Shot " + ssid + " is now " + Number(r.seconds).toFixed(1) + " s." + (PKG.shots.some(function (x) { return x.id === ssid && x.clip_url; }) ? " The clip was filmed at the old length; make the shot again to refilm." : ""), "ok"); await refresh(); } return; } + if ((el = hit("data-floor"))) { + var flid = el.getAttribute("data-floor"), flon = !!el.checked; + el.disabled = true; + r = await act("set_floor", { draft_id: CUR, shot_id: flid, floor: flon }); + if (r) { showMsg("msg", flon ? "Shot " + flid + " is on the cutting room floor - left out of the film. Untick to put it back." : "Shot " + flid + " is back in the film.", "ok"); await refresh(); } + else { el.checked = !flon; el.disabled = false; } + return; + } if ((el = hit("data-useframe"))) { var uf = el.getAttribute("data-useframe").split("|"); el.disabled = true;