@idle-screens/schema 3.11.0 → 3.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -5553,17 +5553,17 @@ function adviseSequence(seq, viewport = { width: 1920, height: 1080 }) {
5553
5553
  });
5554
5554
  }
5555
5555
  for (let i = 0; i < seq.segments.length - 1; i++) {
5556
+ const tr = seq.segments[i].transition;
5556
5557
  const lumaA = backgroundLuma(resolveTimelineAt(seq.segments[i].scene, seq.segments[i].duration ?? 0));
5557
5558
  const lumaB = backgroundLuma(resolveTimelineAt(seq.segments[i + 1].scene, 0));
5558
5559
  const delta = Math.abs(lumaA - lumaB);
5559
- if (delta > 0.5) {
5560
+ if (delta > 0.5 && tr?.type !== "fade") {
5560
5561
  warnings.push({
5561
5562
  path: `segments[${i}]`,
5562
5563
  code: "boundary-luminance-jump",
5563
- message: `background luminance jumps ${delta.toFixed(2)} at boundary ${i}\u2192${i + 1} \u2014 may flash on cut`
5564
+ message: `background luminance jumps ${delta.toFixed(2)} at boundary ${i}\u2192${i + 1} \u2014 may flash on cut${tr === void 0 || tr.type === "cut" ? `; declare transition: { type: 'fade', dur } on segments[${i}] to ramp it` : ""}`
5564
5565
  });
5565
5566
  }
5566
- const tr = seq.segments[i].transition;
5567
5567
  if (tr?.type === "morph") {
5568
5568
  const sigA = structuralSignature(seq.segments[i].scene);
5569
5569
  const sigB = structuralSignature(seq.segments[i + 1].scene);
@@ -5829,6 +5829,37 @@ function distanceToOutline(pts, x, y) {
5829
5829
  }
5830
5830
  return Math.sqrt(best);
5831
5831
  }
5832
+ function rotatedBoxCoverage(cx, cy, hx, hy, rot, x0, y0, x1, y1) {
5833
+ const cr = Math.cos(rot), sr = Math.sin(rot);
5834
+ let poly = [[-hx, -hy], [hx, -hy], [hx, hy], [-hx, hy]].map(([x, y]) => [cx + x * cr - y * sr, cy + x * sr + y * cr]);
5835
+ const clip = (inside, cut) => {
5836
+ const out = [];
5837
+ for (let i = 0; i < poly.length; i++) {
5838
+ const a = poly[i], b = poly[(i + 1) % poly.length];
5839
+ if (inside(a)) {
5840
+ out.push(a);
5841
+ if (!inside(b)) out.push(cut(a, b));
5842
+ } else if (inside(b)) out.push(cut(a, b));
5843
+ }
5844
+ poly = out;
5845
+ };
5846
+ const atX = (x) => (a, b) => [x, a[1] + (x - a[0]) / (b[0] - a[0]) * (b[1] - a[1])];
5847
+ const atY = (y) => (a, b) => [a[0] + (y - a[1]) / (b[1] - a[1]) * (b[0] - a[0]), y];
5848
+ clip((p) => p[0] >= x0, atX(x0));
5849
+ if (!poly.length) return 0;
5850
+ clip((p) => p[0] <= x1, atX(x1));
5851
+ if (!poly.length) return 0;
5852
+ clip((p) => p[1] >= y0, atY(y0));
5853
+ if (!poly.length) return 0;
5854
+ clip((p) => p[1] <= y1, atY(y1));
5855
+ if (!poly.length) return 0;
5856
+ let area = 0;
5857
+ for (let i = 0; i < poly.length; i++) {
5858
+ const a = poly[i], b = poly[(i + 1) % poly.length];
5859
+ area += a[0] * b[1] - b[0] * a[1];
5860
+ }
5861
+ return Math.abs(area) / 2 / ((x1 - x0) * (y1 - y0));
5862
+ }
5832
5863
  function luminanceGrid(spec, opts = {}) {
5833
5864
  spec = resolveTimelineAt(spec, opts.t ?? 5e3);
5834
5865
  const scene = buildScene(spec, opts);
@@ -6051,6 +6082,7 @@ function luminanceGrid(spec, opts = {}) {
6051
6082
  let centerY = p.y;
6052
6083
  let halfX = sz / 2;
6053
6084
  let halfY = s.kind === "rect" ? (e.size2 ?? sz) * (e.size > 0 ? sz / e.size : 1) / 2 : sz / 2;
6085
+ let boxRot = 0, boxHx = 0, boxHy = 0;
6054
6086
  if (s.kind === "text") {
6055
6087
  const box = textBox(s, e, p);
6056
6088
  centerX = box.cx;
@@ -6073,8 +6105,23 @@ function luminanceGrid(spec, opts = {}) {
6073
6105
  const sr = Math.sin(rot);
6074
6106
  centerX = p.x + box.cx * cr - box.cy * sr;
6075
6107
  centerY = p.y + box.cx * sr + box.cy * cr;
6108
+ boxRot = rot;
6109
+ boxHx = box.halfX;
6110
+ boxHy = box.halfY;
6076
6111
  halfX = Math.abs(box.halfX * cr) + Math.abs(box.halfY * sr);
6077
6112
  halfY = Math.abs(box.halfX * sr) + Math.abs(box.halfY * cr);
6113
+ } else if (s.kind === "rect") {
6114
+ const rot = rotationAt(e, tPass);
6115
+ if (rot) {
6116
+ boxRot = rot;
6117
+ boxHx = halfX;
6118
+ boxHy = halfY;
6119
+ const cr = Math.abs(Math.cos(rot));
6120
+ const sr = Math.abs(Math.sin(rot));
6121
+ const hx = halfX * cr + halfY * sr;
6122
+ halfY = halfX * sr + halfY * cr;
6123
+ halfX = hx;
6124
+ }
6078
6125
  }
6079
6126
  const circular = s.kind === "circle" || s.kind === "ring" || s.kind === "polygon";
6080
6127
  const soft = (s.kind === "circle" || s.kind === "polygon") && !!s.soft;
@@ -6088,7 +6135,10 @@ function luminanceGrid(spec, opts = {}) {
6088
6135
  const r0 = Math.max(0, Math.floor((centerY - reachY) / cellH));
6089
6136
  const r1 = Math.min(rows - 1, Math.floor((centerY + reachY) / cellH));
6090
6137
  const inkWeight = (s.kind === "text" || s.kind === "emoji" || s.kind === "textBlock" ? 0.55 : 1) * (s.kind === "textBlock" ? textBlockRevealFraction(s, w, h, t) * (s.opacity ?? 1) : 1);
6138
+ const byArea = s.kind === "rect" || s.kind === "bar";
6091
6139
  for (let r = r0; r <= r1; r++) {
6140
+ const fy = byArea ? Math.max(0, Math.min((r + 1) * cellH, centerY + halfY) - Math.max(r * cellH, centerY - halfY)) / cellH : 1;
6141
+ if (fy <= 0) continue;
6092
6142
  for (let c = c0; c <= c1; c++) {
6093
6143
  const dx = (c + 0.5) * cellW - centerX;
6094
6144
  const dy = (r + 0.5) * cellH - centerY;
@@ -6112,6 +6162,14 @@ function luminanceGrid(spec, opts = {}) {
6112
6162
  wgt = soft ? Math.max(0.1, 1 - d / Math.max(halfX, 1e-6)) : 1;
6113
6163
  }
6114
6164
  compose(r * cols + c, lum, a * wgt * shapeWeight, layer.blend);
6165
+ } else if (byArea) {
6166
+ if (boxRot) {
6167
+ const cov = rotatedBoxCoverage(centerX, centerY, boxHx, boxHy, boxRot, c * cellW, r * cellH, (c + 1) * cellW, (r + 1) * cellH);
6168
+ if (cov > 0) compose(r * cols + c, lum, a * shapeWeight * cov, layer.blend);
6169
+ } else {
6170
+ const fx = Math.max(0, Math.min((c + 1) * cellW, centerX + halfX) - Math.max(c * cellW, centerX - halfX)) / cellW;
6171
+ if (fx > 0) compose(r * cols + c, lum, a * shapeWeight * fx * fy, layer.blend);
6172
+ }
6115
6173
  } else {
6116
6174
  compose(r * cols + c, lum, a * inkWeight * shapeWeight, layer.blend);
6117
6175
  }