Add camera resize and keyframe controls
This commit is contained in:
1 parent
3a93d6ea5d
commit
b9a4b53109
5 files changed
+428
-17
No files matched your search
@@ -789,15 +789,45 @@ const cameraFrameConfig = computed(() => {
|
||||
height: frame.height,
|
||||
fillEnabled: false,
|
||||
stroke: selected ? '#38bdf8' : '#0ea5e9',
|
||||
strokeWidth: (selected ? 2.5 : 1.5) / zoom.value,
|
||||
strokeWidth: (selected ? 1.4 : 1) / zoom.value,
|
||||
strokeScaleEnabled: false,
|
||||
dash: [10 / zoom.value, 6 / zoom.value],
|
||||
hitStrokeWidth: Math.max(10 / zoom.value, 8),
|
||||
dash: [4 / zoom.value, 3 / zoom.value],
|
||||
hitStrokeWidth: Math.max(8 / zoom.value, 6),
|
||||
listening: true,
|
||||
draggable: selected && !camera.locked,
|
||||
}
|
||||
})
|
||||
|
||||
const cameraResizeDragStart = ref<CameraProps | null>(null)
|
||||
|
||||
function cameraOutputAspect(): number {
|
||||
const canvas = store.scene.canvas
|
||||
const width = Number.isFinite(canvas.width) && canvas.width > 0 ? canvas.width : 1
|
||||
const height = Number.isFinite(canvas.height) && canvas.height > 0 ? canvas.height : 1
|
||||
return width / height
|
||||
}
|
||||
|
||||
const cameraResizeHandleConfig = computed(() => {
|
||||
const frame = cameraFrame.value
|
||||
const camera = store.scene.camera
|
||||
if (!frame || !camera || !store.selectedCamera || camera.locked) return null
|
||||
const size = 10 / zoom.value
|
||||
return {
|
||||
id: 'camera-resize-handle',
|
||||
name: 'camera-resize-handle',
|
||||
x: frame.x + frame.width - size / 2,
|
||||
y: frame.y + frame.height - size / 2,
|
||||
width: size,
|
||||
height: size,
|
||||
fill: '#f8fafc',
|
||||
stroke: '#38bdf8',
|
||||
strokeWidth: 1 / zoom.value,
|
||||
strokeScaleEnabled: false,
|
||||
draggable: true,
|
||||
listening: true,
|
||||
}
|
||||
})
|
||||
|
||||
function selectCameraFromStage(e?: Konva.KonvaEventObject<MouseEvent>) {
|
||||
if (e) e.cancelBubble = true
|
||||
store.selectCamera(true)
|
||||
@@ -817,6 +847,47 @@ function onCameraDragEnd(e: Konva.KonvaEventObject<DragEvent>) {
|
||||
onCameraDragMove(e)
|
||||
}
|
||||
|
||||
function onCameraResizeStart(e: Konva.KonvaEventObject<DragEvent | MouseEvent>) {
|
||||
e.cancelBubble = true
|
||||
if (store.scene.camera?.locked) return
|
||||
store.selectCamera(true)
|
||||
cameraResizeDragStart.value = cameraFrame.value ? { ...cameraFrame.value } : null
|
||||
}
|
||||
|
||||
function onCameraResizeDrag(e: Konva.KonvaEventObject<DragEvent>) {
|
||||
e.cancelBubble = true
|
||||
const camera = store.scene.camera
|
||||
const start = cameraResizeDragStart.value ?? cameraFrame.value
|
||||
if (!camera || camera.locked || !start) return
|
||||
|
||||
const node = e.target
|
||||
const handleSize = cameraResizeHandleConfig.value?.width ?? 10 / zoom.value
|
||||
const aspect = cameraOutputAspect()
|
||||
const widthFromPointer = Math.max(1, node.x() + handleSize / 2 - start.x)
|
||||
const heightFromPointer = Math.max(1, node.y() + handleSize / 2 - start.y)
|
||||
const widthDelta = Math.abs(widthFromPointer - start.width) / Math.max(1, start.width)
|
||||
const heightDelta = Math.abs(heightFromPointer - start.height) / Math.max(1, start.height)
|
||||
const width = Math.max(
|
||||
1,
|
||||
Math.round(widthDelta >= heightDelta ? widthFromPointer : heightFromPointer * aspect),
|
||||
)
|
||||
const height = Math.max(1, Math.round(width / aspect))
|
||||
|
||||
node.x(start.x + width - handleSize / 2)
|
||||
node.y(start.y + height - handleSize / 2)
|
||||
store.upsertCameraKeyframe(store.playhead, {
|
||||
x: Math.round(start.x),
|
||||
y: Math.round(start.y),
|
||||
width,
|
||||
height,
|
||||
})
|
||||
}
|
||||
|
||||
function onCameraResizeEnd(e: Konva.KonvaEventObject<DragEvent>) {
|
||||
onCameraResizeDrag(e)
|
||||
cameraResizeDragStart.value = null
|
||||
}
|
||||
|
||||
function toggleCameraEnabled() {
|
||||
if (store.scene.camera?.enabled) {
|
||||
store.disableCamera()
|
||||
@@ -4793,6 +4864,14 @@ function onResizeHandlePointerUp(e: PointerEvent) {
|
||||
@dragmove="onCameraDragMove"
|
||||
@dragend="onCameraDragEnd"
|
||||
/>
|
||||
<v-rect
|
||||
v-if="cameraResizeHandleConfig"
|
||||
:config="cameraResizeHandleConfig"
|
||||
@mousedown="onCameraResizeStart"
|
||||
@dragstart="onCameraResizeStart"
|
||||
@dragmove="onCameraResizeDrag"
|
||||
@dragend="onCameraResizeEnd"
|
||||
/>
|
||||
<v-rect
|
||||
v-for="h in canvasResizeHandles"
|
||||
:key="`canvas-resize-${h.edge}`"
|
||||
|
||||
Reference in new issue
Block a user