JSFiddle - React, Tailwind, and code Playground
by schrodingers
HTML
<canvas id="c"></canvas>
CSS
body {
display: flex;
justify-content: center;
overflow: hidden;
}
canvas {
margin: 0 50%;
/* width: 100%; */
/* height: 100%; */
}
JavaScript
/*Локсодромия*/
var circles = [{
color: '#21a5ad',
size: 84,
angle: Math.PI / 3
}, {
color: '#ffad10',
size: 92,
angle: -Math.PI / 3
}, {
color: '#ef4239',
size: 100,
angle: 0
}];
var segmentsPerCircle = 200;
var speed = .9;
function twistEasing(t) {
return (t < .5) ? 2 * t * t : 1 - 2 * (t = 1 - t) * t;
}
var c = document.getElementById('c');
c.width = window.innerWidth;
c.height = window.innerHeight;
var ctx = c.getContext('2d');
Math.PI2 = 2 * Math.PI;
function rotateX(p, a) {
var d = Math.sqrt(p[2] * p[2] + p[1] * p[1]),
na = Math.atan2(p[1], p[2]) + a;
return [p[0], d * Math.sin(na), d * Math.cos(na)];
}
function rotateY(p, a) {
var d = Math.sqrt(p[2] * p[2] + p[0] * p[0]),
na = Math.atan2(p[2], p[0]) + a;
return [d * Math.cos(na), p[1], d * Math.sin(na)];
}
function rotateZ(p, a) {
var d = Math.sqrt(p[1] * p[1] + p[0] * p[0]),
na = Math.atan2(p[1], p[0]) + a;
return [d * Math.cos(na), d * Math.sin(na), p[2]];
}
function resize() {
c.width = c.offsetWidth;
c.height = c.offsetHeight;
ctx.translate(c.width * .5, c.height * .5);
ctx.lineWidth = 5;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
}
window.addEventListener('resize', resize);
resize();
var angleOffset = 0;
var angleOffsetGoal = 0;
c.addEventListener('mousemove', function(e) {
angleOffsetGoal = Math.PI2 * (e.clientX / c.width - .5);
});
c.addEventListener('mouseout', function(e) {
angleOffsetGoal = 0;
});
function loxo(radius, angle, segments) {
var r = [];
for (var i = 0; i < segments; i++) {
var a = Math.PI2 * i / segments,
c = Math.cos(a),
s = Math.sin(a);
var ax = Math.PI * .5;
ax -= (c + 1) * .5 * angle;
r.push([radius * c, radius * s * Math.sin(ax), radius * s * Math.cos(ax)]);
}
return r;
}
function loop() {
requestAnimationFrame(loop);
angleOffset += (angleOffsetGoal - angleOffset) * .1;
ctx.clearRect(-c.width * .5, -c.height * .5, c.width, c.height);
var t = Date.now() * 1e-3 *...