Skip to content

Instantly share code, notes, and snippets.

@wanghaooo
Created February 27, 2019 06:49
Show Gist options
  • Save wanghaooo/d42f8c41bd5413602b320a33d6e40a9b to your computer and use it in GitHub Desktop.
Save wanghaooo/d42f8c41bd5413602b320a33d6e40a9b to your computer and use it in GitHub Desktop.
SVG polygon flowers
<svg id="svg"></svg>
let width, height, cx, cy;
let svg = document.getElementById('svg');
function init() {
onResize();
window.addEventListener('resize', onResize, false);
for (let i = 0; i < 100; i++) {
createFlower(Math.floor(4 + rnd(12)), rnd(width), rnd(height), 5 + rnd(10));
}
let mouseDown = false;
document.body.addEventListener('mousedown', e => { mouseDown = true; });
document.body.addEventListener('mouseup', e => { mouseDown = false; });
document.body.addEventListener('mouseleave', e => { mouseDown = false; });
document.body.addEventListener('mousemove', e => {
let size = 5 + rnd(5);
if (mouseDown) size *= 2;
createFlower(Math.floor(4 + rnd(12)), e.clientX + rnd(20, true), e.clientY + rnd(20, true), size);
});
}
function createFlower(nbVertexes, x, y, s) {
let opacity = 0.5 + rnd(0.5);
let group = document.createElementNS('http://www.w3.org/2000/svg', 'g');
group.setAttributeNS(null, 'transform', `translate(${x}, ${y})`);
group.setAttributeNS(null, 'style', `opacity:${opacity};`);
svg.appendChild(group);
let duration = 0.5 + rnd(3);
let innerGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');
innerGroup.setAttributeNS(null, 'class', 'flower');
innerGroup.setAttributeNS(null, 'style', `animation-duration:${duration}s;`);
group.appendChild(innerGroup);
let polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
let fill = randomColor({ format: 'rgb' });
polygon.setAttributeNS(null, 'points', polygonPoints(nbVertexes, 0, 0, s, 0));
polygon.setAttributeNS(null, 'style', `fill:${fill};`);
innerGroup.appendChild(polygon);
const dt = 2 * Math.PI / nbVertexes;
// fill = randomColor({ luminosity: 'light', format: 'rgb' });
for (let i = 0; i < nbVertexes; i++) {
let a = (i + 0.5) * dt;
let r1 = Math.sin(Math.PI / nbVertexes) * s / Math.sin(Math.PI / 3);
let r2 = Math.cos(Math.PI / nbVertexes) * s + Math.cos(Math.PI / 3) * r1;
let tx = Math.cos(a) * r2;
let ty = Math.sin(a) * r2;
polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
polygon.setAttributeNS(null, 'points', polygonPoints(3, tx, ty, r1, a));
polygon.setAttributeNS(null, 'style', `fill:${fill};`);
innerGroup.appendChild(polygon);
}
}
function onResize() {
const r = svg.getBoundingClientRect();
width = r.width;
height = r.height;
cx = width / 2;
cy = height / 2;
}
function ppoints(n, x, y, s, r) {
const dt = 2 * Math.PI / n;
let points = [], t, px, py;
for (let i = 0; i < n; i++) {
t = r + i * dt;
px = x + Math.cos(t) * s;
py = y + Math.sin(t) * s;
points.push([px, py]);
}
return points;
}
function polygonPoints(n, x, y, s, r) {
points = ppoints(n, x, y, s, r);
return points.reduce((acc, point, i, a) => `${acc} ${point[0]},${point[1]}`);
}
function rnd(max, negative) {
return negative ? Math.random() * 2 * max - max : Math.random() * max;
}
init();
<script src="https://cdnjs.cloudflare.com/ajax/libs/randomcolor/0.5.2/randomColor.min.js"></script>
body {
margin: 0;
width: 100%;
height: 100%;
}
#svg {
position: fixed;
width: 100%;
height: 100%;
cursor: pointer;
}
polygon {
stroke: #fff;
stroke-width: 1;
}
.flower {
animation-name: animation;
animation-duration: 1s;
animation-timing-function: ease-out;
}
@keyframes animation {
0% {
opacity: 0;
transform: scale(0.1, 0.1) rotateZ(0);
}
100% {
opacity: 1;
transform: scale(1, 1) rotateZ(360deg);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment