CSSアニメーションでカードをくるくる回す

いにしえのテーブルレイアウト時代からWebサイト制作に関わっていた身からすると、表現力豊かになったCSSは楽しい。
楽しいけど、実際さほど使う機会がなかったりする。
たまたま使う機会があったので、忘れないように自分メモ。

#確認環境
+ macOS Catalina(10.15.7)
    + Firefox(90.0.2)
    + Safari(14.1.2)
    + Chrome(92.0.4515.131)
+ Windows10[Parallels Desktop]
    + Chrome(92.0.4515.131)
    + Edge(92.0.902.67)
+ iPhone
    + safari(605.1.15, iOS 14.7.1)
    + safari(604.1, iOS 15.0 beta4)
+ Android
    + Chrome(91.0.4472.120, Android 8.0.0)
    + Chrome(92.0.4515.131, Android 11)

#トランプカードをくるくる回したい
Javascriptを使わずにぐるぐる回したい。
404とかのエラー画面にも使いたいので、理想はエンドレスでぐるんぐるん回って欲しい。

まずは、マウスオーバーでくるんと回るものから試してみる。

##用意するもの
+ トランプカードの表画像
+ トランプカードの裏画像

#トランプカードをくるくる回したい - マウスオーバーで回す
マウスが重なるとカードをくるっと回したい。これは結構簡単。

