I'm trying to have a user manually color in certain parts of an image. As an example, here's a cat https://techflourish.com/images/3-cat-clipart-9.png. The user should be able to color in the foot of the cat if they choose to. I want them to only color inside the cat body image portion of the canvas (not the background portion of the image or whitespace of canvas, but I guess I could just manually trim the image).
What I've attempted so far is below. Basically I check the color of the pixel at my position and draw only if it isn't that background color. This sort of works, but I'm able to bleed out really easily because something is off. I was wondering if it was possibly to set a specific clip area, but wasn't able to figure it out.
`
var canvas = document.getElementById("space");
var ctx = canvas.getContext("2d");
var pos = { x: 0, y: 0 };
// new position from mouse events
function setPosition(e) {
pos.x = e.clientX;
pos.y = e.clientY;
}
function rgbToHex(r, g, b) {
if (r > 255 || g > 255 || b > 255)
throw "Invalid color component";
return ((r << 16) | (g << 8) | b).toString(16);
}
function draw(e) {
if (e.buttons !== 1) return; // if mouse is pressed.....
var color = "#cb3594";
ctx.beginPath(); // begin the drawing path
ctx.lineWidth = 5; // width of line
ctx.lineCap = "round"; // rounded end cap
ctx.strokeStyle = color; // hex color of line
var p = ctx.getImageData(pos.x, pos.y, 1, 1).data;
var sourceColor = rgbToHex(p[0], p[1], p[2]);
if(sourceColor != "BACKGROUNDHEX" && sourceColor != color) {
ctx.moveTo(pos.x, pos.y); // from position
setPosition(e);
p = ctx.getImageData(pos.x, pos.y, 1, 1).data;
targetColor = rgbToHex(p[0], p[1], p[2]);
if(targetColor != "BACKGROUNDHEX" && targetColor != color) {
ctx.lineTo(pos.x, pos.y); // to position
ctx.stroke(); // draw it!
}
}
}
var outlineImage = new Image();
outlineImage.onload = function() {
ctx.drawImage(outlineImage, 0, 0, 704, 720);
}
outlineImage.src = "IMAGE.png";
space.addEventListener("mousemove", draw);
space.addEventListener("mousedown", setPosition);
space.addEventListener("mouseenter", setPosition);
</script>
`
(related edit: the bleeding is caused by my "sourceColor != color" being wrong, but the question is still relevant as this still doesn't feel like a great solution)