Created for the February 2019 CodePen Challenge
A Pen by Kevin LEVRON on CodePen.
<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); | |
} | |
} |
Created for the February 2019 CodePen Challenge
A Pen by Kevin LEVRON on CodePen.