JSFiddle - React, Tailwind, and code Playground
by Andrey Bazykin
HTML
<div class="ellipse ellipse-1"></div>
<div class="ellipse ellipse-2" data-rotate="30deg"></div>
<div class="ellipse ellipse-3" data-rotate="60deg*"></div>
CSS
body{
margin:20px;
}
.ellipse{
display:inline-block;
position:relative;
width:200px;
height:300px;
margin:30px;
background:#f0f0f0;
}
.ellipse .inner{
content:"";
position:absolute;
top:0;
right:0;
bottom:0;
left:0;
border:2px solid #666;
border-radius:100px/150px;
}
.ellipse .dot{
position:absolute;
width:20px;
height:20px;
margin:-10px 0 0 -10px;
border-radius:100%;
background:#000;
transform-origin:50% 50%;
}
.ellipse:hover .dot{
background:#f00;
}
JavaScript
$(function () {
$('.ellipse').each(function () {
var $item = $(this),
$inner = $('<div class="inner">').appendTo($item),
$dot = $('<div class="dot">').appendTo($item),
dims = {
W: this.clientWidth,
H: this.clientHeight
},
center = {
X: dims.W / 2,
Y: dims.H / 2
},
ratio = dims.W / dims.H,
rotate = $item.data('rotate'),
angle = 0,
start = 0,
time = [20, 5],
interval = time[0],
process;
$item
.on('mouseenter', function () {
interval = time[1];
})
.on('mouseleave', function () {
interval = time[0];
})
.on('mousedown', function () {
clearTimeout(process);
})
.on('mouseup', function () {
animation();
});
if (rotate) {
rotate = rotate.split('*');
if (rotate[1] !== undefined) {
angle = Math.PI * parseInt(rotate[0]) / 180;
$inner.css({
transform: 'rotateZ(' + rotate[0] + ')'
});
} else {
$item.css({
transform: 'rotateZ(' + rotate[0] + ')'
});
}
}
animation();
function animation() {
var x = center.X * Math.sin(start),
y = center.Y * Math.cos(start),
X = x * Math.cos(angle) - y * Math.sin(angle),
Y = x * Math.sin(angle) + y * Math.cos(angle);
$dot.css({
top: center.Y + Y,
left: center.X + X
});
start += .02;
process = setTimeout(animation, interval);
}
});
});