Good Evening, I'm working on a project where I need to create MSPaint clone, with one little functionality more. It must have a function that works almost like fill (bucket) but filling area matching pixels with diagonal lines (picture below) instead of filling all of them.
Here is codepen: https://codepen.io/Kamskyy/pen/eYrRxRB
Below is my working function code for filling - how can I modify it to draw diagonal lines instead?
function actionFill(startX,startY,currentColor) {
//get imageData
let colorLayer = offScreenCTX.getImageData(0, 0, offScreenCVS.width, offScreenCVS.height);
let startPos = (startY*offScreenCVS.width + startX) * 4;
//clicked color
let startR = colorLayer.data[startPos];
let startG = colorLayer.data[startPos+1];
let startB = colorLayer.data[startPos+2];
let startA = colorLayer.data[startPos+3];
//exit if color is the same
if (currentColor.r === startR && currentColor.g === startG && currentColor.b === startB && currentColor.a === startA) {
return;
}
//Start with click coords
let pixelStack = [[startX,startY]];
let newPos, x, y, pixelPos, reachLeft, reachRight;
floodFill();
function floodFill() {
newPos = pixelStack.pop();
x = newPos[0];
y = newPos[1];
//get current pixel position
pixelPos = (y*offScreenCVS.width + x) * 4;
// Go up as long as the color matches and are inside the canvas
while(y >= 0 && matchStartColor(pixelPos)) {
y--;
pixelPos -= offScreenCVS.width * 4;
}
//Don't overextend
pixelPos += offScreenCVS.width * 4;
y++;
reachLeft = false;
reachRight = false;
// Go down as long as the color matches and in inside the canvas
while(y < offScreenCVS.height && matchStartColor(pixelPos)) {
colorPixel(pixelPos);
if(x > 0) {
if(matchStartColor(pixelPos - 4)) {
if(!reachLeft) {
//Add pixel to stack
pixelStack.push([x - 1, y]);
reachLeft = true;
}
} else if(reachLeft) {
reachLeft = false;
}
}
if(x < offScreenCVS.width-1) {
if(matchStartColor(pixelPos + 4)) {
if(!reachRight) {
//Add pixel to stack
pixelStack.push([x + 1, y]);
reachRight = true;
}
} else if(reachRight) {
reachRight = false;
}
}
y++;
pixelPos += offScreenCVS.width * 4;
}
if (pixelStack.length) {
floodFill();
// window.setTimeout(floodFill, 100);
}
}
//render floodFill result
offScreenCTX.putImageData(colorLayer, 0, 0);
//helpers
function matchStartColor(pixelPos) {
let r = colorLayer.data[pixelPos];
let g = colorLayer.data[pixelPos+1];
let b = colorLayer.data[pixelPos+2];
let a = colorLayer.data[pixelPos+3];
return (r === startR && g === startG && b === startB && a === startA);
}
function colorPixel(pixelPos) {
colorLayer.data[pixelPos] = currentColor.r;
colorLayer.data[pixelPos+1] = currentColor.g;
colorLayer.data[pixelPos+2] = currentColor.b;
//not ideal
colorLayer.data[pixelPos+3] = currentColor.a;
}
}
