Last active
August 27, 2020 21:05
-
-
Save adrsch/4a0d302754e3e11ed7a21823dc7d6dd6 to your computer and use it in GitHub Desktop.
Generate distorted grid SVG
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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

