Make kaleido pivot keyframable
This commit is contained in:
1 parent
c646f66e8f
commit
70cf131c47
9 files changed
+285
-87
No files matched your search
+21
-18
@@ -4,7 +4,7 @@
|
||||
// (lib/exportPlayer.ts engine source — by mirroring the formulas in
|
||||
// JS) all derive identical geometry from the same definitions.
|
||||
|
||||
import type { Layer, ClipInstance } from '@/types/scene'
|
||||
import type { AnimatableProps, Layer, ClipInstance } from '@/types/scene'
|
||||
|
||||
/** Number of radial copies to render. Returns 1 when kaleido is off
|
||||
* or the count is below the floor — the caller should treat 1 as
|
||||
@@ -107,42 +107,45 @@ export function layerKaleidoCount(layer: Layer): number {
|
||||
return kaleidoCountFor(layer)
|
||||
}
|
||||
|
||||
/** Effective pivot for a layer. Defaults to the layer's sampled
|
||||
* position; an explicit `kaleidoPivotX/Y` overrides per-axis. */
|
||||
/** Effective pivot for a layer. Lookup chain:
|
||||
* 1. `props.kaleidoPivotX/Y` — keyframed value (lets the pivot
|
||||
* animate)
|
||||
* 2. `Layer.kaleidoPivotX/Y` — legacy static override (kept for
|
||||
* back-compat with projects saved before the feature went
|
||||
* keyframable)
|
||||
* 3. layer's sampled (x, y) — default
|
||||
*/
|
||||
export function layerKaleidoPivot(
|
||||
layer: Layer,
|
||||
sampledX: number,
|
||||
sampledY: number,
|
||||
props: AnimatableProps,
|
||||
): { x: number; y: number } {
|
||||
return {
|
||||
x: layer.kaleidoPivotX ?? sampledX,
|
||||
y: layer.kaleidoPivotY ?? sampledY,
|
||||
x: props.kaleidoPivotX ?? layer.kaleidoPivotX ?? props.x,
|
||||
y: props.kaleidoPivotY ?? layer.kaleidoPivotY ?? props.y,
|
||||
}
|
||||
}
|
||||
|
||||
/** World-space (x, y, rotation) for arm `index` of a kaleido'd
|
||||
* layer. The source (index 0) is unchanged. Higher indices
|
||||
* rotate around the pivot — both their position AND their
|
||||
* orientation, since layer kaleido always rotates copies. */
|
||||
* layer. The source (index 0) is unchanged. Higher indices rotate
|
||||
* around the pivot — both their position AND their orientation,
|
||||
* since layer kaleido always rotates copies. */
|
||||
export function layerArmTransform(
|
||||
layer: Layer,
|
||||
sampledX: number,
|
||||
sampledY: number,
|
||||
sampledRotation: number,
|
||||
props: AnimatableProps,
|
||||
index: number,
|
||||
count: number,
|
||||
): { x: number; y: number; rotation: number } {
|
||||
if (index === 0 || count <= 1) {
|
||||
return { x: sampledX, y: sampledY, rotation: sampledRotation }
|
||||
return { x: props.x, y: props.y, rotation: props.rotation }
|
||||
}
|
||||
const { x: px, y: py } = layerKaleidoPivot(layer, sampledX, sampledY)
|
||||
const { x: px, y: py } = layerKaleidoPivot(layer, props)
|
||||
const angle = kaleidoAngleDegrees(index, count)
|
||||
const a = (angle * Math.PI) / 180
|
||||
const dx = sampledX - px
|
||||
const dy = sampledY - py
|
||||
const dx = props.x - px
|
||||
const dy = props.y - py
|
||||
return {
|
||||
x: px + dx * Math.cos(a) - dy * Math.sin(a),
|
||||
y: py + dx * Math.sin(a) + dy * Math.cos(a),
|
||||
rotation: sampledRotation + angle,
|
||||
rotation: props.rotation + angle,
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user