前の記事の続き。
前の記事では落下運動をCSS Animationで実現する方法の説明。
今回の記事では円運動をCSS Animationで実現する方法の説明。
円運動
ぐるぐるまわりますよーという動きです(Rotateではなく)。
通常、ぐるぐる移動させようとした場合はこんな感じだと思う。
X座標 = 中心座標.x + sin(角度) × 半径;
Y座標 = 中心座標.y + cos(角度) × 半径;
しかしCSSではsin, cosが使えない……どころかそもそも四則演算もおぼつかないような状態で;´Д`)calc関数ってネストできないんだね。Edgeでは。
CSS Animationで円運動
sin, cosが使えないならどうするか。easeで似たような感じにすれば動くでしょうということで;´Д`)
ちなみに円運動させてみたのがこちら。
だいたい円運動
うむ、だいたいそれっぽく見えていると思う;´Д`)ただ、iPhoneで表示した場合にタイミングによっては楕円になったり斜めの直線運動になったりする。そんなときはブラウザの更新ボタン(再読み込みボタン?)を押すか1回出てまた入りなおしてもらえれば;´Д`)
2016/10/09 追記
ちょっと修正。移動速度を若干ゆっくりめにしたのと、ページ表示後5秒待つようにしてみた。
本来はJavaScriptでページ情報読み込み完了イベントを貰ったタイミングで処理開始するべきなんだろうけど、JavaScriptが使えないので……。手元のiPhoneでは正常に表示されるようになったがどうだろう。 2016/10/08 追記
ちょっとiPhoneから確認したところ、結構大幅に動きがずれる場合がありますね。どうも画面上に動作が重い広告が出ていると表示異常が顕著に表れるように見えます。動作が重い広告というのは画面上でわざとらしく3Dっぽい変形をするやつですが…単純な動作に見えるがめちゃくちゃ複雑な計算でもやっているのだろうか…。
というわけでまた概要を説明します。
- sin, cosをease-in-outで近似
sinはease-in-outをそのまま使う。
cosはsinが90度ずれた値と一致する。それをY軸に適用することになるからX軸に適用するease-in-outの半分の時間遅らせて実行する。 - sin波の0~180度までをkeyframeで、残りをalternateで
これは前回記事の放物線と同じ理由。 - X軸, Y軸にそれぞれのease-in-outを適用
;´Д`)<ワイはここで詰まってしまった。CSS Animationは同じ種類(属性?)のプロパティに対して、別々のkeyframeを割り当てたりはできないからだ。例えば "keyframe1はtranslateX", "keyframe2はtranslateY" と分けて実行しても、最後に実行したkeyframeが優先されてしまう。
結局どうしたかというと、回転させる要素をdivでラップして、"ラップ側にはX軸用keyframe","表示要素にはY軸用keyframe"という感じで回避した;´Д`)メンドイケド
円運動はこれくらいかな。単純だしね。
実際の実装はこちら。
<style>
.moveBase {
position: absolute;
left:0; top:0;
width:3px; height:3px;
background-color:transparent;
animation:
cercleaniX 0.6s ease-in-out 0s infinite alternate;
}
@keyframes cercleaniX {
0%{transform:translateX(90px);}
100%{transform: translateX( 10px);}
}
.moveCercle {
position: absolute;
left:0; top:0; right:0; bottom:0;
background-color:blue;
border-radius:50%;
animation:
cercleaniY 0.6s ease-in-out 0.3s infinite alternate;
}
@keyframes cercleaniY {
0%{transform:translateY(90px);}
100%{transform: translateY( 10px);}
}
</style>
<div style="position:relative;width:100px;height:100px;border:1px solid black;">
<div class="moveBase" style="animation-delay:calc(0s + 0.00s);"><div class="moveCercle" style="animation-delay:calc(0.3s + 0.00s);background-color:rgba(242, 133, 45, 1);"> </div></div>
<div class="moveBase" style="animation-delay:calc(0s + 0.03s);"><div class="moveCercle" style="animation-delay:calc(0.3s + 0.03s);background-color:rgba(242, 133, 45, 0.6);"> </div></div>
<div class="moveBase" style="animation-delay:calc(0s + 0.06s);"><div class="moveCercle" style="animation-delay:calc(0.3s + 0.06s);background-color:rgba(242, 133, 45, 0.3);"> </div></div>
<p>だいたい円運動</p>
</div>
いやちょっとまてよ…?
この記事を読み直して気付いてしまった。
もしかして、中点をずらしてrotateZすれば円運動できるんじゃないのか!?
そうだ、そういえば過去にどこかでそんな記事を読んだ記憶があるぞ;´Д`)< rotateZで表示要素の内容も回転してしまうが、表示要素をdivでラップして円運動用rotateZ, 逆回転用rotateZに分ければ表示問題も解決するとか書いてあったな……。
……。
いや、まあこっちの方法にはこっちの方法のメリットがあるし!
ease-in-outの値をもっと極端にすれば角丸正方形型に移動したりだってできるしノД`)、ツカイミチ ナイケド
もしこの記事を最後まで読んだ方がおられるなら、この件は反面教師としてこんな余計なことを考えないようにする、というのがこの記事の最も正しい読み方だと思われますノД`)、