feat: add capture button widget to webcam component

Added programmatic capture button that appears when camera is turned on. The button uses node.addWidget() to integrate with LiteGraph canvas.

- Add captureImage() function to draw video frame to canvas and store in node.imgs
- Add capture button widget in showWidgets() using node.addWidget()
- Create canvas element at module level for efficient reuse
- Widget restoration handled by existing restoreWidgets() cleanup
This commit is contained in:
Johnpaul
2025-11-25 01:40:59 +01:00
parent a65b063a98
commit e1693dc341

View File

@@ -74,6 +74,7 @@ const videoRef = ref<HTMLVideoElement>()
const videoContainerRef = ref<HTMLElement>()
const stream = ref<MediaStream | null>(null)
const isHovered = useElementHover(videoContainerRef)
const canvas = document.createElement('canvas')
const litegraphNode = computed(() => {
if (!props.nodeId || !app.rootGraph) return null
@@ -177,6 +178,15 @@ function showWidgets() {
node.widgets = newWidgets
const rawNode = toRaw(node)
rawNode.addWidget(
'button',
t('g.capture', 'Capture'),
'capture',
captureImage,
{ canvasOnly: true, serialize: false }
)
if (node.graph) {
node.graph._version++
}
@@ -184,6 +194,33 @@ function showWidgets() {
app.graph.setDirtyCanvas(true, true)
}
function captureImage() {
const node = litegraphNode.value
if (!node || !videoRef.value) return
const widthWidget = node.widgets?.find((w) => toRaw(w).name === 'width')
const heightWidget = node.widgets?.find((w) => toRaw(w).name === 'height')
const width = (widthWidget?.value as number) || 640
const height = (heightWidget?.value as number) || 480
canvas.width = width
canvas.height = height
const ctx = canvas.getContext('2d')
if (!ctx) return
ctx.drawImage(videoRef.value, 0, 0, width, height)
const data = canvas.toDataURL('image/png')
const img = new Image()
img.onload = () => {
node.imgs = [img]
app.graph.setDirtyCanvas(true)
}
img.src = data
}
async function startCameraPreview() {
if (props.readonly) return