JSFiddle - React, Tailwind, and code Playground
HTML
<html>
<body>
<canvas width="1000" height="1000" id="canvas"></canvas>
</body>
</html>
JavaScript
// Convert SVG to Canvas and setup hover behavior
function svgToCanvasWithHover(svgString) {
// Create an image from the SVG string
var svg = new Blob([svgString], {
type: "image/svg+xml;charset=utf-8"
});
var url = URL.createObjectURL(svg);
var img = new Image();
img.addEventListener('load', e => {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.drawImage(e.target, 0, 0);
URL.revokeObjectURL(url);
const originalImageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const floodFillData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const floodFill = (x, y, newColor) => {
const stack = [[x, y]];
const { data, width } = floodFillData;
// Get the color at the starting pixel
const startIdx = (y * width + x) * 4;
const startColor = [data[startIdx], data[startIdx + 1], data[startIdx + 2], data[startIdx + 3]];
// Check if the color matches
const matchColor = (idx) => {
return (
data[idx] === startColor[0] &&
data[idx + 1] === startColor[1] &&
data[idx + 2] === startColor[2] &&
data[idx + 3] === startColor[3]
);
};
while (stack.length > 0) {
const [cx, cy] = stack.pop();
const idx = (cy * width + cx) * 4;
if (!matchColor(idx)) continue;
// Fill the pixel with the new color
data[idx] = newColor[0];
data[idx + 1] = newColor[1];
data[idx + 2] = newColor[2];
data[idx + 3] = newColor[3];
// Add neighboring pixels to the stack
if (cx > 0) stack.push([cx - 1, cy]);
if (cx < width - 1) stack.push([cx + 1, cy]);
if (cy > 0) stack.push([cx, cy - 1]);
...