EtonMu commited on
Commit
c20e771
·
verified ·
1 Parent(s): b6382fd

Ship gallery assets as LFS tar (fix broken images)

Browse files
Files changed (2) hide show
  1. static/index.html +135 -30
  2. static_assets.tar +2 -2
static/index.html CHANGED
@@ -277,28 +277,64 @@
277
  }
278
  .look-card.film .ov .can-btn2:hover { transform: scale(1.15); }
279
 
280
- /* shutter effect on the process button */
281
- #processBtn { position: relative; overflow: hidden; }
282
- #processBtn.snap { animation: pressScale .55s cubic-bezier(.2,.7,.2,1); }
283
- #processBtn.snap::after {
284
- content: ""; position: absolute; inset: -2px;
285
- background: #0c0c0f;
286
- transform: translateX(-103%);
287
- animation: curtain .55s cubic-bezier(.65,0,.35,1);
288
- }
289
- @keyframes curtain {
290
- 0% { transform: translateX(-103%); }
291
- 42% { transform: translateX(0); }
292
- 58% { transform: translateX(0); }
293
- 100% { transform: translateX(103%); }
294
- }
295
- @keyframes pressScale { 0% { transform: scale(1); } 35% { transform: scale(.955); } 100% { transform: scale(1); } }
296
- #flashFx {
297
- position: fixed; inset: 0; background: #fff;
298
- opacity: 0; pointer-events: none; z-index: 2000;
299
- }
300
- #flashFx.on { animation: flashfx .4s ease-out; }
301
- @keyframes flashfx { 0% { opacity: 0; } 18% { opacity: .45; } 100% { opacity: 0; } }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
302
 
303
  /* look anatomy: recipe + 3D LUT in one module */
304
  .anatomy {
@@ -438,7 +474,7 @@
438
  .lab-box .ref-group-label { color: var(--accent); margin: 0 0 8px; display: flex; justify-content: space-between; align-items: baseline; }
439
  .lab-box .ref-group-label .sub { font-size: 10px; letter-spacing: .04em; text-transform: none; color: var(--text-dim); }
440
  .ref-list { display: flex; flex-direction: column; gap: 6px; }
441
- .ref-list.scroll { max-height: 252px; overflow-y: auto; padding-right: 4px; }
442
  .ref-list.tall { max-height: 560px; overflow-y: auto; padding-right: 4px; }
443
  .pick-row {
444
  display: flex; align-items: center; gap: 10px;
@@ -881,6 +917,15 @@
881
  </div>
882
  <button class="try-btn" id="runPairBtn" style="margin-top:14px;width:100%">
883
  Run this pair in the app →</button>
 
 
 
 
 
 
 
 
 
884
  </div>
885
  </div>
886
 
@@ -1043,18 +1088,25 @@
1043
  });
1044
 
1045
  // ------------------------------------------------ process
1046
- const flashFx = document.createElement('div');
1047
- flashFx.id = 'flashFx';
1048
- document.body.appendChild(flashFx);
 
 
 
 
1049
 
1050
  function shutterSnap() {
1051
  const btn = $('processBtn');
1052
  btn.classList.remove('snap');
1053
- flashFx.classList.remove('on');
1054
- void btn.offsetWidth;
1055
  btn.classList.add('snap');
1056
- flashFx.classList.add('on');
1057
- setTimeout(() => { btn.classList.remove('snap'); flashFx.classList.remove('on'); }, 650);
 
 
 
1058
  }
1059
 
