<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
<style>
body {
display: flex;
margin: 0;
height: 100vh
}
svg { flex: 1 }
</style>
</HEAD>
<BODY>
<svg viewBox="-2000 -1000 4000 2000">
<style>
svg { background: #000 }rect, [r], #m { fill: #fff }</style>
<radialGradient id="r">
<stop stop-color="#ff0" offset=".32"></stop>
<stop stop-color="#fa0" offset=".83"></stop>
<stop stop-color="#fa0" offset=".91"></stop>
<stop stop-color="#000" offset=".95"></stop>
</radialGradient>
<filter id="f">
<feGaussianBlur in="SourceGraphic" stdDeviation="8"></feGaussianBlur>
</filter>
<mask id="m">
<path d="M500 170c200 340 820 340 780 -290c-200 0 -600 -60 -780 290" filter="url(#f)"></path>
</mask>
<g id="g" mask="url(#m)" filter="url(#f)">
<rect width="2000" height="2000"></rect>
<ellipse cx="930" cy="-70" rx="420" ry="500" fill="url(#r)"></ellipse>
<ellipse cx="950" cy="-20" rx="200" ry="260" transform="rotate(-9 950 -20)"></ellipse>
<circle cx="860" cy="-20" r="14"></circle>
</g>
<use xlink:href="#g" transform="scale(-1 1)"></use>
</svg>
<script>
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
var _P = document.querySelector('#m path'),
NF = 30;
var ends = void 0,
pts = void 0,
curr = void 0,
dir = 1,
rID = null,
cf = 0,
m = void 0;
function getAbsData(el) {
var d = el.getAttribute('d').split('M').slice(1)[0].split('c').map(function (c) {
return c.split(' ').map(function (c) {
return +c;
});
}).map(function (b) {
return b.reduce(function (a, c, i) {
return i % 2 ? a.concat([[b[i - 1], c]]) : a;
}, []);
});
var _loop = function _loop(i) {
var lastPrev = d[i - 1].slice(-1)[0];
d[i] = d[i].map(function (c) {
return c.map(function (k, j) {
return lastPrev[j] + k;
});
});
};
for (var i = 1; i < d.length; i++) {
_loop(i);
}
return d;
};
function stopAni() {
cancelAnimationFrame(rID);
rID = null;
};
function tfn(k) {
return Math.pow(.5 * (Math.sin((k - .5) * Math.PI) + 1), 3);
};
function update() {
cf += dir;
var k = tfn(cf / NF);
curr = ends[0].map(function (c, i) {
return c.map(function (c, j) {
return Math.round(k * c + (1 - k) * ends[1][i][j]);
});
}).reverse();
_P.setAttribute('d', 'M' + pts[0][0] + '\n\t\t C' + [[].concat(_toConsumableArray(ends[0]), [pts[1][2]]), [].concat(_toConsumableArray(curr), [pts[0][0]])]);
if (!(cf % NF)) {
dir *= -1;
}
rID = requestAnimationFrame(update);
};
(function init() {
pts = getAbsData(_P);
ends = [].concat(_toConsumableArray(pts)).slice(1).map(function (c) {
return c.slice(0, -1);
}).map(function (c, i) {
return i % 2 ? c.reverse() : c;
});
curr = ends[1];
update();
})();
</script>
</BODY>
</HTML>