<svg
viewBox="0 0 1000 1000"
width="1000"
height="1000"
role="img"
>
<title>
A geometric pattern composed of nested circles and squiggly lines.
Inspired by Legends of Zelda: Tears of the Kingdom
</title>
<text text-anchor="middle" y="500" x="500" style="font-size: 2em; font-family: sans-serif;">Tap anywhere on the SVG canvas to add circle groups</text>
<g class="pattern">
<!--
Our graphics code goes here
-->
</g>
</svg>
html, body {
display: grid;
place-items: center;
min-height: 100%;
background-color: #eee;
}
svg {
background: #fff;
max-width: 90vw;
max-height: 90vh;
width: auto;
height: auto;
}
.filled-circle {
fill: #fff;
}
.stroked-circle {
fill: none;
stroke: #999;
stroke-width: 10;
}
import { randomInt } from 'https://unpkg.com/randomness-helpers@0.0.1/dist/index.js';
function circle({ x, y, r, className }) {
return `
<circle
cx="${x}"
cy="${y}"
r="${r}"
class="${className}"
/>
`;
}
function circleGroup({x, y, r }) {
// We'll store all our circles in an array.
const circles = [];
// First, draw a circle with a white background but no border.
// This will hide any elements behind the circle.
circles.push(circle({ x, y, r, className: 'filled-circle' }));
// Decide how much space to put between our circles.
const gap = 20;
// Draw a number of circles, making each one smaller than the last
// until we hit a radius of 0.
let circleSize = r;
while(circleSize > 0) {
circles.push(circle({ x, y, r: circleSize, className: 'stroked-circle' }));
circleSize -= gap;
}
// Return all our circles as a single string;
return circles.join('');
}
const patternEl = document.querySelector('.pattern');
const svgEl = document.querySelector('svg');
svgEl.addEventListener('click', (e) => {
const { x, y } = getClickOnSvg(e);
patternEl.innerHTML += circleGroup({
x,
y,
r: randomInt(100, 400),
});
});
function getClickOnSvg(e) {
let pt = DOMPoint.fromPoint(svgEl);
pt.x = e.clientX;
pt.y = e.clientY;
// The cursor point, translated into svg coordinates
return pt.matrixTransform(svgEl.getScreenCTM().inverse());
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.