Skip to content

Instantly share code, notes, and snippets.

@adrsch
Last active August 27, 2020 21:05
Show Gist options
  • Select an option

  • Save adrsch/4a0d302754e3e11ed7a21823dc7d6dd6 to your computer and use it in GitHub Desktop.

Select an option

Save adrsch/4a0d302754e3e11ed7a21823dc7d6dd6 to your computer and use it in GitHub Desktop.
Generate distorted grid SVG
// Use svgPath and bezierCommand from https://medium.com/@francoisromain/smooth-a-svg-path-with-cubic-bezier-curves-e37b49d46c74
import { svgPath, bezierCommand } from './svgPath';
import { makeNoise2D } from 'open-simplex-noise';
const chance = require('chance').Chance();
// Creates a grid specified as a list of lines, with each line a list of coordinate pairs
// Each line is made up of points spaced as given
const grid = ({
width,
height,
xSpacing,
ySpacing,
pointSpacing,
}={}) => {
const vertical = [...Array(Math.ceil(height / ySpacing)).keys()]
.map(yNum => yNum * ySpacing)
.map(y =>
[...Array(Math.ceil(width / pointSpacing) + 1).keys()]
.map(xNum => xNum * pointSpacing)
.map(x => [x, y]));
const horizontal = [...Array(Math.ceil(width / xSpacing)).keys()]
.map(xNum => xNum * xSpacing)
.map(x =>
[...Array(Math.ceil(height / pointSpacing) + 1).keys()]
.map(yNum => yNum * pointSpacing)
.map(y => [x, y]));
return [...vertical, ...horizontal];
};
// Two simplex noise generators, for calculating the x and y displacement of each point
const makeDistortion = (scale, intensity) => {
const noise = {
x: makeNoise2D(chance.integer()),
y: makeNoise2D(chance.integer()),
};
return {
x: (x, y) => noise.x(x * scale, y * scale) * intensity,
y: (x, y) => noise.y(x * scale, y * scale) * intensity,
};
};
// Given a list of lines, distort each point in the line
const makeDistort = distortion => lines =>
lines.map(line =>
line.map(([x, y]) => [x + distortion.x(x, y), y + distortion.y(x, y)]));
const distortedGrid = ({
width = 300,
height = 300,
xSpacing = 10,
ySpacing = 10,
pointSpacing = 50,
scale = 0.01,
intensity = 100,
} = {}) => {
const distort = makeDistort(makeDistortion(scale, intensity));
return distort(grid({
width,
height,
xSpacing,
ySpacing,
pointSpacing,
}));
};
const svgStrokeSmoothed = (color, lines) =>
lines.reduce((acc, cur) => acc + svgPath(cur, bezierCommand, color), '');
const svg = (w, h, contents) =>
`<svg xmlns='http://www.w3.org/2000/svg' width='${w}' height='${h}' viewBox='0 0 ${w} ${h}'>${contents.join('')}</svg>`;
const svgDistortedGrid = ({
width,
height,
xSpacing,
ySpacing,
pointSpacing,
scale,
intensity,
color = 'gray',
background = 'black',
} = {}) => {
const backgroundSvg = `<rect x='0' y='0' width='${width}' height='${height}' fill='${background}'/>`;
const gridSvg = svgStrokeSmoothed(
color,
distortedGrid({
width,
height,
xSpacing,
ySpacing,
pointSpacing,
scale,
intensity,
}),
);
return svg(width, height, [backgroundSvg, gridSvg]);
};
export default svgDistortedGrid;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment