From 8e71d7379ad9b63b7c6029a53cdc1f3d123703c0 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 3 Jan 2026 18:25:24 +0100 Subject: [PATCH] [FEAT] Add eye drop to pixel editor --- src/components/DrawTab.vue | 26 +++++++++++++++++++--- src/composables/usePixelEditor.ts | 37 ++++++++++++++++++++++++------- 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/src/components/DrawTab.vue b/src/components/DrawTab.vue index 0da8189..ffdb732 100644 --- a/src/components/DrawTab.vue +++ b/src/components/DrawTab.vue @@ -56,6 +56,11 @@ + + + @@ -130,15 +135,15 @@ Grid
{{ editor.pointerX.value }}, {{ editor.pointerY.value }}
-
{{ editor.canvasWidth.value }} × {{ editor.canvasHeight.value }}
+
W: {{ editor.canvasWidth.value }} H: {{ editor.canvasHeight.value }}
@@ -182,6 +187,18 @@ backgroundSize: `${editor.zoom.value}px ${editor.zoom.value}px`, }" > + + +
@@ -269,6 +286,7 @@ const resizeWidth = ref(32); const resizeHeight = ref(32); const resizeAnchor = ref('top-left'); + const showPixelHighlight = ref(true); const recentColors = ref(['#ffffff', '#000000', '#ff0000', '#00ff00', '#0000ff']); @@ -425,6 +443,8 @@ editor.currentTool.value = 'pencil'; } else if (event.key === 'e' || event.key === 'E') { editor.currentTool.value = 'eraser'; + } else if (event.key === 'i' || event.key === 'I') { + editor.currentTool.value = 'picker'; } // Undo/Redo diff --git a/src/composables/usePixelEditor.ts b/src/composables/usePixelEditor.ts index 90c940c..ebebe45 100644 --- a/src/composables/usePixelEditor.ts +++ b/src/composables/usePixelEditor.ts @@ -20,7 +20,7 @@ export const usePixelEditor = (options: PixelEditorOptions = {}) => { const canvasWidth = ref(options.initialWidth || 32); const canvasHeight = ref(options.initialHeight || 32); - const currentTool = ref<'pencil' | 'eraser'>('pencil'); + const currentTool = ref<'pencil' | 'eraser' | 'picker'>('pencil'); const currentColor = ref('#000000'); const brushSize = ref(1); const zoom = ref(1); @@ -31,7 +31,7 @@ export const usePixelEditor = (options: PixelEditorOptions = {}) => { const pointerX = ref(0); const pointerY = ref(0); - const showPointerLocation = ref(false); + const showPointerLocation = ref(true); const showCheckerboard = ref(false); // History management @@ -185,14 +185,31 @@ export const usePixelEditor = (options: PixelEditorOptions = {}) => { } }; + const pickColor = (x: number, y: number) => { + if (!ctx.value) return; + const p = ctx.value.getImageData(x, y, 1, 1).data; + + // Ignore if fully transparent + if (p[3] === 0) return; + + const hex = '#' + ('00' + p[0].toString(16)).slice(-2) + ('00' + p[1].toString(16)).slice(-2) + ('00' + p[2].toString(16)).slice(-2); + + currentColor.value = hex; + }; + const startDrawing = (event: MouseEvent) => { if (!canvas.value) return; isDrawing.value = true; const { x, y } = getPixelCoords(event, canvas.value); - lastX.value = x; - lastY.value = y; - drawPixel(x, y); + + if (currentTool.value === 'picker') { + pickColor(x, y); + } else { + lastX.value = x; + lastY.value = y; + drawPixel(x, y); + } }; const continueDrawing = (event: MouseEvent) => { @@ -204,9 +221,13 @@ export const usePixelEditor = (options: PixelEditorOptions = {}) => { if (!isDrawing.value) return; - drawLine(lastX.value, lastY.value, x, y); - lastX.value = x; - lastY.value = y; + if (currentTool.value === 'picker') { + pickColor(x, y); + } else { + drawLine(lastX.value, lastY.value, x, y); + lastX.value = x; + lastY.value = y; + } }; const stopDrawing = () => {