Public
Edited
Oct 9, 2023
Paused
Importers
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
noiseImage(createSimplexNoise(Object.assign({ rand }, params)), {
scale: scaleParms.scaleName,
thresholds: scaleParms.thresholds,
width: 800,
height: 600
})
Insert cell
snoiseModule = import(
"https://unpkg.com/simplex-noise@4.0.1/dist/esm/simplex-noise.js?module"
)
Insert cell
import { perlin2, perlin3, octave } from "@mbostock/perlin-noise"
Insert cell
mutable randomSeed = 0
Insert cell
{
randomize;
mutable randomSeed++;
}
Insert cell
rand = d3.randomLcg(randomSeed)
Insert cell
function createSimplexNoise(options = {}) {
const {
xScaleLog = -5,
yScaleLog = -5,
octaves = 3,
random = rand
} = options;
const xScale = 2 ** xScaleLog;
const yScale = 2 ** yScaleLog;
const noise = octave(snoiseModule.createNoise2D(random), octaves);
return (x, y) => noise(x * xScale, y * yScale);
}
Insert cell
scales = {
let obj = {};
for (let name of [...Object.keys(d3)].filter((s) => {
if (s.slice(0, 11) != "interpolate") return false;
try {
const result = d3[s](0);
if (result.slice(0, 3) == "rgb" || result[0] == "#") return true;
} catch (e) {}
return false;
})) {
obj[name.slice(11)] = d3[name];
}
return obj;
}
Insert cell
function makeThresholdScale(scale, thresholdCount = 2) {
const delta = 1 / (thresholdCount + 1);
const domain = d3.range(thresholdCount).map((i) => (i + 1) * delta);
const range = d3
.range(thresholdCount + 1)
.map((i) => scale((i + 0.5) * delta));
return d3.scaleThreshold(domain, range);
}
Insert cell
makeThresholdScale(scales.Greys, 3)
Insert cell
function makeColorArray(scale) {
let array = new Uint8Array(3 * 256);
for (let i = 0; i < 256; i++) {
let color = d3.color(scale(i / 255));
array[i * 3] = color.r;
array[i * 3 + 1] = color.g;
array[i * 3 + 2] = color.b;
}
return array;
}
Insert cell
function noiseImage(noise, options = {}) {
const {
height = 400,
width = 400,
scale = "Greys",
thresholds = 0
} = options;
let scaleFunction = d3.scaleSequential(scales[scale]).domain([0, 1]);
if (thresholds > 0)
scaleFunction = makeThresholdScale(scaleFunction, thresholds);
const colorArray = makeColorArray(scaleFunction);
const context = DOM.context2d(width, height, 1);
const image = context.createImageData(width, height);
for (let y = 0, i = 0; y < height; ++y) {
for (let x = 0; x < width; ++x, i += 4) {
const j = ~~Math.max(0, Math.min(255, (noise(x, y) + 1) * 128)) * 3;
image.data[i] = colorArray[j];
image.data[i + 1] = colorArray[j + 1];
image.data[i + 2] = colorArray[j + 2];
image.data[i + 3] = 255;
}
}
context.putImageData(image, 0, 0);
return context.canvas;
}
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