<p class="codepen" data-height="420" data-default-tab="html,result" data-slug-hash="MWmxYab" data-user="mrd-takahashi" style="height: 420px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/mrd-takahashi/pen/MWmxYab">
  Playing Card Click to Flip</a> by Mari Takahashi (<a href="https://codepen.io/mrd-takahashi">@mrd-takahashi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

##transformプロパティ
```css:CSS
.stage {
    position: relative;
    padding-top: 2rem;
    margin: 0 auto;
    width: 11.25rem;
    height: 20rem;
    transform: rotateZ(10deg);
}
```
水平ではなく、ちょっと斜めにしておきたいので、```transform: rotateZ(10deg);```と指定。
**deg**はdegree(度)の略なので、Z軸に10度傾けています。

|値|2D(X,Y軸)|3D(X,Y,Z軸)|説明|
| :-- | :--: | :--: | :-- |
|translate|○|○|移動|
|rotate|○|○|移動|
|scale|○|○|サイズ|
|skew|○||傾斜|

##transform-style・transitionプロパティ
```css:CSS
.stage_cardImage {
    position: relative;
    transform-style: preserve-3d;
    transition: all 1s ease-in-out;
}
```
###transform-styleプロパティ
初期値は2D(flat)のため、奥行きがある3D(preserve-3d)表現をしたい場合は親要素に追加。
今回はカードの親要素```.stage_cardImage```に**preserve-3d**を指定。

###transitionプロパティ
アニメーション方法を指定する。ショートハンドで書いているのでリスト化。

|プロパティ|説明|値|今回設定|
| :-- | :-- | :-- | :-- | 
|transition-property|変化を適用するプロパティの指定|all=全て適用(初期値)<br>none=適用しない<br>[プロパティ名]=プロパティ名をカンマ区切りで指定 |all|
|transition-duration|1回当たりの時間|[数字]s=秒<br>[数字]ms=ミリ秒|1s|
|transition-timing-function|アニメーションの加減速|別項|ease-in-out|
|transition-delay|開始までの時間|[数字]s=秒<br>[数字]ms=ミリ秒||

##backface-visibilityプロパティとsafari用の対応
```css:CSS
.stage_cardImage div {
    position: absolute;
    width: 100%;
    height: 100%;
    text-align: center;
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
}
```
要素が裏返しになった時、```backface-visibility```で可視(visible)・不可視(hidden)を指定します。
ほとんどのブラウザは対応済みですが、**safariのみプレフィックスが必要**(2021/08/13現在)。
これを追加しないとアニメーションがガタつきます。

参考：["backface-visibility" | Can I use... Support tables for HTML5, CSS3, etc](https://caniuse.com/?search=backface-visibility)

今回は裏面を別に用意しているので```hidden```で不可視にします。

##マウスオーバー時に回すためのtransformプロパティ
```css:CSS
.stage_cardImage_back {
    transform: rotateY( 180deg );
}

.stage_cardImage:hover {
  transform: rotateY( 180deg );
  cursor: pointer;
}
```
マウスオーバーした時に、意図通りにアニメーションさせるために必要な設定。
カードは表からスタートしたいので```.stage_cardImage_back```は**rotateY( 180deg )**にします。
裏からスタートしたい場合は**rotateY( 0deg )**にします。

この辺りは、いろいろ数値変えると面白いものできるかも。

##タッチデバイス(スマホ・タブレット)用の対応
HTML```<div class="stage_cardImage" ontouchstart="">```の**ontouchstart=""**はタッチデバイス(スマホやタブレット)用の対応。
マウスオーバーでアニメーションするので、CSSでは```.stage_cardImage:hover {…}```という記述になっている。当然、タッチデバイスでは無効。
そこで**ontouchstart属性**を指定してあげると、```:hover```や```active```の設定が有効になります。
今回は親要素に設定しましたが、```<body>```タグに追加すればページ全体で有効にできます。
そのため、タッチデバイスでは、カードに触れると回転します。

#トランプカードをくるくる回したい - エンドレスで回す
そもそも404などのエラー画面で使いたいので、勝手にくるくる回っているのが理想。
そのため、CSSをちょっと改造する。
<p class="codepen" data-height="420" data-default-tab="html,result" data-slug-hash="ZEKPEJY" data-user="mrd-takahashi" style="height: 420px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/mrd-takahashi/pen/ZEKPEJY">
  Playing Card CSS Animation</a> by Mari Takahashi (<a href="https://codepen.io/mrd-takahashi">@mrd-takahashi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

##keyframesとanimetion
自動でくるくる回って欲しいので、キーフレームを利用しよう。

```css:CSS
.stage_cardImage {
    animation: animation-cardImage 3s ease-in-out infinite alternate;
}

@keyframes animation-cardImage {
    0%  {transform: rotateY(0deg);}
    100%  {transform: rotateY(360deg);}
}

.stage_cardImage_back {
    transform: rotateY( 180deg );
}
```

###animationプロパティ
ショートハンドで書いているのでリスト化。

|プロパティ|説明|値|今回設定|
| :-- | :-- | :-- | :-- | 
|animation-name|アニメーションの名前|任意|animation-cardImage|
|animation-duration|1回当たりの時間|[数字]s=秒<br>[数字]ms=ミリ秒|3s|
|animation-timing-function|アニメーションの加減速|別項|ease-in-out|
|animation-delay |開始までの時間|[数字]s=秒<br>[数字]ms=ミリ秒||
|animation-iteration-count|繰り返す回数|[数字]=再生回数<br>infinite=無限|infinite|
|animation-direction|アニメーションの向き|normal=同じ方向(初期値)<br>alternate=偶数回は逆方向|alternate|
|animation-fill-mode|開始前と終了後の状態|none=なし(初期値)<br>forwards=元の状態に戻らない(100%)<br>backwards=元の状態に戻る(0%)<br>both=forwardsとbackwardsの両方 ||
|animation-play-state|再生と停止|running=再生(初期値)<br>paused=停止||

#アニメーションの加減速
アニメーションの加減速を設定する値。

|値|説明|cubic-bezier値|
| :-- | :-- | :-- |
|ease|開始と完了を滑らかにする(初期値）|cubic-bezier(0.25, 0.1, 0.25, 1.0)|
|linear|一定|cubic-bezier(0.0, 0.0, 1.0, 1.0)|
|ease-in|ゆっくり始まる|cubic-bezier(0.42, 0, 1.0, 1.0)|
|ease-out|ゆっくり終わる|cubic-bezier(0, 0, 0.58, 1.0)|
|ease-in-out|ゆっくり始まりゆっくり終わる|cubic-bezier(0.42, 0, 0.58, 1.0)|
|cubic-bezier|3次ベジェ曲線のP1とP2を (x1, y1, x2, y2)で数値で指定|

イラレで作図する際、「ベジェ曲線」には非常にお世話になってるんですが、数学の素養が必要な```cubic-bezier```は無視しますwww
無理www

https://qiita.com/PG0721/items/8ff00fed9f92aa66368b

#参考サイト
初学者の場合、いちからCSSを書こうとするとかなり辛い。
一般的なアニメーション実装を参考にしつつ、そこから改造していくほうが理解しやすい。

さらに定着・発展させるには、まとめ記事を書くのが良いと個人的には思います。

##CSSアニメーション
https://qiita.com/soarflat/items/4a302e0cafa21477707f

+ [animation | Can I use... Support tables for HTML5, CSS3, etc](https://caniuse.com/?search=animation)
+ [CSSで、3D空間で回転するカードをつくる | ブランディング、Web戦略、ホームページ制作は東京都品川区五反田のアッタデザイン｜ATTAdesign](https://attadesign.co.jp/blog/795/)
+ [[CSS]コピペで簡単に使える、パネルの表と裏をくるっと水平・垂直にひっくり返すスタイルシート -CSS Flip Boards | コリス](https://coliss.com/articles/build-websites/operation/css/css-tutorial-flip-boards-by-paulund.html)
+ [[CSS]カードをぺろっと裏返すエフェクトを実装するスタイルシート | コリス](https://coliss.com/articles/build-websites/operation/css/css-tutorial-flip-effect-with-webkit-animation.html)
+ [簡単CSSアニメーション＆デザイン20選（ソースコードと解説付き） | knowledge / baigie](https://baigie.me/officialblog/2021/02/25/css-tips-1/)

#その他
https://qiita.com/kouh/items/94018ab5dafdb09e0d8a

https://qiita.com/yoshitake_1201/items/05a13fd77c18ff380eb6