animation variety: per-scene motion signatures (occlusion-safe scenes only) - aperitif tumble, Course IV curved-arc trajectories, Course V spiral orbit-in; achieved via manual per-frame transform math, no plugin/dependency added; bite-carrying scenes keep clean translate
This commit is contained in:
+18
-1
@@ -943,13 +943,30 @@ body:not(.fx) .slab{display:none}
|
|||||||
u.flat.style.visibility = "hidden";
|
u.flat.style.visibility = "hidden";
|
||||||
const lis = u.legend ? [...u.legend.children] : [];
|
const lis = u.legend ? [...u.legend.children] : [];
|
||||||
const n = lis.length;
|
const n = lis.length;
|
||||||
|
// per-scene motion signature (occlusion-safe scenes only; default is straight translate).
|
||||||
|
// "away" is 0 at the hero layout, 1 at collapsed/flown - every signature returns to identity
|
||||||
|
// at the hero so the assembled slices always match the source image exactly.
|
||||||
|
const M = u.man.motion, RAD = Math.PI / 180;
|
||||||
u.apply = t => {
|
u.apply = t => {
|
||||||
const sg = u.man.stagger || 0, k = u.man.parts.length;
|
const sg = u.man.stagger || 0, k = u.man.parts.length;
|
||||||
u.man.parts.forEach((p, i) => {
|
u.man.parts.forEach((p, i) => {
|
||||||
const pt = sg ? Math.min(1, Math.max(0, t * (1 + sg * (k - 1)) - sg * i)) : t;
|
const pt = sg ? Math.min(1, Math.max(0, t * (1 + sg * (k - 1)) - sg * i)) : t;
|
||||||
const e = u.man.reverse ? (1 - pt) : pt;
|
const e = u.man.reverse ? (1 - pt) : pt;
|
||||||
|
const away = 1 - e;
|
||||||
|
let ox = p.dx * away, oy = p.dy * away, extra = "";
|
||||||
|
if (M === "tumble") { // aperitif: fragments spin as they fly out
|
||||||
|
const spin = (p.spin != null ? p.spin : (i % 2 ? 20 : -20)) * away;
|
||||||
|
extra = " rotate(" + spin.toFixed(2) + "deg)";
|
||||||
|
} else if (M === "arc") { // traffic: slices travel a bowed (curved) path
|
||||||
|
const len = Math.hypot(p.dx, p.dy) || 1;
|
||||||
|
const bow = (u.man.bow || 9) * 4 * away * (1 - away);
|
||||||
|
ox += (-p.dy / len) * bow; oy += (p.dx / len) * bow;
|
||||||
|
} else if (M === "orbit") { // OpenShift: satellites spiral in around the core
|
||||||
|
const a = (u.man.orbit || 55) * away * RAD, c = Math.cos(a), sn = Math.sin(a);
|
||||||
|
ox = (p.dx * c - p.dy * sn) * away; oy = (p.dx * sn + p.dy * c) * away;
|
||||||
|
}
|
||||||
u.slabs[i].style.transform =
|
u.slabs[i].style.transform =
|
||||||
"translate3d(" + (p.dx * (1 - e)).toFixed(3) + "%," + (p.dy * (1 - e)).toFixed(3) + "%,0)";
|
"translate3d(" + ox.toFixed(3) + "%," + oy.toFixed(3) + "%,0)" + extra;
|
||||||
});
|
});
|
||||||
u.scene.style.transform = "scale(" + (0.95 + 0.05 * t).toFixed(4) + ")";
|
u.scene.style.transform = "scale(" + (0.95 + 0.05 * t).toFixed(4) + ")";
|
||||||
if (n) lis.forEach((li, i) => li.classList.toggle("lit", t >= 0.9 * ((i + 0.5) / n)));
|
if (n) lis.forEach((li, i) => li.classList.toggle("lit", t >= 0.9 * ((i + 0.5) / n)));
|
||||||
|
|||||||
@@ -828,5 +828,7 @@
|
|||||||
"dx": 13.85,
|
"dx": 13.85,
|
||||||
"dy": 15.36
|
"dy": 15.36
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"motion": "orbit",
|
||||||
|
"orbit": 60
|
||||||
}
|
}
|
||||||
@@ -675,5 +675,6 @@
|
|||||||
"dy": 31.74
|
"dy": 31.74
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"reverse": true
|
"reverse": true,
|
||||||
|
"motion": "tumble"
|
||||||
}
|
}
|
||||||
@@ -667,5 +667,7 @@
|
|||||||
"dy": -11.61
|
"dy": -11.61
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"stagger": 0.22
|
"stagger": 0.22,
|
||||||
|
"motion": "arc",
|
||||||
|
"bow": 8
|
||||||
}
|
}
|
||||||
@@ -96,6 +96,8 @@ def emit(name, tag, spec):
|
|||||||
man["stagger"] = spec["stagger"]
|
man["stagger"] = spec["stagger"]
|
||||||
if spec.get("reverse"):
|
if spec.get("reverse"):
|
||||||
man["reverse"] = True
|
man["reverse"] = True
|
||||||
|
for kk in ("motion","bow","orbit"):
|
||||||
|
if kk in spec: man[kk]=spec[kk]
|
||||||
out = ROOT / "pilot" / f"manifest-{tag}.json"
|
out = ROOT / "pilot" / f"manifest-{tag}.json"
|
||||||
out.write_text(json.dumps(man, indent=1))
|
out.write_text(json.dumps(man, indent=1))
|
||||||
print(f"manifest-{tag}.json: {len(parts)} parts ->",
|
print(f"manifest-{tag}.json: {len(parts)} parts ->",
|
||||||
|
|||||||
Reference in New Issue
Block a user