1060
  $('processBtn').addEventListener('click', () => {
@@ -1211,12 +1263,55 @@
1211
  catch (e) { /* canvas unavailable — skip silently */ }
1212
  try { aR.appendChild(makeVizCard(data.cube_lut)); }
1213
  catch (e) { /* WebGL unavailable — skip viz silently */ }
 
 
1214
  if (aL.children.length || aR.children.length) body.appendChild(anatomy);
1215
 
1216
  $('results').style.display = 'block';
1217
  $('results').scrollIntoView({ behavior: 'smooth', block: 'start' });
1218
  }
1219
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1220
  function b64ToBlob(b64, type) {
1221
  const bin = atob(b64);
1222
  const arr = new Uint8Array(bin.length);
@@ -1819,6 +1914,16 @@
1819
  $('pairInput').src = input.src;
1820
  $('pairInfo').innerHTML = '<b>' + refName() + '</b> &nbsp;→&nbsp; <b>' + input.name + '</b>';
1821
 
 
 
 
 
 
 
 
 
 
 
1822
  // every pair has a pre-render; onerror falls back to the live hint
1823
  $('instantWrap').style.display = 'block';
1824
  $('liveHint').style.display = 'none';
 
277
  }
278
  .look-card.film .ov .can-btn2:hover { transform: scale(1.15); }
279
 
280
+ /* full-viewport leaf shutter: blades close, flash fires, blades open */
281
+ #processBtn.snap { animation: pressScale .6s cubic-bezier(.2,.7,.2,1); }
282
+ @keyframes pressScale { 0% { transform: scale(1); } 30% { transform: scale(.95); } 100% { transform: scale(1); } }
283
+ #shutterFx { position: fixed; inset: 0; pointer-events: none; z-index: 2000; }
284
+ #shutterFx .sc {
285
+ position: absolute; left: 0; right: 0; height: 51%;
286
+ background: #030304; transform: scaleY(0);
287
+ }
288
+ #shutterFx .sc.t { top: 0; transform-origin: top;
289
+ box-shadow: 0 3px 30px rgba(0,0,0,.9); }
290
+ #shutterFx .sc.b { bottom: 0; transform-origin: bottom;
291
+ box-shadow: 0 -3px 30px rgba(0,0,0,.9); }
292
+ #shutterFx .sflash { position: absolute; inset: 0; background: #fff; opacity: 0; }
293
+ #shutterFx .sring {
294
+ position: absolute; top: 50%; left: 50%;
295
+ width: 70px; height: 70px; margin: -35px 0 0 -35px;
296
+ border: 2.5px solid var(--accent); border-radius: 50%;
297
+ opacity: 0; transform: scale(.4);
298
+ }
299
+ #shutterFx.go .sc.t { animation: scClose .62s cubic-bezier(.75,0,.25,1); }
300
+ #shutterFx.go .sc.b { animation: scClose .62s cubic-bezier(.75,0,.25,1); }
301
+ #shutterFx.go .sflash { animation: sflash .62s ease-out; }
302
+ #shutterFx.go .sring { animation: sring .62s cubic-bezier(.2,.8,.3,1); }
303
+ @keyframes scClose {
304
+ 0% { transform: scaleY(0); }
305
+ 30% { transform: scaleY(1); }
306
+ 58% { transform: scaleY(1); }
307
+ 100% { transform: scaleY(0); }
308
+ }
309
+ @keyframes sflash {
310
+ 0%, 26% { opacity: 0; }
311
+ 40% { opacity: .85; }
312
+ 62% { opacity: .12; }
313
+ 100% { opacity: 0; }
314
+ }
315
+ @keyframes sring {
316
+ 0%, 30% { opacity: 0; transform: scale(.4); }
317
+ 45% { opacity: 1; }
318
+ 100% { opacity: 0; transform: scale(1.6); }
319
+ }
320
+
321
+ /* extracted parameters panel (anatomy, under the 3D LUT) */
322
+ .param-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin-top: 14px; }
323
+ .pchip {
324
+ background: var(--bg-3); border: 1px solid var(--line); border-radius: 9px;
325
+ padding: 8px 11px;
326
+ }
327
+ .pchip .k { font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--text-dim); }
328
+ .pchip .v { font-family: ui-monospace, Menlo, monospace; font-size: 12px; color: var(--text); margin-top: 3px; display: flex; align-items: center; gap: 6px; }
329
+ .pchip .sw { width: 13px; height: 13px; border-radius: 4px; border: 1px solid rgba(255,255,255,.15); display: inline-block; }
330
+
331
+ /* per-reference look downloads (playground result column) */
332
+ .look-dl { margin-top: 18px; border-top: 1px dashed var(--line); padding-top: 14px; }
333
+ .look-dl .t { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--text-dim); margin-bottom: 10px; }
334
+ .look-dl .t b { color: var(--accent); text-transform: none; letter-spacing: 0; }
335
+ .look-dl-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
336
+ .dl-btn.mini { padding: 8px 11px; font-size: 12px; gap: 7px; justify-content: flex-start; }
337
+ .dl-btn.mini .kind { font-size: 10px; }
338
 
