- Web制作
- sin()、cos()を、CSSアニメーションとJavaScriptで動かした時の違い
sin()、cos()を、CSSアニメーションとJavaScriptで動かした時の違い

CSS上の三角関数、sin()、cos()を動かすため、CSSアニメーションを使ってみたのですが、きちんと動きませんでした。もう少し正確にいうと、動くには動いたが、想定通りには動かなかったという感じです。
いろいろと原因を考えてみて、おそらくこういった理由なんじゃないかと思い、それをまとめてみました。とはいっても、レンダリングレベルまで見ている訳ではないので、間違っていたらゴメンナサイ。
オブジェクトを楕円形に動かすサンプル
まずは、こちらのページで、サンプルを確認してください。
sin()、cos()を、CSSアニメーションとJavaScriptで動かした時の違い
あと、こちらが動作のスクリーンショットになります。

今回は、二つのサンプルを用意したのですが、上の方がCSSの三角関数をCSSのanimationで動かしているもの。下の方がCSSの三角関数をJavaScriptで動かしているものです。
本当は、両方とも楕円の動きをさせたかったのですが、CSSの方は菱形の動きになっています。その理由について、確認したいと思います。
コードの確認
使用しているHTMLについて、こちらが、CSSアニメーション版のもの(抜粋)になります。
<style>
.circle {
width: 600px;
height: 300px;
position: relative;
background-color: aliceblue;
margin: 30px auto;
display: flex;
justify-content: center;
align-items: center;
}
.css-circle {
width: 30px;
height: 30px;
border-radius: 9999px;
background-color: rgb(147, 147, 12);
animation: loop 5s linear infinite;
}
@keyframes loop {
0% {
transform: translate(calc(cos(0deg) * 260px), calc(sin(0deg) * 120px * -1));
}
25% {
transform: translate(calc(cos(90deg) * 260px), calc(sin(90deg) * 120px * -1));
}
50% {
transform: translate(calc(cos(180deg) * 260px), calc(sin(180deg) * 120px * -1));
}
75% {
transform: translate(calc(cos(270deg) * 260px), calc(sin(270deg) * 120px * -1));
}
100% {
transform: translate(calc(cos(360deg) * 260px), calc(sin(360deg) * 120px * -1));
}
}
</style>
<div class="circle">
<div class="css-circle"></div>
</div>
そして、こちらがJavaScriptで動かしているコード(抜粋)になります。
<style>
.circle {
width: 600px;
height: 300px;
position: relative;
background-color: aliceblue;
margin: 30px auto;
display: flex;
justify-content: center;
align-items: center;
}
.js-circle {
width: 30px;
height: 30px;
border-radius: 9999px;
background-color: rgb(208, 72, 174);
}
</style>
<script>
window.onload = function () {
let circle = document.querySelector('.js-circle');
let degree = 0;
let circleAnimation = function () {
circle.style.transform = "translate( calc( cos(" + degree + "deg) * 260px ) ,
calc( sin(" +
degree +
"deg) * 120px * -1) )";
if (degree > 358) {
degree = 0;
} else {
degree = degree + 3;
}
}
setInterval(circleAnimation, 30);
}
</script>
<div class="circle">
<div class="js-circle"></div>
</div>
どうやって動かしているか
CSS版
次に、どのようにして動かしているかという部分について、CSS版の方から確認していきます。
まず、円の親となるタグを設定し、円をflexを使って中心部に配置します。そして、positionを併用して、表示位置を変更しているのですが、その値を決める際に、三角関数を用いています。
あとは、CSSアニメーションを使って、三角関数の角度部分を増やしています。
JavaScript版
一方、JavaScript版はというと、基本の配置はCSS版と同じなのですが、positionで位置を変更する際に、角度をJavaScriptを用いて加算しています。三角関数の角度が、都度上書きされています。
あと、繰り返し処理を行う際に、setIntervalを用いて繰り返し処理をしています。JavaScriptの繰り返しには、「requestAnimationFrame()」もありますが、繰り返しのスピードを調整することができません。ですので、今回のサンプルでは、setIntervalを用いてます。
CSS版は、三角関数を計算してから代入している?
そして、CSS版が想定通り動かなかった理由ですが、おそらく三角関数を設定した際に、CSSが『あらかじめ数値を計算してしまう=角度を変化させるのではなく計算した数値を変化させている』ためだと思います。

CSSの三角関数の今後
今回、CSSの三角関数を使ったサンプルを作ってみました。CSSで三角関数が使えるのは、確かにありがたいのですが、簡単にアニメーションを実装できるという訳ではないので、今の時点では使い所を見つけるのが難しいです。
もし、『CSSの三角関数ならでは』というのが登場すれば別ですが、そうでなければ、あまり登場の出番はなさそうな気がします。