viewof palette = {
const width = 500,
height = 500;
const ctx = DOM.context2d(width, height, 1);
let imgData = ctx.getImageData(0, 0, width, height);
const setImgData = () => {
const colors = rgb.value;
if (gradientType == "3 colors") {
colorInterpolationImgDataTriangle(
imgData,
colors.c3,
colors.c4,
colors.c1,
mode.value
);
} else if (gradientType == "4 colors") {
colorInterpolationImgData(
imgData,
colors.c1,
colors.c2,
colors.c3,
colors.c4,
mode.value
);
} else {
ctx.drawImage(pickImageFile, 0, 0, width, height);
imgData = ctx.getImageData(0, 0, width, height);
}
};
setImgData();
let vertices = [
[width * 0.1, height * 0.9],
[width * 0.9, height * 0.9],
[width * 0.5, height * 0.1]
];
let points;
const container = htl.html`<div>`;
Object.assign(container.style, {
maxWidth: width + "px",
background: "gray",
padding: "10px"
});
container.append(ctx.canvas);
container.value = null;
const drawImageData = () => ctx.putImageData(imgData, 0, 0);
ctx.canvas.drawImageData = drawImageData;
const drawInteractionWidgets = () => {
ctx.strokeStyle = "black";
ctx.setLineDash([8, 8]);
ctx.lineWidth = 1;
ctx.beginPath();
for (let p of points.slice(0, 3)) ctx.lineTo(...p);
ctx.closePath();
ctx.stroke();
for (let [i, j] of [
[0, 4],
[1, 5],
[2, 6]
]) {
ctx.beginPath();
ctx.lineTo(...points[i]);
ctx.lineTo(...points[j]);
ctx.stroke();
}
ctx.setLineDash([]);
for (let p of points.slice(0, 4)) {
ctx.fillStyle = "white";
ctx.beginPath();
ctx.arc(...p, 4, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = "black";
ctx.beginPath();
ctx.arc(...p, 3, 0, Math.PI * 2);
ctx.fill();
}
const palette = [];
for (let [x, y] of points) {
ctx.strokeStyle = "white";
ctx.lineWidth = 2;
ctx.beginPath();
ctx.arc(x, y, 8, 0, Math.PI * 2);
ctx.stroke();
const index = (Math.round(x) + Math.round(y) * width) * 4;
let [r, g, b] = imgData.data.slice(index, index + 3);
palette.push(`rgb(${r},${g},${b})`);
}
container.value = palette;
};
ctx.canvas.drawInteractionWidgets = drawInteractionWidgets;
const change = (ctx, pts) => {
points = pts;
drawImageData();
drawInteractionWidgets();
container.dispatchEvent(new Event("input", { bubbles: true }));
};
triangleInteraction(ctx, vertices, change);
const gradientChangeCallback = () => {
setImgData();
change(ctx, points);
};
rgb.addEventListener("input", gradientChangeCallback);
mode.addEventListener("input", gradientChangeCallback);
const curveParmCallback = () => {
change(ctx, points);
};
return container;
}