339
  /* look anatomy: recipe + 3D LUT in one module */
340
  .anatomy {
 
474
  .lab-box .ref-group-label { color: var(--accent); margin: 0 0 8px; display: flex; justify-content: space-between; align-items: baseline; }
475
  .lab-box .ref-group-label .sub { font-size: 10px; letter-spacing: .04em; text-transform: none; color: var(--text-dim); }
476
  .ref-list { display: flex; flex-direction: column; gap: 6px; }
477
+ .ref-list.scroll { max-height: 580px; overflow-y: auto; padding-right: 4px; }
478
  .ref-list.tall { max-height: 560px; overflow-y: auto; padding-right: 4px; }
479
  .pick-row {
480
  display: flex; align-items: center; gap: 10px;
 
917
  </div>
918
  <button class="try-btn" id="runPairBtn" style="margin-top:14px;width:100%">
919
  Run this pair in the app →</button>
920
+ <div class="look-dl">
921
+ <div class="t">Download the <b id="lookDlName"></b> look</div>
922
+ <div class="look-dl-grid">
923
+ <a class="dl-btn mini" id="lkCube"><span>LUT</span><span class="kind">.CUBE</span></a>
924
+ <a class="dl-btn mini" id="lkXmp"><span>Adobe</span><span class="kind">.XMP</span></a>
925
+ <a class="dl-btn mini" id="lkCo"><span>Capture One</span><span class="kind">.COSTYLE</span></a>
926
+ <a class="dl-btn mini" id="lkJson"><span>Parameters</span><span class="kind">.JSON</span></a>
927
+ </div>
928
+ </div>
929
  </div>
930
  </div>
931
 
 
1088
  });
1089
 
1090
  // ------------------------------------------------ process
1091
+ const shutterFx = document.createElement('div');
1092
+ shutterFx.id = 'shutterFx';
1093
+ shutterFx.setAttribute('aria-hidden', 'true');
1094
+ shutterFx.innerHTML =
1095
+ '<div class="sc t"></div><div class="sc b"></div>' +
1096
+ '<div class="sflash"></div><div class="sring"></div>';
1097
+ document.body.appendChild(shutterFx);
1098
 
1099
  function shutterSnap() {
1100
  const btn = $('processBtn');
1101
  btn.classList.remove('snap');
1102
+ shutterFx.classList.remove('go');
1103
+ void shutterFx.offsetWidth;
1104
  btn.classList.add('snap');
1105
+ shutterFx.classList.add('go');
1106
+ setTimeout(() => {
1107
+ btn.classList.remove('snap');
1108
+ shutterFx.classList.remove('go');
1109
+ }, 700);
1110
  }
1111
 
