function pickColorFromImage(
img,
{ height = 256, callback = null, color = "red" } = {}
) {
const aspect = img.width / img.height;
const width = height * aspect;
const div = htl.html`<div>`;
Object.assign(div.style, {
height: `${height}px`,
width: `${width}px`,
display: "flex",
flexDirection: "row"
});
const canvas = htl.html`<canvas width=${width} height=${height}>`;
Object.assign(canvas.style, {
flex: 1
});
const samplePane = htl.html`<div>`;
Object.assign(samplePane.style, {
maxWidth: "80px",
maxHeight: "80px",
display: "flex",
flexDirection: "column",
paddingLeft: "10px",
flex: 2
});
const sample = htl.html`<div>`;
Object.assign(sample.style, {
maxWidth: "40px",
minWidth: "40px",
minHeight: "40px",
maxHeight: "40px",
background: color,
border: "1px solid gray",
flex: 1
});
const colorName = htl.html`<span>${color}`;
Object.assign(colorName.style, {
maxWidth: "20em",
paddingTop: "10px",
font: "10pt sans-serif",
flex: 2
});
samplePane.append(sample, colorName);
const ctx = canvas.getContext("2d");
canvas.onmousemove = (evt) => {
const [x, y] = [evt.offsetX, evt.offsetY];
if (x < 0 || y < 0 || x >= width || y >= height) return;
const myImageData = ctx.getImageData(x, y, 1, 1);
const d = myImageData.data;
const color = `rgb(${d[0]},${d[1]},${d[2]})`;
sample.style.background = color;
colorName.innerHTML = color;
};
canvas.onmousedown = (evt) => {
canvas.onmousemove(evt);
let hexColor = d3.color(colorName.innerHTML).hex();
div.value = hexColor;
div.dispatchEvent(new CustomEvent("input"));
if (callback) callback(colorName.innerHTML);
};
ctx.drawImage(img, 0, 0, width, height);
div.append(canvas, samplePane);
div.setCallback = (cb) => {
callback = cb;
if (callback) {
canvas.style.cursor = "pointer";
} else {
canvas.style.cursor = "default";
}
};
div.setCallback(callback);
div.value = d3.color(color).hex();
return div;
}