|
const canvasSketch = require("canvas-sketch"); |
|
const SimplexNoise = require("simplex-noise"); |
|
|
|
const s = new SimplexNoise(); |
|
|
|
// Sketch parameters |
|
const settings = { |
|
dimensions: "A4", |
|
orientation: "portrait", |
|
pixelsPerInch: 300, |
|
scaleToView: true, |
|
units: "cm" |
|
}; |
|
|
|
// Artwork function |
|
function sketch() { |
|
return function({ context, width, height }) { |
|
// Margin in inches |
|
const margin = 1.5; |
|
|
|
// Off-white background |
|
context.fillStyle = "rgb(255, 0, 255)"; |
|
context.fillRect(0, 0, width, height); |
|
context.strokeStyle = "hsl(0, 0%, 98%)"; |
|
|
|
const steps = 50; |
|
const numLines = 100; |
|
|
|
const availableHeight = height - 2 * margin; |
|
const availableWidth = width - 2 * margin; |
|
|
|
const x0 = margin; |
|
const y0 = margin + availableHeight / 4; |
|
const stepY = (0.75 * availableHeight) / (numLines - 1); |
|
const stepX = availableWidth / (steps - 1); |
|
const centerX = width / 2; |
|
|
|
context.lineWidth = 0.05; |
|
|
|
for (let j = 0; j < numLines; j++) { |
|
let y = y0 + j * stepY; |
|
|
|
context.beginPath(); |
|
|
|
for (let i = 0; i < steps; i++) { |
|
let x = x0 + i * stepX; |
|
|
|
let normalizedDist = normalize( |
|
Math.abs(centerX - x), |
|
0, |
|
availableWidth / 2 |
|
); |
|
|
|
let invertedDist = 1 - normalizedDist; |
|
let factor = invertedDist ** 2; |
|
|
|
context.lineTo( |
|
x, |
|
y - 2.5 * factor * Math.abs(noiseOctaves(x / 25, y / 25, 6, 0.5)) |
|
); |
|
} |
|
context.stroke(); |
|
} |
|
}; |
|
} |
|
|
|
// Start the sketch |
|
canvasSketch(sketch, settings); |
|
|
|
// Helperfunctions |
|
function normalize(v, min, max) { |
|
return (v - min) / (max - min); |
|
} |
|
|
|
function noiseOctaves(x, y, numOctaves, persistence) { |
|
let maxValue = 0; |
|
let total = 0; |
|
|
|
let frequency = 4; |
|
let amplitude = 128; |
|
|
|
for (let i = 0; i < numOctaves; i++) { |
|
total += s.noise2D(x * frequency, y * frequency) * amplitude; |
|
|
|
maxValue += amplitude; |
|
|
|
frequency *= 2; |
|
amplitude *= persistence; |
|
} |
|
|
|
return total / maxValue; |
|
} |