Published
Edited
Mar 31, 2021
Insert cell
md`# Simplex noise`
Insert cell
function saturate(x) {
return Math.max(0, Math.min(1, x));
}
Insert cell
function hue(h) {
const r = Math.abs(h * 6 - 3) - 1;
const g = 2 - Math.abs(h * 6 - 2);
const b = 2 - Math.abs(h * 6 - 4);
return [saturate(r), saturate(g), saturate(b)];
}
Insert cell
SimplexNoise = (await import("https://jspm.dev/npm:simplex-noise")).default;
Insert cell
simplexNoise = new SimplexNoise(42);
Insert cell
noiseScale = 0.05;
Insert cell
renderer.canvas
Insert cell
function frag(u, v) {
const noise = Math.random();
const fun = 1*Math.tan(u) + 1*Math.tan(v); // u/v+v/u +
const i = (fun)/3 + noise/3;
const val = i*255;//Math.abs(i - Math.trunc(i));
//return [...hue(val).map(x => (x*255%255)), 255];//[255, val, val, val];
const nval = Math.abs(val % 255);
return [nval, nval, nval, 255];
}

Insert cell
canvasWidth=800;
Insert cell
canvasHeight=400;
Insert cell
renderer = {
const w = canvasWidth;
const h = canvasHeight;
const context = DOM.context2d(w, h, 1);
context.canvas.style.imageRendering = "pixelated";

const imageData = new ImageDataUint32(context.getImageData(0, 0, w, h));
function render(transform) {
for (let i = 0; i < h; i++) {
for (let j = 0; j < w; j++) {
imageData.setPixelArr(
j, i,
frag((j - transform.x) / transform.k,
(i - transform.y) / transform.k));
}
}
context.putImageData(imageData, 0, 0);
}

render({x: 0, y: 0, k: 1});
return {
context,
canvas: context.canvas,
render,
};
}
Insert cell
class ImageDataUint32 extends ImageData {
constructor(imageData) {
super(imageData.data, imageData.width, imageData.height);
this.dataUint32 = new Uint32Array(this.data.buffer);
}

setPixel(x, y, abgr) {
this.dataUint32[y * this.width + x] = abgr;
}

setPixelArr(x, y, [r, g, b, a]) {
const i = 4 * (y * this.width + x);
this.data[i + 0] = r;
this.data[i + 1] = g;
this.data[i + 2] = b;
this.data[i + 3] = a;
}
}

Insert cell
{
d3.select(renderer.canvas).call(
d3.zoom()
.on("zoom", ({transform}) => renderer.render(transform)));
return md`Adding pan-n-zoom`;
}
Insert cell
d3 = require("d3@6")

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