reframe-video 0.6.33 → 0.6.34

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/bin.js CHANGED
@@ -1263,6 +1263,33 @@ var init_gradient = __esm({
1263
1263
  });
1264
1264
 
1265
1265
  // ../core/src/evaluate.ts
1266
+ function multiply(m, n) {
1267
+ return [
1268
+ m[0] * n[0] + m[2] * n[1],
1269
+ m[1] * n[0] + m[3] * n[1],
1270
+ m[0] * n[2] + m[2] * n[3],
1271
+ m[1] * n[2] + m[3] * n[3],
1272
+ m[0] * n[4] + m[2] * n[5] + m[4],
1273
+ m[1] * n[4] + m[3] * n[5] + m[5]
1274
+ ];
1275
+ }
1276
+ function localMatrix(x, y, rotationDeg, scale, scaleX = 1, scaleY = 1, skewXDeg = 0, skewYDeg = 0) {
1277
+ const r = rotationDeg * Math.PI / 180;
1278
+ if (scaleX === 1 && scaleY === 1 && skewXDeg === 0 && skewYDeg === 0) {
1279
+ const cos = Math.cos(r) * scale;
1280
+ const sin = Math.sin(r) * scale;
1281
+ return [cos, sin, -sin, cos, x, y];
1282
+ }
1283
+ const c = Math.cos(r);
1284
+ const s = Math.sin(r);
1285
+ const tx = Math.tan(skewXDeg * Math.PI / 180);
1286
+ const ty = Math.tan(skewYDeg * Math.PI / 180);
1287
+ const R = [c, s, -s, c, 0, 0];
1288
+ const K = [1, ty, tx, 1, 0, 0];
1289
+ const S = [scale * scaleX, 0, 0, scale * scaleY, 0, 0];
1290
+ const m = multiply(R, multiply(K, S));
1291
+ return [m[0], m[1], m[2], m[3], x, y];
1292
+ }
1266
1293
  function behaviorEnvelope(b, t) {
1267
1294
  const from = b.from ?? Number.NEGATIVE_INFINITY;
1268
1295
  const until = b.until ?? Number.POSITIVE_INFINITY;
@@ -1318,7 +1345,39 @@ function sampleProp(compiled, t, target, prop, fallback) {
1318
1345
  }
1319
1346
  return value;
1320
1347
  }
