<svg viewBox="0 0 20 20" id="surface">
<g id="circle">
<path class="north">
<animate
attributeName="d"
dur="3"
keyTimes="0;0.1;0.4;0.6;0.9;1"
repeatCount="indefinite"
values="
M 10 10
q 0.3536 -0.3536 0.7071 -0.7071
q -0.3 -0.2929 -0.7071 -0.2929
q -0.4 0 -0.7071 0.2929
q 0.3536 0.3536 0.7071 0.7071;
M 10 10
q 0.3536 -0.3536 0.7071 -0.7071
q -0.3 -0.2929 -0.7071 -0.2929
q -0.4 0 -0.7071 0.2929
q 0.3536 0.3536 0.7071 0.7071;
M 10 8.75
q 0.4 0 0.7071 -0.2929
q -0.3536 -0.3536 -0.7071 -0.7071
q -0.3536 0.3536 -0.7071 0.7071
q 0.3 0.2929 0.7071 0.2929;
M 10 8.75
q 0.4 0 0.7071 -0.2929
q -0.3536 -0.3536 -0.7071 -0.7071
q -0.3536 0.3536 -0.7071 0.7071
q 0.3 0.2929 0.7071 0.2929;
M 10 10
q 0.3536 -0.3536 0.7071 -0.7071
q -0.3 -0.2929 -0.7071 -0.2929
q -0.4 0 -0.7071 0.2929
q 0.3536 0.3536 0.7071 0.7071;
M 10 10
q 0.3536 -0.3536 0.7071 -0.7071
q -0.3 -0.2929 -0.7071 -0.2929
q -0.4 0 -0.7071 0.2929
q 0.3536 0.3536 0.7071 0.7071
">
</path>
<path class="east">
<animate
attributeName="d"
dur="3"
keyTimes="0;0.1;0.4;0.6;0.9;1"
repeatCount="indefinite"
values="
M 10 10
q 0.3536 -0.3536 0.7071 -0.7071
q 0.2929 0.3 0.2929 0.7071
q 0 0.4 -0.2929 0.7071
q -0.3536 -0.3536 -0.7071 -0.7071;
M 10 10
q 0.3536 -0.3536 0.7071 -0.7071
q 0.2929 0.3 0.2929 0.7071
q 0 0.4 -0.2929 0.7071
q -0.3536 -0.3536 -0.7071 -0.7071;
M 11.25 10
q 0 -0.4 0.2929 -0.7071
q 0.3536 0.3536 0.7071 0.7071
q -0.3536 0.3536 -0.7071 0.7071
q -0.2929 -0.3 -0.2929 -0.7071;
M 11.25 10
q 0 -0.4 0.2929 -0.7071
q 0.3536 0.3536 0.7071 0.7071
q -0.3536 0.3536 -0.7071 0.7071
q -0.2929 -0.3 -0.2929 -0.7071;
M 10 10
q 0.3536 -0.3536 0.7071 -0.7071
q 0.2929 0.3 0.2929 0.7071
q 0 0.4 -0.2929 0.7071
q -0.3536 -0.3536 -0.7071 -0.7071;
M 10 10
q 0.3536 -0.3536 0.7071 -0.7071
q 0.2929 0.3 0.2929 0.7071
q 0 0.4 -0.2929 0.7071
q -0.3536 -0.3536 -0.7071 -0.7071
">
</path>
<path class="south">
<animate
attributeName="d"
dur="3"
keyTimes="0;0.1;0.4;0.6;0.9;1"
repeatCount="indefinite"
values="
M 10 10
q -0.3536 0.3536 -0.7071 0.7071
q 0.3 0.2929 0.7071 0.2929
q 0.4 0 0.7071 -0.2929
q -0.3536 -0.3536 -0.7071 -0.7071;
M 10 10
q -0.3536 0.3536 -0.7071 0.7071
q 0.3 0.2929 0.7071 0.2929
q 0.4 0 0.7071 -0.2929
q -0.3536 -0.3536 -0.7071 -0.7071;
M 10 11.25
q -0.4 0 -0.7071 0.2929
q 0.3536 0.3536 0.7071 0.7071
q 0.3536 -0.3536 0.7071 -0.7071
q -0.3 -0.2929 -0.7071 -0.2929;
M 10 11.25
q -0.4 0 -0.7071 0.2929
q 0.3536 0.3536 0.7071 0.7071
q 0.3536 -0.3536 0.7071 -0.7071
q -0.3 -0.2929 -0.7071 -0.2929;
M 10 10
q -0.3536 0.3536 -0.7071 0.7071
q 0.3 0.2929 0.7071 0.2929
q 0.4 0 0.7071 -0.2929
q -0.3536 -0.3536 -0.7071 -0.7071;
M 10 10
q -0.3536 0.3536 -0.7071 0.7071
q 0.3 0.2929 0.7071 0.2929
q 0.4 0 0.7071 -0.2929
q -0.3536 -0.3536 -0.7071 -0.7071
">
</path>
<path class="west">
<animate
attributeName="d"
dur="3"
keyTimes="0;0.1;0.4;0.6;0.9;1"
repeatCount="indefinite"
values="
M 10 10
q -0.3536 0.3536 -0.7071 0.7071
q -0.2929 -0.3 -0.2929 -0.7071
q 0 -0.4 0.2929 -0.7071
q 0.3536 0.3536 0.7071 0.7071;
M 10 10
q -0.3536 0.3536 -0.7071 0.7071
q -0.2929 -0.3 -0.2929 -0.7071
q 0 -0.4 0.2929 -0.7071
q 0.3536 0.3536 0.7071 0.7071;
M 8.75 10
q 0 0.4 -0.2929 0.7071
q -0.3536 -0.3536 -0.7071 -0.7071
q 0.3536 -0.3536 0.7071 -0.7071
q 0.2929 0.3 0.2929 0.7071;
M 8.75 10
q 0 0.4 -0.2929 0.7071
q -0.3536 -0.3536 -0.7071 -0.7071
q 0.3536 -0.3536 0.7071 -0.7071
q 0.2929 0.3 0.2929 0.7071;
M 10 10
q -0.3536 0.3536 -0.7071 0.7071
q -0.2929 -0.3 -0.2929 -0.7071
q 0 -0.4 0.2929 -0.7071
q 0.3536 0.3536 0.7071 0.7071;
M 10 10
q -0.3536 0.3536 -0.7071 0.7071
q -0.2929 -0.3 -0.2929 -0.7071
q 0 -0.4 0.2929 -0.7071
q 0.3536 0.3536 0.7071 0.7071
">
</path>
</g>
</svg>
<p>a re-creation of this amazing <a href="http://beesandbombs.tumblr.com/post/101579804084/quarters">Bees and Bombs gif</a></p>
<small><p>2 the haters: this is just for fun, won't work in IE because SMIL isn't supported there</p></small>
xxxxxxxxxx
svg {
width: 500px;
height: 500px;
}
body {
padding: 20px;
text-align: center;
}
a {
color: #000;
}
xxxxxxxxxx
var originRe = /M(\s*)[0-9.]*[\s,][0-9.]*/;
var surface = document.getElementById('surface');
var circle = document.getElementById('circle');
var waveOffset = 0.1;
var gridScale = 2.25;
var numRings = 5;
/* generate diagonal grid points in n concentric rings */
function makeGrid(n){
//make an array of n empty arrays
var coords = [];
while(coords.push([]) <= n);
for (var x = -n; x <= n; x++){
for (var y = -n; y <=n; y++){
if ((x + y)%2 === 0){
var ringIndex = (Math.abs(x) + Math.abs(y))/2;
coords[ringIndex].push([x*gridScale,y*gridScale]);
}
}
}
return coords;
}
/* takes seimclon separated path list, amount to translate in x and y
returns the same list with the M coordiates translated by a certain amount */
function translatePaths(paths, dx, dy){
return paths.split(';').map(function(path){
var origin = originRe.exec(path)[0].split(" ");
origin[1] = Number(origin[1]) + dx;
origin[2] = Number(origin[2]) + dy;
return path.replace(originRe, origin.join(" "));
}).join(";");
}
/* take a circle elem and clone it but placed at a new location and with an animation start offset */
function cloneCircle(circle, dx, dy, animOffset){
var clone = circle.cloneNode(true);
var quads = clone.childNodes;
for (var i=0; i < quads.length; i++){
/* eliminate text only nodes, because .children ain't working on mobile
and .childNodes gets all sorts of garbage */
if (quads[i].nodeType === 1){
var paths = quads[i].childNodes[1].getAttribute('values');
quads[i].childNodes[1].setAttribute('values', translatePaths(paths, dx, dy));
quads[i].childNodes[1].setAttribute('begin', animOffset);
}
}
surface.appendChild(clone);
}
//make a grid
var gridCoords = makeGrid(numRings);
//then generate the waaaves:
//start at 1. 0 is trivial, it's the original circle
for (var i = 1; i < gridCoords.length; i++){
gridCoords[i].forEach(function(pos){
cloneCircle(circle, pos[0], pos[1], waveOffset*i );
});
}