Skip to content

Instantly share code, notes, and snippets.

@vwochnik
Last active August 13, 2021 15:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vwochnik/5eb9983f9a4a5403c9413cfb16119b4d to your computer and use it in GitHub Desktop.
Save vwochnik/5eb9983f9a4a5403c9413cfb16119b4d to your computer and use it in GitHub Desktop.
Snap.SVG background shapes
license: mit
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Snap.SVG Shapes</title>
<style>
body { margin: 0; background: #212428 }
#shapes { position: fixed; left: 0; top: 0; width: 100%; height: 100%; }
</style>
</head>
<body>
<svg id="shapes"></svg>
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.5.1/snap.svg.js"></script>
<script src="shapes.js" ></script>
</body>
</html>
(function(window, Snap, mina) {
'use strict';
const WIDTH = 1000, HEIGHT = 1000;
/* shapes, each (-100 < x,y < 100) */
const SHAPE_PATHS = [
"M0,59.172702727031975A59.172702727031975,59.172702727031975 0 1,1 0,-59.172702727031975A59.172702727031975,59.172702727031975 0 1,1 0,59.172702727031975Z",
"M-70.35623639735145,-23.45207879911715H-23.45207879911715V-70.35623639735145H23.45207879911715V-23.45207879911715H70.35623639735145V23.45207879911715H23.45207879911715V70.35623639735145H-23.45207879911715V23.45207879911715H-70.35623639735145Z",
"M0,-97.60266103764192L56.35092262370636,0 0,97.60266103764192 -56.35092262370636,0Z",
"M-52.44044240850758,-52.44044240850758L52.44044240850758,-52.44044240850758 52.44044240850758,52.44044240850758 -52.44044240850758,52.44044240850758Z",
"M0,69.01550348156863L79.69223902668242,-69.01550348156863 -79.69223902668242,-69.01550348156863Z",
"M0,-69.01550348156863L79.69223902668242,69.01550348156863 -79.69223902668242,69.01550348156863Z"
];
const SHAPE_COLORS = [
'hsl(0, 100%, 50%)',
'hsl(16%, 100%, 50%)',
'hsl(33%, 100%, 50%)',
'hsl(49%, 100%, 50%)',
'hsl(66%, 100%, 50%)',
'hsl(82%, 100%, 50%)',
];
var MAX_SHAPES = 25;
var paper, shapesGroup, shapeFilter, shapes = 0;
function createShapeFilter() {
const filter = paper.filter(`
<feGaussianBlur in="SourceGraphic" stdDeviation="9" result="blurred"></feGaussianBlur>
<feMerge>
<feMergeNode in="blurred" />
<feMergeNode in="SourceGraphic"/>
</feMerge>
`);
filter.attr({ x: '-50%', y: '-50%', width: '200%', height: '200%' });
return filter;
}
function matrix(a, size) {
var offset = a * (2 * WIDTH + 2 * HEIGHT),
mtx = Snap.matrix();
if (offset < WIDTH) {
mtx.translate(offset, -100*size);
} else {
offset -= WIDTH;
if (offset < HEIGHT) {
mtx.translate(WIDTH+100*size, offset);
} else {
offset -= HEIGHT;
if (offset < WIDTH) {
mtx.translate(WIDTH - offset, HEIGHT+100*size);
} else {
offset -= WIDTH;
mtx.translate(-100*size, HEIGHT - offset);
}
}
}
mtx.scale(size);
return mtx;
}
function randomAttributes(r) {
var opacity = 0.3 + (0.7 * r),
size = 0.0008 * (WIDTH + HEIGHT) * (1.0 - opacity);
return {
transform: matrix(r, size),
strokeWidth: 8/Math.pow(1+size, 3),
opacity: 1//opacity
};
}
function spawn() {
var shape = Math.floor(SHAPE_PATHS.length * Math.random());
const r0 = Math.random(),
r1 = Math.random();
var element = shapesGroup.path(SHAPE_PATHS[shape]);
element.attr(randomAttributes(r0));
element.attr({
fill: 'none',
stroke: SHAPE_COLORS[shape],
filter: shapeFilter
});
shapes++;
element.animate(randomAttributes(r1), 1000+10000*r1, function() {
element.remove();
shapes--;
fillShapes();
});
}
function fillShapes() {
while (shapes < MAX_SHAPES) {
spawn();
}
}
paper = Snap("#shapes");
paper.attr({
viewBox: `0 0 ${WIDTH} ${HEIGHT}`,
preserveAspectRatio: "xMidYMid slice"
});
shapeFilter = createShapeFilter();
shapesGroup = paper.group();
fillShapes();
})(window, Snap, mina);
@vwochnik
Copy link
Author

use viewport for relative sizing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment