Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 65 additions & 16 deletions js/canvas-utils.mjs
Original file line number Diff line number Diff line change
@@ -1,33 +1,82 @@
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 CURSOR_SIZE = 20;
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);
const half = CURSOR_SIZE / 2;

ctx.lineWidth = 5;
ctx.lineWidth = LINE_WIDTH;
ctx.lineCap = "round";
ctx.strokeStyle = COLOR.BLACK;
ctx.strokeStyle = getPixelRGBAColor(x, y);

/* --- 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();
}
12 changes: 12 additions & 0 deletions js/ui-utils.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +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?
*/
export function isCursorWithinPanelBounds(x, y, rect) {
return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom;
}
5 changes: 1 addition & 4 deletions js/ui/panel.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down