htmlでパワポっぽいアニメーション

# はじめに
パワポのアニメーションをcssで作ってみました。
いくつか足りてないですが…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3779420/ac8bf0fb-9816-47ee-9265-c8fe581fd969.png)

# アニメーション
## コード
<p class="codepen" data-height="500" data-default-tab="result" data-slug-hash="emYqBBR" data-pen-title="Untitled" data-user="cjlsrdxi-the-builder" style="height: 500px; 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/cjlsrdxi-the-builder/pen/emYqBBR">
  Untitled</a> by masayasu_t (<a href="https://codepen.io/cjlsrdxi-the-builder">@cjlsrdxi-the-builder</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://public.codepenassets.com/embed/index.js"></script>

## 解説
### 表示
```css
#start-display-box {
  visibility: hidden;
}
#animation-start-display:checked~#start-display-box {
  visibility: visible;
}
```
表示・非表示を切り替えているだけです。

### フェード
```css
#start-fade-box {
  opacity: 0;
  transition-duration: 1000ms;
}
#animation-start-fade:checked~#start-fade-box {
  opacity: 1;
}
```
透過度を変更しているだけです。

### スライド
```css
#start-slide-box {
  transform: translateX(-150px);
  transition-duration: 1000ms;
}
#animation-start-slide:checked~#start-slide-box {
  transform: translateX(0);
}
```
画面の外から移動しているだけです。

### フロート
```css
#start-float-box {
  transform: translateX(100px);
  opacity: 0;
  transition-duration: 1000ms;
}
#animation-start-float:checked~#start-float-box {
  transform: translateX(0);
  opacity: 1;
}
```
透過度を変更しながら移動しているだけです。

### スプリット
```css
div:has(>#start-split-box) {
  width: 0;
  height: 100px;
  overflow: hidden;
  transform: translateX(50px);
  transition-duration: 1000ms;
}
#start-split-box {
  transform: translateX(-50px);
  transition-duration: 1000ms;
}
#animation-start-split:checked~div:has(>#start-split-box) {
  transform: translateX(0);
  width: 100px;
}
#animation-start-split:checked~div #start-split-box {
  transform: translateX(0);
}
```
divで括って、括ったdivの幅を動かします。
真ん中から表示されるように見えるよう表示させる要素の位置も動かしています。

### ワイプ
```css
div:has(>#start-wipe-box) {
  width: 100px;
  height: 100px;
  overflow: hidden;
  transform: translateX(-100px);
  transition-duration: 1000ms;
}
#start-wipe-box {
  transform: translateX(100px);
  transition-duration: 1000ms;
}
#animation-start-wipe:checked~div:has(>#start-wipe-box),
#animation-start-wipe:checked~div #start-wipe-box {
  transform: translateX(0);
}
```
divで括って、括ったdivの幅を動かします。
左から表示されるように見えるよう表示させる要素の位置も動かしています。

### 図形
```css
#start-shape-box {
  mask-image: radial-gradient(#000, #000), url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><circle cx="50" cy="50" r="50" stroke="none" fill="rgb(0,0,0)"/></svg>');
  mask-repeat: no-repeat;
  mask-composite: exclude;
  mask-position: 0 0, center center;
  mask-size: 100% 100%, 150px 150px;
  opacity: 0;
  transition-duration: 1000ms;
}
#animation-start-shape:checked~#start-shape-box {
  mask-size: 100% 100%, 0 0;
  opacity: 1;
}
```
mask-imageを使ってドーナツ形で表示するようにしました。
非表示にしたとき、なぜか四隅の線？が残るので「opacity:0;」でごまかしています。

```css
#start-shape-box {
  mask-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><circle cx="50" cy="50" r="50" stroke="none" fill="rgb(0,0,0)"/></svg>');
  mask-repeat: no-repeat;
  mask-composite: exclude;
  mask-position: center center;
  mask-size: 0 0;
  transition-duration: 1000ms;
}
#animation-start-shape:checked~#start-shape-box {
  mask-size: 150px 150px;
}
```
とすると円形で表示します。

マスクしているsvgを変更すれば好きな形で表示できます。

### ホイール
```css
#start-wheel-box {
  clip-path: polygon(50% 0, 50% 0, 50% 0, 50% 0, 50% 100%, 50% 100%, 50% 100%, 50% 100%);
}
#animation-start-wheel:checked~#start-wheel-box {
  animation: tick 1000ms forwards linear;
}
@keyframes tick {
   0% {clip-path: polygon(50% 0, 50% 0, 50% 0, 50% 0, 50% 100%, 50% 100%, 50% 100%, 50% 100%);}
  25% {clip-path: polygon(50% 0, 100% 0, 100% 0, 100% 0, 0 100%, 0 100%, 0 100%, 50% 100%);}
  75% {clip-path: polygon(50% 0, 100% 0, 100% 100%, 100% 100%, 0 0, 0 0, 0 100%, 50% 100%);}
 100% {clip-path: polygon(50% 0, 100% 0, 100% 100%, 50% 100%, 50% 0, 0 0, 0 100%, 50% 100%);}
}
```
clip-pathを使ってパワポでいう「2スポーク」で表示するようにしました。
ON/OFFをCSSのみでアニメーションさせたいのですが、javascriptを使わないと出来なそうです。

```css
#start-wheel-box {
  clip-path: polygon(50% 50%, 50% 0, 50% 0, 50% 0, 50% 0, 50% 0, 50% 0);
}
@keyframes tick {
     0% {clip-path: polygon(50% 50%, 50% 0, 50% 0, 50% 0, 50% 0, 50% 0, 50% 0);}
  12.5% {clip-path: polygon(50% 50%, 50% 0, 100% 0, 100% 0, 100% 0, 100% 0, 100% 0);}
  37.5% {clip-path: polygon(50% 50%, 50% 0, 100% 0, 100% 100%, 100% 100%, 100% 100%, 100% 100%);}
  62.5% {clip-path: polygon(50% 50%, 50% 0, 100% 0, 100% 100%, 0 100%, 0 100%, 0 100%);}
  87.5% {clip-path: polygon(50% 50%, 50% 0, 100% 0, 100% 100%, 0 100%, 0 0, 0 0);}
   100% {clip-path: polygon(50% 50%, 50% 0, 100% 0, 100% 100%, 0 100%, 0 0, 50% 0);}
}
```
とすると1スポークで表示します。

clip-path＋keyframesを使えば大抵のアニメーションは出来そうです。

https://qiita.com/masayasu_t/items/11acf9b46b6499084800

### グローとターン
```css
div:has(>#start-grow-box) {
  width: 100px;
  height: 100px;
  overflow: hidden;
}
#start-grow-box {
  width: 0;
  height: 0;
  transform: rotate(calc(180deg));
  opacity: 0;
  margin: 50px;
  transition-duration: 1000ms;
}
#animation-start-grow:checked~div #start-grow-box {
  width: 100px;
  height: 100px;
  transform: rotate(0);
  opacity: 1;
  margin: 0;
}
```
括ったdivのは表示領域を確保するだけなので、アニメーションは関係していません。
透過度を変更しながら回転して大きさを変えています。

### ズーム
```css
div:has(>#start-zoom-box) {
  width: 100px;
  height: 100px;
  overflow: hidden;
}
#start-zoom-box {
  width: 0;
  height: 0;
  opacity: 0;
  margin: 50px;
  transition-duration: 1000ms;
}
#animation-start-zoom:checked~div #start-zoom-box {
  width: 100px;
  height: 100px;
  opacity: 1;
  margin: 0;
}
```
括ったdivのは表示領域を確保するだけなので、アニメーションは関係していません。
透過度を変更しながら大きさを変えています。

### ターン
```css
#start-turn-box {
  transform-style: preserve-3d;
  transform: rotateY(0);
  opacity: 0;
  transition-duration: 1000ms;
}
#animation-start-turn:checked~#start-turn-box {
  transform: rotateY(360deg);
  opacity: 1;
}
```
透過度を変更しながらY軸で回転させています。

# おわりに
実務で使うかと言われると使わない気がしますが、アニメーションで使う要素が詰まっているので、サンプルコードとして纏めました

未作成のものは出来たら追加します。