<svg id="mySVG" width="340" height="340">
<!-- <circle cx="50%" cy="50%" r="135" fill="none" stroke="#666" stroke-width="1" /> -->
</svg>
body {
background: #f2f2f2;
}
svg {
overflow: visible !important;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
// outline: 1px dotted #666;
animation: rotate 20s linear infinite;
}
path {
stroke: #0D0D0D;
stroke-width: 3px;
fill: none;
}
@keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(-360deg);
}
}
View Compiled
////////////////////////////////////////////
// You can try modifying these params //
////////////////////////////////////////////
var cx = 170; // center x
var cy = 170; // center y
var r = 135; // radius
var wn = 15; // number of waves
var wa = 10; // number of active waves
var wh = 15; // max height of a wave
var duration = 2; // duration of one cycle in seconds
var curviness = 1.5; // kurvatura :)
////////////////////////////////////////////
function segmentToString(x, y) {
return [x.b.toFixed(2), y.b.toFixed(2), x.c.toFixed(2), y.c.toFixed(2), x.d.toFixed(2), y.d.toFixed(2)].join(",");
}
function arrayRotate(arr, count) {
count -= arr.length * Math.floor(count / arr.length)
arr.push.apply(arr, arr.splice(0, count))
return arr
}
function getCurve(phase, inverse) {
inverse = inverse ? -1 : 1;
var step = 1 / Math.ceil(wa/2);
var steps = new Array(wn).fill(0);
for (let i = 0, diff = 0; i < Math.ceil(wa/2); i++) {
diff += step;
steps[i] = Sine.easeInOut.getRatio(diff) * wh;
}
for (let i = wa - 1, diff = 0; i > Math.ceil(wa/2) - 1; i--) {
diff += step;
steps[i] = Sine.easeInOut.getRatio(diff) * wh;
}
var steps = arrayRotate(steps, phase);
var values = [];
steps.forEach((step, i) => {
var a = cx + (r + (i%2 ? -step : step ) * inverse) * Math.cos(2 * Math.PI * (i*2) / (wn*2));
var b = cy + (r + (i%2 ? -step : step ) * inverse) * Math.sin(2 * Math.PI * (i*2) / (wn*2));
var c = cx + r * Math.cos(2 * Math.PI * (i*2 + 1) / (wn*2));
var d = cy + r * Math.sin(2 * Math.PI * (i*2 + 1) / (wn*2));
values.push({x: a, y: b}, {x: c, y: d});
});
values.push(values[0]);
var data = BezierPlugin.bezierThrough(values, curviness);
var d = "M" + data.x[0].a + "," + data.y[0].a + " C" + segmentToString(data.x[0], data.y[0]);
for (var i = 1; i < data.x.length; i++) {
d += "," + segmentToString(data.x[i], data.y[i]);
}
return d;
}
var svgNS = "http://www.w3.org/2000/svg";
var path1 = document.createElementNS(svgNS, "path");
var path2 = document.createElementNS(svgNS, "path");
TweenMax.set(path1, {
attr: {
"d": getCurve(0),
// "stroke": "#f00",
"id": "svg-preloader-wave-1"
}
});
TweenMax.set(path2, {
attr: {
"d": getCurve(0, true),
// "stroke": "#fff",
"id": "svg-preloader-wave-2"
}
});
document.getElementById("mySVG").appendChild(path1);
document.getElementById("mySVG").appendChild(path2);
var phase = 0;
var timeline = new TimelineMax({
repeat: -1
});
for (var i = 0; i < wn; i++) {
phase--;
timeline.to("#svg-preloader-wave-1", (duration / wn), {
attr: {d: getCurve(phase)},
ease: Power0.easeNone
});
timeline.to("#svg-preloader-wave-2", (duration / wn), {
attr: {d: getCurve(phase, true)},
ease: Power0.easeNone
}, "-=" + (duration / wn));
}
View Compiled
This Pen doesn't use any external CSS resources.