JSFiddle - React, Tailwind, and code Playground
by Gwyn Milcote
HTML
<h3>SVG colouring (vanilla JS)</h3>
<p>Select a colour, then fill in shapes. Image output button is at the bottom. Takes 2 clicks, for some reason...
<br><button id='fill-btn'>Fill with colour</button></p>
<div id='palette'>
<div class='swatch' style='background-color:red' data-colour='red'></div>
<div class='swatch' style='background-color:blue' data-colour='blue'></div>
<div class='swatch' style='background-color:#ffcc33' data-colour='#ffcc33'></div>
</div>
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<!-- Created using Krita: https://krita.org -->
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:krita="http://krita.org/namespaces/svg/krita"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
width="600pt"
height="600pt"
viewBox="0 0 144 144">
<defs/>
<path id="shape0" transform="translate(76.68, 118.8)" fill="#6e3de8" fill-rule="evenodd" stroke="#000000" stroke-width="0.1392" stroke-linecap="square" stroke-linejoin="bevel" d="M0 20.28L10.44 23.28L20.76 23.16L17.64 20.4L22.56 22.8L32.64 20.28L40.56 16.2L37.44 14.76L41.64 15.72L44.4 13.92L40.2 13.32L45.48 13.2L48.6 9L54.24 1.68L52.92 0L47.4 1.2L34.32 5.16L22.08 8.88L0 20.28"/><path id="shape1" transform="translate(103.8, 123.36)" fill="#d9c01b" fill-rule="evenodd" stroke="#000000" stroke-width="0.1392" stroke-linecap="square" stroke-linejoin="bevel" d="M2.52 9.6L8.52 9.84L14.16 7.56L21.36 0L15.24 0L7.32 2.16L0.84 7.08L0 10.2L2.52 9.6"/><path id="shape2" transform="translate(106.2, 126.6)" fill="#6158e8" fill-rule="evenodd" stroke="#000000" stroke-width="0.1392" stroke-linecap="square" stroke-linejoin="bevel" d="M0 5.52L5.88 5.4L9 3.36L10.44 0L5.64 0.24L1.2 3L0 5.52"/><path id="shape3" transform="translate(80.04, 88.32)" fill="#a989f8" fill-rule="evenodd" stroke="#000000" stroke-width="0.1392" stroke-linecap="square"...
CSS
svg {
width: 100%;
max-width: 800px;
height: auto;
}
#output-image {
display: none;
}
#output-canvas {
/*display: none;*/
}
#palette {
display: flex;
flex-flow: row wrap;
margin: 20px auto;
}
#palette .swatch {
width: 30px;
height: 30px;
margin: 2px;
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.3);
}
#palette .swatch:hover {
cursor: pointer;
box-shadow: inset 0 0 0 1px #000;
}
#palette .active-swatch {
box-shadow: inset 0 0 0 2px #000;
}
JavaScript
let palette = ["white","red","lightpink","gold","green","blue","skyblue","purple","coral","brown"];
// Generate colour palette.
let html = "";
for(let c of palette){
html += "<div class='swatch' style='background-color:" + c + "' data-colour='" + c + "'></div>";
}
document.getElementById("palette").innerHTML = html;
//$("#palette").html(html);
let paths = document.querySelectorAll("path"),
swatches = document.querySelectorAll(".swatch"),
colour = "gold",
// For output.
svg = document.querySelector("svg"),
img = document.getElementById("output-image"),
canvas = document.getElementById("output-canvas"),
ctx = canvas.getContext("2d");
canvas.width = 800;
canvas.height = 800;
/*
// Select a colour when palette is clicked.
swatches.forEach(function(e){
e.addEventListener("click", function(e){
// Get this swatch's colour data.
colour = e.target.getAttribute("data-colour");
// Highlight this swatch.
swatches.forEach(function(e){
e.classList.remove("active-swatch");
});
e.target.classList.add("active-swatch");
});
});
*/
document.getElementById("palette").onclick = function(e){
colour = e.target.getAttribute("data-colour");
swatches.forEach(function(e){
e.classList.remove("active-swatch");
});
e.target.classList.add("active-swatch");
};
// Fill a path with current colour.
paths.forEach(function(e){
e.addEventListener("click", function(e){
e.target.setAttribute("fill", colour);
});
});
// Fill whole pattern with current colour.
document.getElementById("fill-btn").addEventListener("click", function(){
let msg = "This will fill the whole design with " + colour + ", and lose your progress. Are you sure?";
if(confirm(msg)){
paths.forEach(function(e){
e.setAttribute("fill", colour);
});
}
});
// Get SVG contents, turn into image.
// Then render image contents on a...