◆ composite オプションがあったけどブラウザが未対応
◆ div を多重に重ねて別レイヤでアニメーション
  ◆ 合成可能数を増やすと div のネストが多すぎて devtools で確認不可能に

ボタンを押すと要素を 1 回転させたいです
回転途中にもう一回押すとすでに回転中のと新しい回転をあわせて少し早く回転させたいです

一見簡単そうなのですが CSS や JavaScript の animation 系ってキーフレームの指定なので新しくアニメーションさせると前回のがリセットされてしまいます
WebAnimation ならプロパティ変更やメソッドで実行中のアニメーションを操作できないのかなと調べたのですが duration や 100% 時点のキーフレームを置き換えるような機能はみつけれませんでした

今実行中のアニメーションを停止して 新しいアニメーションを行うことを考えましたが アニメーション中の今の状態がわかりません
style プロパティを見ても途中段階は反映されませんし getComputedStyle を使うと角度じゃなくて matrix とかでてきます
そこから角度を計算したとしても 360 と 720 の違い(何周目か)は取得できなそうです
開始時刻と現在時刻から進行率を出して from と to に当てはめて計算すれば出せそうですけどそこまでしないとだめなの?って思うほどです
単純に新しいキーフレームだけ指定すれば今のところから始まらないかなと思って試しても「partial keyframes are not supported.」と言われます

オプションなどを探してみると composite といういかにもそれっぽいのがありました
composite に accumulate を指定すればリセットせずに複数のアニメーションが合成されるようです
早速試したのですが 動きませんでした
現状ブラウザが対応してないみたいです

ブラウザが対応してない以上仕方ないので 無理やり合成させる方法を取ることにしました
div を多重にして別のレイヤを動かせば見た目的には合成されたアニメーションになります
div がいっぱいあるのがあんまり気がすすまないのですが 考えなくていいようにコンポーネントに押し込みます

最大 128 個まで合成できます
1 回転が 6 秒間なので 6 秒以内に 129 回 SPIN ボタンを押せばおかしくなりますが 人がマウスで押してる以上 そんなに押せないよね ということで 128 重までにしてます
div が多すぎて devtools で途中から確認できなくなります
スクロールバー出せばいいのですけどね

<!DOCTYPE html>

<script>
customElements.define("spin-elem", class extends HTMLElement {
constructor() {
super()
this.max_level = 128
this.duration = 6000
this.attachShadow({ mode: "open" })
}

connectedCallback() {
this.shadowRoot.innerHTML = `
${
[...Array(this.max_level)].map((e, i) => `<div id="l${i}">`).join("")
}<slot></slot>${
"</div>".repeat(this.max_level)
}
`
this.idx = 0
}

spin() {
const idx = this.idx
this.idx = (this.idx + 1) % this.max_level
const elem = this.shadowRoot.getElementById("l" + idx)
const anim = elem.animate([
{ transform: "rotate(0deg)" },
{ transform: "rotate(360deg)" },
], {
duration: this.duration,
easing: "ease",
}
)
}
})
</script>

<style>
spin-elem {
width: 48px;
height: 48px;
line-height: 48px;
font-size: 32px;
border: 1px solid gray;
border-radius: 50%;
display: block;
text-align: center;
margin: 30px;
overflow: hidden;
}
</style>

<spin-elem id="se">A</spin-elem>
<button onclick="se.spin()">SPIN</button>