<i style="--x:300px;--y:180px"></i>

<div class="panel">
<div>Duration of a1: <input type="range" min="0" max="4" step="0.2" value="1" name="Da1"></div>
<div>Duration of a2: <input type="range" min="0" max="4" step="0.2" value="2" name="Da2"></div>
<div>Duration of d1: <input type="range" min="0" max="4" step="0.2" value="1" name="Dd1"></div>
<div>Duration of d2: <input type="range" min="0" max="4" step="0.2" value="4" name="Dd2"></div></div>

<button> Run the animation</button>

<div class="debug"></div>
@property --a1 {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}
@property --a2 {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}
@property --d1 {
  syntax: '<length>';
  inherits: false;
  initial-value: 0px;
}
@property --d2 {
  syntax: '<length>';
  inherits: false;
  initial-value: 0px;
}

i{
  position:fixed;
  width:50px;
  height:50px;
  border-radius:50%;
  background:radial-gradient(at 30% 30%,#0000,#000a) red;
  left:var(--x);
  top: var(--y);
  transform:rotate(var(--a1)) translate(var(--d1)) rotate(var(--a2)) translate(var(--d2));
}
.start i {
  animation: a1 var(--da1,1s), a2 var(--da2,2s), d1 var(--dd1,1s),d2 var(--dd2,4s);
  animation-timing-function:cubic-bezier(.5,-900,.5,900);
  animation-iteration-count:infinite;
}

@keyframes a1 { to { --a1:0.5deg; } }
@keyframes a2 { to { --a2:0.5deg } }
@keyframes d1 { to { --d1:0.5px } }
@keyframes d2 { to { --d2:0.5px } }



/**/
d {position:fixed;height:4px;width:4px;background:#222;border-radius:50%}
button {border:none;border-radius:10px;padding:10px 20px;cursor:pointer;position:fixed;bottom:20px;right:20px;font-family:sans-serif;font-size:30px;background:#c82629;color:#fff;}
.panel {position: fixed;top: 20px;right: 20px;padding: 10px;border: 1px solid;border-radius: 10px;background: #0001;font-family: sans-serif;}
.panel > div:not(:last-child) {border-bottom: 1px solid;padding-bottom: 10px;margin-bottom: 10px;}
let elem = document.querySelector('i');
let start;

function debug(timestamp) {
  if (start === undefined)
    start = timestamp;
  const elapsed = timestamp - start;
  let rect = elem.getBoundingClientRect();
  document.querySelector('.debug').insertAdjacentHTML("afterbegin",'<d style="top:'+(rect.y + rect.height/2)+'px;left:'+(rect.x + rect.width/2)+'px;"></d>')

  if (elapsed < 30000) { 
    window.requestAnimationFrame(debug);
  }
}

function clear() {
	document.querySelector('.debug').innerHTML="&nbsp;";
  start=undefined;
  window.requestAnimationFrame(debug);
}


document.querySelector('[name=Da1]').addEventListener('change', function() {
  elem.style.setProperty("--da1", this.value+"s");
  clear()
});
document.querySelector('[name=Da2]').addEventListener('change', function() {
  elem.style.setProperty("--da2", this.value+"s");
  clear()
});
document.querySelector('[name=Dd1]').addEventListener('change', function() {
  elem.style.setProperty("--dd1", this.value+"s");
  clear()
});
document.querySelector('[name=Dd2]').addEventListener('change', function() {
  elem.style.setProperty("--dd2", this.value+"s");
  clear()
});

document.querySelector("button").addEventListener("click",function() {
  document.body.classList.add("start");
  window.requestAnimationFrame(debug);
})

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.