Public
Edited
Nov 21, 2024
4 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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;
}
Insert cell
pickImageFile.width
Insert cell
colorPickFileReactivity
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
import { vec2, lr, lr4, fourPoint } from "@esperanc/lane-riesenfeld-subdivision"
Insert cell
import {
viewof newPickImageFile,
viewof fourColorSelect,
colorPickFileReactivity,
mutable pickImageFile
} from "@esperanc/image-color-picker"
Insert cell
Insert cell
Insert cell
loadSvg = {
mutable svgtext = await svgFile.text();
}
Insert cell
mutable svgtext = await FileAttachment("testimg@2.svg").text()
Insert cell
testimg = html`${svgtext}`
Insert cell
Insert cell
mutable color_order = d3.range(7)
Insert cell
set_testimg_palette = {
let color = {};
let n = palette.length;
let pal = [...palette];
let i = 0;
for (let c of imgclasses) {
color[c] = pal[color_order[i]];
i = (i + 1) % n;
}
d3.select(testimg)
.selectAll("path")
.each(function () {
let path = d3.select(this);
path.style("fill", color[path.attr("class")]);
//console.log(path.attr("class"), path.attr("fill"));
});
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more