<div id="result"></div>
<div class="content">
<button id="regen">Regenerate</button>
</div>
<div class="filler"></div>
$bg: #a497c5;
body {
display: grid;
grid-template-rows: 1fr auto auto 1fr;
min-height: 100vh;
background: $bg;
color: #2e2c40;
font-size: 24px;
}
#result {
grid-row: 2;
}
svg {
display: block;
}
.content {
background: currentColor;
grid-row: 3;
padding-top: 4rem;
text-align: center;
}
#regen {
background: $bg;
border: 2px solid transparent;
border-radius: .25rem;
color: inherit;
cursor: pointer;
display: inline-block;
font-family: sans-serif;
font-weight: 900;
padding: 0.5rem 2rem;
text-align: center;
text-decoration: none;
text-transform: uppercase;
}
.filler {
background: currentColor;
grid-row: 4;
}
View Compiled
const WIDTH = 1000
const HEIGHT = 100
const MIN_SEGMENT = 1
const MAX_SEGMENT = 50
const ROUGHNESS = 0.8
generate()
document.getElementById('regen').addEventListener('click', generate)
async function generate() {
const dividerSvg = await divider('')
document.getElementById('result').innerHTML = dividerSvg
}
// mountain divider
async function divider(classes) {
const points = line(WIDTH, HEIGHT, MIN_SEGMENT, MAX_SEGMENT)
const path = convertPath(WIDTH, HEIGHT, points)
const svg = genSvg(WIDTH, HEIGHT, path)
return `
<div class="b-divider ${classes}" role="img" aria-hidden="true">
${svg}
</div>
`
}
// generate midpoint displacement points
function displaceMap(height, displace, roughness, power) {
const points = []
// set initial left point
points[0] = height / 2 + (Math.random() * displace * 2) - displace
// set initial right point
points[power] = height / 2 + (Math.random() * displace * 2) - displace
displace *= roughness
// increase number of segments to maximum
for (let i = 1; i < power; i *= 2) {
// for each segment, find centre point
for (let j = (power / i) / 2; j < power; j += power / i) {
points[j] = ((points[j - (power / i) / 2] + points[j + (power / i) / 2]) / 2)
points[j] += (Math.random() * displace * 2) - displace
}
// reduce random range
displace *= roughness
}
return points
}
// format points in [x, y] array
function line(width, height, minSegment, maxSegment) {
let i = 0
let points = []
while (i < width) {
points.push([
i,
Math.round(Math.random() * height)
])
i = i + Math.random() * (maxSegment - minSegment) + minSegment
}
points.push([
width,
Math.round(Math.random() * height)
])
return points
}
// convert points into SVG path
function convertPath(width, height, points) {
// add first M (move) command
const first = points.shift()
let path = `M ${first[0]} ${first[1]}`
// iterate through points adding L (line) commands to path
points.forEach(val => {
path += ` L ${val[0]} ${val[1]}`
})
// close path
path += ` L ${width} ${height} L 0 ${height} Z`
return path
}
// generate SVG from path
function genSvg(width, height, path) {
return `
<svg viewBox="0 0 ${width} ${height}" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
<path fill="currentColor" d="${path}"></path>
</svg>
`
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.