1321
- var DEG;
1348
+ function nodeParentMatrix(compiled, id, t) {
1349
+ const num2 = (target, prop, fallback) => {
1350
+ const v = sampleProp(compiled, t, target, prop, fallback);
1351
+ return typeof v === "number" ? v : fallback;
1352
+ };
1353
+ let result = null;
1354
+ const walk = (node, parent) => {
1355
+ if (node.id === id) {
1356
+ result = parent;
1357
+ return true;
1358
+ }
1359
+ if (node.type === "group") {
1360
+ const m = multiply(
1361
+ parent,
1362
+ localMatrix(
1363
+ num2(node.id, "x", node.props.x),
1364
+ num2(node.id, "y", node.props.y),
1365
+ num2(node.id, "rotation", node.props.rotation ?? 0),
1366
+ num2(node.id, "scale", node.props.scale ?? 1),
1367
+ num2(node.id, "scaleX", node.props.scaleX ?? 1),
1368
+ num2(node.id, "scaleY", node.props.scaleY ?? 1),
1369
+ num2(node.id, "skewX", node.props.skewX ?? 0),
1370
+ num2(node.id, "skewY", node.props.skewY ?? 0)
1371
+ )
1372
+ );
1373
+ for (const child of node.children) if (walk(child, m)) return true;
1374
+ }
1375
+ return false;
1376
+ };
1377
+ for (const node of compiled.ir.nodes) if (walk(node, IDENTITY)) break;
1378
+ return result;
1379
+ }
1380
+ var IDENTITY, DEG;
1322
1381
  var init_evaluate = __esm({
1323
1382
  "../core/src/evaluate.ts"() {
1324
1383
  "use strict";
@@ -1327,6 +1386,7 @@ var init_evaluate = __esm({
1327
1386
  init_gradient();
1328
1387
  init_interpolate();
1329
1388
  init_path();
1389
+ IDENTITY = [1, 0, 0, 1, 0, 0];
1330
1390
  DEG = Math.PI / 180;
1331
1391
  }
1332
1392
  });
@@ -1364,6 +1424,10 @@ function autoFoley(compiled, opts = {}) {
1364
1424
  os.push(num(compiled, t, id, "opacity", node.props.opacity ?? 1));
1365
1425
  }
1366
1426
  const speed = (i2) => i2 <= 0 ? 0 : Math.hypot(xs[i2] - xs[i2 - 1], ys[i2] - ys[i2 - 1]) * fps;
1427
+ const worldX = (frame) => {
1428
+ const m = nodeParentMatrix(compiled, id, frame / fps);
1429
+ return m ? m[0] * xs[frame] + m[2] * ys[frame] + m[4] : xs[frame];
1430
+ };
1367
1431
  let i = 1;
1368
1432
  while (i <= N) {
1369
1433
  if (speed(i) <= vMin) {
@@ -1386,19 +1450,20 @@ function autoFoley(compiled, opts = {}) {
1386
1450
  if (peakV > vMin && durS >= MIN_DUR && visible) {
1387
1451
  if (wantWhoosh) {
1388
1452
  const quickFlick = durS < 0.25;
1389
- cands.push({ t: peak / fps, sfx: quickFlick ? "swish" : "whoosh", gain: master * loud(peakV), pan: panOf(xs[peak]), rank: peakV });
1453
+ cands.push({ t: peak / fps, sfx: quickFlick ? "swish" : "whoosh", gain: master * loud(peakV), pan: panOf(worldX(peak)), rank: peakV });
1390
1454
  }
1391
1455
  const stopped = b >= N || speed(b + 1) < vStop && speed(Math.min(N, b + 2)) < vStop;
1392
- const landsOnScreen = xs[b] >= 0 && xs[b] <= W && os[b] > 0.1;
1456
+ const wxb = worldX(b);
1457
+ const landsOnScreen = wxb >= 0 && wxb <= W && os[b] > 0.1;
1393
1458
  if (wantImpact && peakV > vDecel && stopped && landsOnScreen && b < N) {
1394
- cands.push({ t: (b + 1) / fps, sfx: size > 220 ? "thud" : "knock", gain: master * loud(peakV), pan: panOf(xs[b]), rank: peakV * 1.1 });
1459
+ cands.push({ t: (b + 1) / fps, sfx: size > 220 ? "thud" : "knock", gain: master * loud(peakV), pan: panOf(worldX(b)), rank: peakV * 1.1 });
1395
1460
  }
1396
1461
  }
1397
1462
  }
1398
1463
  if (wantPop && ss[0] < 0.25) {
1399
1464
  for (let k = 1; k <= N; k++) {
1400
1465
  if (ss[k - 1] < 0.5 && ss[k] >= 0.5 && os[k] > 0.05) {
1401
- cands.push({ t: k / fps, sfx: "pop", gain: master * 0.7, pan: panOf(xs[k]), rank: 600 });
1466
+ cands.push({ t: k / fps, sfx: "pop", gain: master * 0.7, pan: panOf(worldX(k)), rank: 600 });
1402
1467
  break;
1403
1468
  }
1404
1469
  }
package/dist/cli.js CHANGED
@@ -1174,7 +1174,35 @@ function hash01(n, seed) {
1174
1174
  }
1175
1175
 
1176
1176
  // ../core/src/evaluate.ts
1177
+ var IDENTITY = [1, 0, 0, 1, 0, 0];
1178
+ function multiply(m, n) {
1179
+ return [
1180
+ m[0] * n[0] + m[2] * n[1],
1181
+ m[1] * n[0] + m[3] * n[1],
1182
+ m[0] * n[2] + m[2] * n[3],
1183
+ m[1] * n[2] + m[3] * n[3],
1184
+ m[0] * n[4] + m[2] * n[5] + m[4],
1185
+ m[1] * n[4] + m[3] * n[5] + m[5]
1186
+ ];
1187
+ }
1177
1188
  var DEG = Math.PI / 180;
1189
+ function localMatrix(x, y, rotationDeg, scale, scaleX = 1, scaleY = 1, skewXDeg = 0, skewYDeg = 0) {
1190
+ const r = rotationDeg * Math.PI / 180;
1191
+ if (scaleX === 1 && scaleY === 1 && skewXDeg === 0 && skewYDeg === 0) {
1192
+ const cos = Math.cos(r) * scale;
1193
+ const sin = Math.sin(r) * scale;
1194
+ return [cos, sin, -sin, cos, x, y];
1195
+ }
1196
+ const c = Math.cos(r);
1197
+ const s = Math.sin(r);
1198
+ const tx = Math.tan(skewXDeg * Math.PI / 180);
1199
+ const ty = Math.tan(skewYDeg * Math.PI / 180);
1200
+ const R = [c, s, -s, c, 0, 0];
1201
+ const K = [1, ty, tx, 1, 0, 0];
1202
+ const S = [scale * scaleX, 0, 0, scale * scaleY, 0, 0];
1203
+ const m = multiply(R, multiply(K, S));
1204
+ return [m[0], m[1], m[2], m[3], x, y];
1205
+ }
1178
1206
  function behaviorEnvelope(b, t) {
1179
1207
  const from = b.from ?? Number.NEGATIVE_INFINITY;
1180
1208
  const until = b.until ?? Number.POSITIVE_INFINITY;
@@ -1230,6 +1258,38 @@ function sampleProp(compiled, t, target, prop, fallback) {
1230
1258
  }
1231
1259
  return value;
1232
1260
  }
1261
+ function nodeParentMatrix(compiled, id, t) {
1262
+ const num2 = (target, prop, fallback) => {
1263
+ const v = sampleProp(compiled, t, target, prop, fallback);
1264
+ return typeof v === "number" ? v : fallback;
1265
+ };
1266
+ let result = null;
1267
+ const walk = (node, parent) => {
1268
+ if (node.id === id) {
1269
+ result = parent;
1270
+ return true;
1271
+ }
1272
+ if (node.type === "group") {
1273
+ const m = multiply(
1274
+ parent,
1275
+ localMatrix(
1276
+ num2(node.id, "x", node.props.x),
1277
+ num2(node.id, "y", node.props.y),
1278
+ num2(node.id, "rotation", node.props.rotation ?? 0),
1279
+ num2(node.id, "scale", node.props.scale ?? 1),
1280
+ num2(node.id, "scaleX", node.props.scaleX ?? 1),
1281
+ num2(node.id, "scaleY", node.props.scaleY ?? 1),
1282
+ num2(node.id, "skewX", node.props.skewX ?? 0),
1283
+ num2(node.id, "skewY", node.props.skewY ?? 0)
1284
+ )
1285
+ );
1286
+ for (const child of node.children) if (walk(child, m)) return true;
1287
+ }
1288
+ return false;
1289
+ };
1290
+ for (const node of compiled.ir.nodes) if (walk(node, IDENTITY)) break;
1291
+ return result;
1292
+ }
1233
1293
 
1234
1294
  // ../core/src/autoFoley.ts
1235
1295
  var V_MIN = 360;
@@ -1275,6 +1335,10 @@ function autoFoley(compiled, opts = {}) {
1275
1335
  os.push(num(compiled, t, id, "opacity", node.props.opacity ?? 1));
1276
1336
  }
1277
1337
  const speed = (i2) => i2 <= 0 ? 0 : Math.hypot(xs[i2] - xs[i2 - 1], ys[i2] - ys[i2 - 1]) * fps;
1338
+ const worldX = (frame) => {
1339
+ const m = nodeParentMatrix(compiled, id, frame / fps);
1340
+ return m ? m[0] * xs[frame] + m[2] * ys[frame] + m[4] : xs[frame];
1341
+ };
1278
1342
  let i = 1;
1279
1343
  while (i <= N) {
1280
1344
  if (speed(i) <= vMin) {
@@ -1297,19 +1361,20 @@ function autoFoley(compiled, opts = {}) {
1297
1361
  if (peakV > vMin && durS >= MIN_DUR && visible) {
1298
1362
  if (wantWhoosh) {
1299
1363
  const quickFlick = durS < 0.25;
1300
- cands.push({ t: peak / fps, sfx: quickFlick ? "swish" : "whoosh", gain: master * loud(peakV), pan: panOf(xs[peak]), rank: peakV });
1364
+ cands.push({ t: peak / fps, sfx: quickFlick ? "swish" : "whoosh", gain: master * loud(peakV), pan: panOf(worldX(peak)), rank: peakV });
1301
1365
  }
1302
1366
  const stopped = b >= N || speed(b + 1) < vStop && speed(Math.min(N, b + 2)) < vStop;
1303
- const landsOnScreen = xs[b] >= 0 && xs[b] <= W && os[b] > 0.1;
1367
+ const wxb = worldX(b);
1368
+ const landsOnScreen = wxb >= 0 && wxb <= W && os[b] > 0.1;
1304
1369
  if (wantImpact && peakV > vDecel && stopped && landsOnScreen && b < N) {
1305
- cands.push({ t: (b + 1) / fps, sfx: size > 220 ? "thud" : "knock", gain: master * loud(peakV), pan: panOf(xs[b]), rank: peakV * 1.1 });
1370
+ cands.push({ t: (b + 1) / fps, sfx: size > 220 ? "thud" : "knock", gain: master * loud(peakV), pan: panOf(worldX(b)), rank: peakV * 1.1 });
1306
1371
  }
1307
1372
  }
1308
1373
  }
1309
1374
  if (wantPop && ss[0] < 0.25) {
1310
1375
  for (let k = 1; k <= N; k++) {
1311
1376
  if (ss[k - 1] < 0.5 && ss[k] >= 0.5 && os[k] > 0.05) {
1312
- cands.push({ t: k / fps, sfx: "pop", gain: master * 0.7, pan: panOf(xs[k]), rank: 600 });
1377
+ cands.push({ t: k / fps, sfx: "pop", gain: master * 0.7, pan: panOf(worldX(k)), rank: 600 });
1313
1378
  break;
1314
1379
  }
1315
1380
  }
package/dist/index.js CHANGED
@@ -1796,6 +1796,10 @@ function autoFoley(compiled, opts = {}) {
1796
1796
  os.push(num(compiled, t, id, "opacity", node.props.opacity ?? 1));
1797
1797
  }
1798
1798
  const speed = (i2) => i2 <= 0 ? 0 : Math.hypot(xs[i2] - xs[i2 - 1], ys[i2] - ys[i2 - 1]) * fps;
1799
+ const worldX = (frame) => {
1800
+ const m = nodeParentMatrix(compiled, id, frame / fps);
1801
+ return m ? m[0] * xs[frame] + m[2] * ys[frame] + m[4] : xs[frame];
1802
+ };
1799
1803
  let i = 1;
1800
1804
  while (i <= N) {
1801
1805
  if (speed(i) <= vMin) {
@@ -1818,19 +1822,20 @@ function autoFoley(compiled, opts = {}) {
1818
1822
  if (peakV > vMin && durS >= MIN_DUR && visible) {
1819
1823
  if (wantWhoosh) {
1820
1824
  const quickFlick = durS < 0.25;
1821
- cands.push({ t: peak / fps, sfx: quickFlick ? "swish" : "whoosh", gain: master * loud(peakV), pan: panOf(xs[peak]), rank: peakV });
1825
+ cands.push({ t: peak / fps, sfx: quickFlick ? "swish" : "whoosh", gain: master * loud(peakV), pan: panOf(worldX(peak)), rank: peakV });
1822
1826
  }
1823
1827
  const stopped = b >= N || speed(b + 1) < vStop && speed(Math.min(N, b + 2)) < vStop;
1824
- const landsOnScreen = xs[b] >= 0 && xs[b] <= W && os[b] > 0.1;
1828
+ const wxb = worldX(b);
1829
+ const landsOnScreen = wxb >= 0 && wxb <= W && os[b] > 0.1;
1825
1830
  if (wantImpact && peakV > vDecel && stopped && landsOnScreen && b < N) {
1826
- cands.push({ t: (b + 1) / fps, sfx: size > 220 ? "thud" : "knock", gain: master * loud(peakV), pan: panOf(xs[b]), rank: peakV * 1.1 });
1831
+ cands.push({ t: (b + 1) / fps, sfx: size > 220 ? "thud" : "knock", gain: master * loud(peakV), pan: panOf(worldX(b)), rank: peakV * 1.1 });
1827
1832
  }
1828
1833
  }
1829
1834
  }
1830
1835
  if (wantPop && ss[0] < 0.25) {
1831
1836
  for (let k = 1; k <= N; k++) {
1832
1837
  if (ss[k - 1] < 0.5 && ss[k] >= 0.5 && os[k] > 0.05) {
1833
- cands.push({ t: k / fps, sfx: "pop", gain: master * 0.7, pan: panOf(xs[k]), rank: 600 });
1838
+ cands.push({ t: k / fps, sfx: "pop", gain: master * 0.7, pan: panOf(worldX(k)), rank: 600 });
1834
1839
  break;
1835
1840
  }
1836
1841
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reframe-video",
3
- "version": "0.6.33",
3
+ "version": "0.6.34",
4
4
  "description": "Declarative motion graphics that AI can write and humans can tweak — human edits survive AI regeneration. Deterministic mp4 renders from a plain-data scene format.",
5
5
  "keywords": [
6
6
  "motion-graphics",