Make kaleido pivot keyframable
This commit is contained in:
1 parent
c646f66e8f
commit
70cf131c47
9 files changed
+285
-87
No files matched your search
@@ -561,36 +561,35 @@ function kaleidoIndicesForLayer(layer: Layer): number[] {
|
||||
}
|
||||
|
||||
/** Augments a layer's Konva config with the kaleido per-copy
|
||||
* position + rotation. Pivot defaults to the layer's own (x, y),
|
||||
* but a per-layer override moves the orbit centre elsewhere on the
|
||||
* canvas — same arithmetic as render.ts/exportPlayer use, so all
|
||||
* three render paths land identical pixels. Non-source copies are
|
||||
* position + rotation. Pivot lookup matches render.ts: live drag
|
||||
* override → keyframed `props.kaleidoPivotX/Y` → static layer
|
||||
* override → layer's own (x, y). Non-source copies are
|
||||
* listening:false to keep events on the source. */
|
||||
function withK<T extends Record<string, unknown>>(
|
||||
cfg: T,
|
||||
layer: Layer,
|
||||
props: AnimatableProps,
|
||||
ki: number,
|
||||
n: number,
|
||||
): T {
|
||||
if (n <= 1 || ki === 0) return cfg
|
||||
const sx = typeof cfg.x === 'number' ? (cfg.x as number) : 0
|
||||
const sy = typeof cfg.y === 'number' ? (cfg.y as number) : 0
|
||||
const srot = typeof cfg.rotation === 'number' ? (cfg.rotation as number) : 0
|
||||
// Live-pivot drag: when the user drags the on-stage handle for
|
||||
// this layer, route through liveKaleidoPivot so the orbit follows
|
||||
// the pointer in real time.
|
||||
const live = liveKaleidoPivot.value
|
||||
const pivotX = live && live.instanceId === layer.id ? live.x : (layer.kaleidoPivotX ?? sx)
|
||||
const pivotY = live && live.instanceId === layer.id ? live.y : (layer.kaleidoPivotY ?? sy)
|
||||
const liveOverride = live && live.instanceId === layer.id
|
||||
const pivotX = liveOverride
|
||||
? live.x
|
||||
: props.kaleidoPivotX ?? layer.kaleidoPivotX ?? props.x
|
||||
const pivotY = liveOverride
|
||||
? live.y
|
||||
: props.kaleidoPivotY ?? layer.kaleidoPivotY ?? props.y
|
||||
const angle = kaleidoAngleDegrees(ki, n)
|
||||
const a = (angle * Math.PI) / 180
|
||||
const dx = sx - pivotX
|
||||
const dy = sy - pivotY
|
||||
const dx = props.x - pivotX
|
||||
const dy = props.y - pivotY
|
||||
return {
|
||||
...cfg,
|
||||
x: pivotX + dx * Math.cos(a) - dy * Math.sin(a),
|
||||
y: pivotY + dx * Math.sin(a) + dy * Math.cos(a),
|
||||
rotation: srot + angle,
|
||||
rotation: props.rotation + angle,
|
||||
listening: false,
|
||||
draggable: false,
|
||||
} as T
|
||||
@@ -1683,8 +1682,14 @@ const kaleidoPivotHandle = computed<KaleidoPivotEntity | null>(() => {
|
||||
if (asset?.kind === 'button') return null
|
||||
const sampled = sampleLayer(layer, store.playhead)
|
||||
const live = liveKaleidoPivot.value
|
||||
const x = live && live.instanceId === lyId ? live.x : (layer.kaleidoPivotX ?? sampled.x)
|
||||
const y = live && live.instanceId === lyId ? live.y : (layer.kaleidoPivotY ?? sampled.y)
|
||||
// Pivot lookup matches render.ts: live drag → keyframed prop →
|
||||
// legacy static layer field → sampled layer position.
|
||||
const x = live && live.instanceId === lyId
|
||||
? live.x
|
||||
: sampled.kaleidoPivotX ?? layer.kaleidoPivotX ?? sampled.x
|
||||
const y = live && live.instanceId === lyId
|
||||
? live.y
|
||||
: sampled.kaleidoPivotY ?? layer.kaleidoPivotY ?? sampled.y
|
||||
return { kind: 'layer', layerId: layer.id, x, y }
|
||||
}
|
||||
return null
|
||||
@@ -1752,9 +1757,11 @@ function onKaleidoPivotPointerUp() {
|
||||
kaleidoPivotY: liveKaleidoPivot.value.y,
|
||||
})
|
||||
} else {
|
||||
store.setLayerKaleidoPivot(pivotDragEntity.layerId, {
|
||||
x: liveKaleidoPivot.value.x,
|
||||
y: liveKaleidoPivot.value.y,
|
||||
// Layer pivot is keyframable. Upsert at the current playhead
|
||||
// so dropping multiple kfs animates the orbit centre.
|
||||
store.upsertKeyframe(pivotDragEntity.layerId, store.playhead, {
|
||||
kaleidoPivotX: liveKaleidoPivot.value.x,
|
||||
kaleidoPivotY: liveKaleidoPivot.value.y,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -4496,7 +4503,7 @@ function onResizeHandlePointerUp(e: PointerEvent) {
|
||||
>
|
||||
<v-group
|
||||
v-if="entry.item.asset.kind === 'svg' && svgAssetFor(entry.item.asset)"
|
||||
:config="withK(buttonLayerGroupConfig(entry.item.layer, entry.item.props), entry.item.layer, ki, kaleidoCountFor(entry.item.layer))"
|
||||
:config="withK(buttonLayerGroupConfig(entry.item.layer, entry.item.props), entry.item.layer, entry.item.props, ki, kaleidoCountFor(entry.item.layer))"
|
||||
@dragmove="handleDragMove"
|
||||
@dragend="handleDragEnd"
|
||||
@transform="handleTransform"
|
||||
@@ -4581,7 +4588,7 @@ function onResizeHandlePointerUp(e: PointerEvent) {
|
||||
</v-group>
|
||||
<v-rect
|
||||
v-else-if="entry.item.asset.kind === 'rect'"
|
||||
:config="withK(rectConfig(entry.item.layer, entry.item.asset, entry.item.props), entry.item.layer, ki, kaleidoCountFor(entry.item.layer))"
|
||||
:config="withK(rectConfig(entry.item.layer, entry.item.asset, entry.item.props), entry.item.layer, entry.item.props, ki, kaleidoCountFor(entry.item.layer))"
|
||||
@dragmove="handleDragMove"
|
||||
@dragend="handleDragEnd"
|
||||
@transform="handleTransform"
|
||||
@@ -4589,7 +4596,7 @@ function onResizeHandlePointerUp(e: PointerEvent) {
|
||||
/>
|
||||
<v-circle
|
||||
v-else-if="entry.item.asset.kind === 'circle'"
|
||||
:config="withK(circleConfig(entry.item.layer, entry.item.asset, entry.item.props), entry.item.layer, ki, kaleidoCountFor(entry.item.layer))"
|
||||
:config="withK(circleConfig(entry.item.layer, entry.item.asset, entry.item.props), entry.item.layer, entry.item.props, ki, kaleidoCountFor(entry.item.layer))"
|
||||
@dragmove="handleDragMove"
|
||||
@dragend="handleDragEnd"
|
||||
@transform="handleTransform"
|
||||
@@ -4597,7 +4604,7 @@ function onResizeHandlePointerUp(e: PointerEvent) {
|
||||
/>
|
||||
<v-text
|
||||
v-else-if="entry.item.asset.kind === 'text'"
|
||||
:config="withK(textConfig(entry.item.layer, entry.item.asset, entry.item.props), entry.item.layer, ki, kaleidoCountFor(entry.item.layer))"
|
||||
:config="withK(textConfig(entry.item.layer, entry.item.asset, entry.item.props), entry.item.layer, entry.item.props, ki, kaleidoCountFor(entry.item.layer))"
|
||||
@dragmove="handleDragMove"
|
||||
@dragend="handleDragEnd"
|
||||
@transform="handleTransform"
|
||||
@@ -4605,7 +4612,7 @@ function onResizeHandlePointerUp(e: PointerEvent) {
|
||||
/>
|
||||
<v-line
|
||||
v-else-if="entry.item.asset.kind === 'polygon'"
|
||||
:config="withK(polygonConfig(entry.item.layer, entry.item.asset, entry.item.props), entry.item.layer, ki, kaleidoCountFor(entry.item.layer))"
|
||||
:config="withK(polygonConfig(entry.item.layer, entry.item.asset, entry.item.props), entry.item.layer, entry.item.props, ki, kaleidoCountFor(entry.item.layer))"
|
||||
@dragmove="handleDragMove"
|
||||
@dragend="handleDragEnd"
|
||||
@transform="handleTransform"
|
||||
@@ -4613,7 +4620,7 @@ function onResizeHandlePointerUp(e: PointerEvent) {
|
||||
/>
|
||||
<v-image
|
||||
v-else-if="entry.item.asset.kind === 'image' && imageConfig(entry.item.layer, entry.item.asset, entry.item.props)"
|
||||
:config="withK(imageConfig(entry.item.layer, entry.item.asset, entry.item.props)!, entry.item.layer, ki, kaleidoCountFor(entry.item.layer))"
|
||||
:config="withK(imageConfig(entry.item.layer, entry.item.asset, entry.item.props)!, entry.item.layer, entry.item.props, ki, kaleidoCountFor(entry.item.layer))"
|
||||
@dragmove="handleDragMove"
|
||||
@dragend="handleDragEnd"
|
||||
@transform="handleTransform"
|
||||
|
||||
Reference in new issue
Block a user