From a6bfc7a989486d04143e65a654583149aba25d49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Syn=C3=A1=C4=8Dek?= Date: Sun, 30 Mar 2025 11:34:44 +0200 Subject: [PATCH 1/5] fix cursor offset --- js/canvas-utils.mjs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/js/canvas-utils.mjs b/js/canvas-utils.mjs index 978a572..4c89640 100644 --- a/js/canvas-utils.mjs +++ b/js/canvas-utils.mjs @@ -4,7 +4,12 @@ import { getCursorCanvas } from "./dom.mjs"; const ctx = getCursorCanvas().getContext("2d"); const CURSOR_SIZE = 20; +function offsetCursorX(x) { + return x - CURSOR_SIZE / 2; +} + export function drawCursor(x, y) { + x = offsetCursorX(x); ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); const half = CURSOR_SIZE / 2; @@ -24,6 +29,7 @@ export function drawCursor(x, y) { ctx.closePath(); + ctx.moveTo(x + half, y + half); ctx.strokeStyle = COLOR.WHITE; ctx.fillStyle = COLOR.WHITE; From 0bc8434bc699681036ac82ca4fa50c075ec84786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Syn=C3=A1=C4=8Dek?= Date: Sun, 30 Mar 2025 13:19:30 +0200 Subject: [PATCH 2/5] make center of cursor transparent --- js/canvas-utils.mjs | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/js/canvas-utils.mjs b/js/canvas-utils.mjs index 4c89640..d5440d2 100644 --- a/js/canvas-utils.mjs +++ b/js/canvas-utils.mjs @@ -2,38 +2,42 @@ import { COLOR } from "./state/constants.mjs"; import { getCursorCanvas } from "./dom.mjs"; const ctx = getCursorCanvas().getContext("2d"); -const CURSOR_SIZE = 20; - -function offsetCursorX(x) { - return x - CURSOR_SIZE / 2; -} +const CURSOR_SIZE = 10; +const CURSOR_PART_SIZE = CURSOR_SIZE / 2; +const GAP = CURSOR_SIZE / 2; +const LINE_WIDTH = 5; export function drawCursor(x, y) { - x = offsetCursorX(x); ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); - const half = CURSOR_SIZE / 2; - ctx.lineWidth = 5; + ctx.lineWidth = LINE_WIDTH; ctx.lineCap = "round"; ctx.strokeStyle = COLOR.BLACK; + /* --- Cursor --- */ + // Draw top line ctx.beginPath(); - ctx.moveTo(x, y); - ctx.lineTo(x + CURSOR_SIZE, y); + ctx.moveTo(x, y - GAP); + ctx.lineTo(x, y - CURSOR_PART_SIZE - GAP - CURSOR_SIZE); ctx.stroke(); + // Draw bottom line ctx.beginPath(); - ctx.moveTo(x + half, y - half); - ctx.lineTo(x + half, y + half); + ctx.moveTo(x, y + GAP); + ctx.lineTo(x, y + CURSOR_PART_SIZE + GAP + CURSOR_SIZE); ctx.stroke(); - ctx.closePath(); - + // Draw left line + ctx.beginPath(); + ctx.moveTo(x - GAP, y); + ctx.lineTo(x - CURSOR_PART_SIZE - GAP - CURSOR_SIZE, y); + ctx.stroke(); - ctx.moveTo(x + half, y + half); - ctx.strokeStyle = COLOR.WHITE; - ctx.fillStyle = COLOR.WHITE; + // Draw right line ctx.beginPath(); - ctx.arc(x + half, y, 3, 0, Math.PI * 2); - ctx.fill(); + ctx.moveTo(x + GAP, y); + ctx.lineTo(x + CURSOR_PART_SIZE + GAP + CURSOR_SIZE, y); + ctx.stroke(); + + ctx.closePath(); } From 62385e7024c533ffd2e0de1c2c4658b9a4ae5a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Syn=C3=A1=C4=8Dek?= Date: Sun, 30 Mar 2025 13:41:10 +0200 Subject: [PATCH 3/5] invert color automatically with cursor --- js/canvas-utils.mjs | 45 ++++++++++++++++++++++++++++++++++++++++++--- js/ui-utils.mjs | 13 +++++++++++++ js/ui/panel.mjs | 5 +---- 3 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 js/ui-utils.mjs diff --git a/js/canvas-utils.mjs b/js/canvas-utils.mjs index d5440d2..10efe6e 100644 --- a/js/canvas-utils.mjs +++ b/js/canvas-utils.mjs @@ -1,18 +1,57 @@ import { COLOR } from "./state/constants.mjs"; -import { getCursorCanvas } from "./dom.mjs"; +import { getCursorCanvas, getCanvas } from "./dom.mjs"; +import { getPanel } from "./dom.mjs"; +import { isCursorWithinPanelBounds } from "./ui-utils.mjs"; const ctx = getCursorCanvas().getContext("2d"); +const canvasCtx = getCanvas().getContext("2d"); const CURSOR_SIZE = 10; const CURSOR_PART_SIZE = CURSOR_SIZE / 2; const GAP = CURSOR_SIZE / 2; const LINE_WIDTH = 5; +/** + * Inverts color to avoid invisible cursor. + * + * @param {number} r - Red color. + * @param {number} g - Green color. + * @param {number} b - Blue color. + * + * @returns {number[]} - Inverted color in r, g,b order. + */ +function invertColor(r, g, b, a) { + const rgb = [r, g, b, a] + for (var i = 0; i < rgb.length; i++) rgb[i] = (i === 3 ? 1 : 255) - rgb[i]; + return rgb +} + +/** + * Returns color on given canvas area in RGBA format. + * + * @param {number} x - X coordinate. + * @param {number} y - Y coordinate. + * + * @returns {string} - RGBA color. + */ +function getPixelRGBAColor(x, y) { + const panel = getPanel(); + const rect = panel.getBoundingClientRect(); + + if (isCursorWithinPanelBounds(x, y, rect)) { + return COLOR.BLACK; + } + + const pixel = canvasCtx.getImageData(x, y, GAP, GAP) + const [r, g, b, a] = invertColor(...pixel.data); + + return `rgb(${r}, ${g}, ${b}, ${Math.abs(a)})`; +} + export function drawCursor(x, y) { ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); - ctx.lineWidth = LINE_WIDTH; ctx.lineCap = "round"; - ctx.strokeStyle = COLOR.BLACK; + ctx.strokeStyle = getPixelRGBAColor(x, y); /* --- Cursor --- */ // Draw top line diff --git a/js/ui-utils.mjs b/js/ui-utils.mjs new file mode 100644 index 0000000..a8f182d --- /dev/null +++ b/js/ui-utils.mjs @@ -0,0 +1,13 @@ +/** + * Is cursor located on UI panel? + * + * @param {number} x - Cursor x coordinate. + * @param {number} y - Cursor y coordinate. + * @param {DOMRect} rect - Panel bounds. + * + * @returns {boolean} - Is cursor located on UI panel? + */ +export function isCursorWithinPanelBounds(x, y, rect) { + return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom; +} + diff --git a/js/ui/panel.mjs b/js/ui/panel.mjs index 521bbe9..2ad51ca 100644 --- a/js/ui/panel.mjs +++ b/js/ui/panel.mjs @@ -3,10 +3,7 @@ import { isPrimaryGamepadButtonPressed, } from "../controls/gamepad.mjs"; import { getPanel } from "../dom.mjs"; - -function isCursorWithinPanelBounds(x, y, rect) { - return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom; -} +import { isCursorWithinPanelBounds } from "../ui-utils.mjs"; function getPanelButtonByCoordinates(x, y, panel) { const buttons = panel.querySelectorAll("button"); From 3514c71e4e4f67c0dad5e22aab9b2ee41c65721f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Syn=C3=A1=C4=8Dek?= Date: Sun, 30 Mar 2025 13:42:56 +0200 Subject: [PATCH 4/5] Fix formatting --- js/canvas-utils.mjs | 6 +++--- js/ui-utils.mjs | 15 +++++++-------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/js/canvas-utils.mjs b/js/canvas-utils.mjs index 10efe6e..24dc175 100644 --- a/js/canvas-utils.mjs +++ b/js/canvas-utils.mjs @@ -20,9 +20,9 @@ const LINE_WIDTH = 5; * @returns {number[]} - Inverted color in r, g,b order. */ function invertColor(r, g, b, a) { - const rgb = [r, g, b, a] + const rgb = [r, g, b, a]; for (var i = 0; i < rgb.length; i++) rgb[i] = (i === 3 ? 1 : 255) - rgb[i]; - return rgb + return rgb; } /** @@ -41,7 +41,7 @@ function getPixelRGBAColor(x, y) { return COLOR.BLACK; } - const pixel = canvasCtx.getImageData(x, y, GAP, GAP) + const pixel = canvasCtx.getImageData(x, y, GAP, GAP); const [r, g, b, a] = invertColor(...pixel.data); return `rgb(${r}, ${g}, ${b}, ${Math.abs(a)})`; diff --git a/js/ui-utils.mjs b/js/ui-utils.mjs index a8f182d..f4b5b99 100644 --- a/js/ui-utils.mjs +++ b/js/ui-utils.mjs @@ -1,13 +1,12 @@ /** * Is cursor located on UI panel? - * - * @param {number} x - Cursor x coordinate. - * @param {number} y - Cursor y coordinate. - * @param {DOMRect} rect - Panel bounds. - * - * @returns {boolean} - Is cursor located on UI panel? - */ + * + * @param {number} x - Cursor x coordinate. + * @param {number} y - Cursor y coordinate. + * @param {DOMRect} rect - Panel bounds. + * + * @returns {boolean} - Is cursor located on UI panel? + */ export function isCursorWithinPanelBounds(x, y, rect) { return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom; } - From 8e5b1c674cbe8008435b5f54748bf9532f05e056 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Syn=C3=A1=C4=8Dek?= Date: Sun, 30 Mar 2025 13:43:23 +0200 Subject: [PATCH 5/5] 0.1.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2e7180b..935b4c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "sdraw", - "version": "0.1.2", + "version": "0.1.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sdraw", - "version": "0.1.2", + "version": "0.1.3", "license": "MIT", "devDependencies": { "eslint": "^8.52.0", diff --git a/package.json b/package.json index d351db6..a2eef95 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sdraw", - "version": "0.1.2", + "version": "0.1.3", "description": "Simple drawing application for kids, can be controlled via mouse, keyboard or gamepad.", "private": true, "main": "index.mjs",