1112
  $('processBtn').addEventListener('click', () => {
 
1263
  catch (e) { /* canvas unavailable — skip silently */ }
1264
  try { aR.appendChild(makeVizCard(data.cube_lut)); }
1265
  catch (e) { /* WebGL unavailable — skip viz silently */ }
1266
+ try { aR.appendChild(makeParamsPanel(data.params)); }
1267
+ catch (e) { /* skip silently */ }
1268
  if (aL.children.length || aR.children.length) body.appendChild(anatomy);
1269
 
1270
  $('results').style.display = 'block';
1271
  $('results').scrollIntoView({ behavior: 'smooth', block: 'start' });
1272
  }
1273
 
1274
+ function makeParamsPanel(p) {
1275
+ const el = document.createElement('div');
1276
+ el.innerHTML =
1277
+ '<div class="viz-head" style="margin-top:16px"><span class="t">Extracted parameters' +
1278
+ '<span class="help">?<span class="tip">The measured film characteristics driving ' +
1279
+ 'this render — grain statistics, halation geometry, and the tonal fingerprint of ' +
1280
+ 'the reference. The full set is in the Film parameters JSON.</span></span></span></div>' +
1281
+ '<div class="param-grid"></div>';
1282
+ const grid = el.querySelector('.param-grid');
1283
+
1284
+ function hex(c) {
1285
+ return '#' + c.map(v => Math.round(Math.min(Math.max(v, 0), 1) * 255)
1286
+ .toString(16).padStart(2, '0')).join('').toUpperCase();
1287
+ }
1288
+ function chip(k, v, swatch) {
1289
+ const d = document.createElement('div');
1290
+ d.className = 'pchip';
1291
+ d.innerHTML = '<div class="k"></div><div class="v"></div>';
1292
+ d.querySelector('.k').textContent = k;
1293
+ const vv = d.querySelector('.v');
1294
+ if (swatch) {
1295
+ const s = document.createElement('span');
1296
+ s.className = 'sw';
1297
+ s.style.background = swatch;
1298
+ vv.appendChild(s);
1299
+ }
1300
+ vv.appendChild(document.createTextNode(v));
1301
+ grid.appendChild(d);
1302
+ }
1303
+
1304
+ chip('Grain', 'σ ' + p.grain_sigma + ' · size ' + p.grain_size);
1305
+ chip('Halation', 'thr ' + p.h_threshold + ' · r ' + p.h_radius + ' · i ' + p.h_intensity);
1306
+ chip('Black point', String(p.ref_black_point));
1307
+ chip('White point', String(p.ref_white_point));
1308
+ chip('Shadow tint', hex(p.ref_shadow_color), hex(p.ref_shadow_color));
1309
+ chip('Highlight tint', hex(p.ref_highlight_color), hex(p.ref_highlight_color));
1310
+ chip('Contrast range', String(p.ref_contrast_range));
1311
+ chip('LUT residual', '×' + p.residual_scale);
1312
+ return el;
1313
+ }
1314
+
1315
  function b64ToBlob(b64, type) {
1316
  const bin = atob(b64);
1317
  const arr = new Uint8Array(bin.length);
 
1914
  $('pairInput').src = input.src;
1915
  $('pairInfo').innerHTML = '<b>' + refName() + '</b> &nbsp;→&nbsp; <b>' + input.name + '</b>';
1916
 
1917
+ // per-reference look downloads (pre-generated on the server)
1918
+ const slug = refName().replace(/[^A-Za-z0-9]+/g, '-').replace(/^-|-$/g, '');
1919
+ $('lookDlName').textContent = refName();
1920
+ [['lkCube', 'cube'], ['lkXmp', 'xmp'], ['lkCo', 'costyle'], ['lkJson', 'json']]
1921
+ .forEach(([id, ext]) => {
1922
+ const a = $(id);
1923
+ a.href = 'static/looks/' + refId() + '.' + ext;
1924
+ a.download = 'DeepAnalog-' + slug + '.' + ext;
1925
+ });
1926
+
1927
  // every pair has a pre-render; onerror falls back to the live hint
1928
  $('instantWrap').style.display = 'block';
1929
  $('liveHint').style.display = 'none';
static_assets.tar CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:7d1f5ef93d84a0a62bc47686d8bd4971bdd2120a3bc497b2f1f6359f56a45ba7
3
- size 70051840
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d7dc9e23f3b49c962e15d0c47701d6dd0e93560c32ca19149aa3f066d728b201
3
+ size 83742720