CSS 観覧車のように動かしてみる

2020-07-06

サイトにアクセントを持たせるために、アニメーションを用いるケースがありますが、今回は、観覧車のように要素が周っていくアニメーションについてまとめたいと思います。
方法としては、JSのスクリプトを利用して表現する方法と、CSSアニメーションを利用して表現する方法があります。
JSは『Jquery Interactive Animated Menu』を利用する方法がありますが、結構いろんなサイトで紹介されているので、今回はCSSアニメーションで表現する方法を紹介していきたいと思います。


完成イメージ

今回は、全体的に長くなりそうなので、最初にどのような動きになるかを表示してみます。

01
02
03
04
05
06
07
08

と、完成形は、このような形になり、観覧車が動いているように見せることができます。
各要素は、わかりやすいように、番号だけにしていますが、この部分を画像に置き換えたりすれば、より観覧車に見せることができます。
それでは、下記に解説を書いていきたいと思います。


回す要素の数は、一応、いくつでも大丈夫かと思いますが、360度を割り切れる数がおすすめです。


基本的に、CSSだけなので、レスポンシブ対応となります。
正方形となるようにスペースを確保するために、大枠となっている部分には、以前、掲載した手法を応用しています。 (詳しくはこちら

大きすぎてもスペースを取るだけなので、今回は、80%幅の正方形となるようにしました。
また、中の要素を回転させると、回転する角度によっては、大きくはみ出すため、overflow:hidden;ではみ出してしまう部分は隠すようにしています。
このページのように余白がある場合は、特に問題ありませんが、スマホなどで、横幅いっぱいに設計していたりすると、横に余白が出たり、消えたりとします。
背景にある大きい丸は、:beforeの擬似要素で、円を作って配置しているだけなので、実は回転していません。


解説

.rotateで、大枠の確保している正方形のスペースの中心に配置するようになり、その中の.rotate-ctnが常に回転するアニメーションを記述しています。.rotateはなくても問題ないかもしれませんが、中央に文字を配置したい時など、有効になってくるかと思います。
今回のサンプルは、100sで一周する記述になります。

.boxは、回転する大枠(大円)の半径のサイズに高さをとり、中央下を起点に、等間隔になるように回転をしています。
left: 50%; transform: translate(-50%, 0);とすることで、大円の中心を基点とすることができます。
widthだけは、pxで指定しているので、サイズによって、変えたほうがいいと思います。
アニメーションさせずに、配置してみるとわかりますが、このままの状態では、文字の部分も回転しているので、個別にさらに回転をさせる必要があります。

.parts01
.parts02
.parts03
.parts04
.parts05
.parts06
.parts07
.parts08

というように、枠線は.box、数字が入っているグレー背景の部分(.parts)も回転していることがわかります。
そのため、まず、この状態で、文字が正常に見えるように、個別で角度をつけておく必要があります。

さらに、この個別に角度をつけた分をズラした状態から、1周するアニメーションをスタートさせることで、最初のような観覧車のような動きにすることができます。
この時、注意しなければいけないのは、大円が1周する時間と、個別の.partsが回転する時間は同じにしておかないと、文字の方だけが斜めになっていったりします。

もしかしたら、keyframesは大円用と小円用だけを用意して、delayなどで回転するタイミングをずらして、スッキリさせる方法があるのかもしれませんが、思い浮かびませんでした。
とりあえず、この方法であれば、角度の部分は、360度をpartsの個数で割った数値を当てはめればいいので、これはこれでいいのかとも思っています。
あとは、javascriptで計算して、動的に対応するなどの方法もあるかもしれませんので、試行錯誤してみてください。


ちょっと応用編

今回、観覧車のような動きを取り入れたサイトをとある案件で制作したのですが、中心から広がるような動きはなかったので、作ってみました。一応、レスポンシブですが、広がるタイミングなどはjavascriptで制御になります。

クリック!
01
02
03
04
05
06
07
08


.boxまでは同じですが、小円の部分は、transitionopacityで動きを追加している感じです。
ただ、個別にしている回転とは別に動作するように、divを追加しています。
translateを調整すれば、中心からではなく、外側から集まってくる動きとかもできると思います。そういった表現が必要かどうかは、わかりませんが。。。