pug + scssでインフィニティ・ストーンを作る

はっぴーめりーくりすます！
とは言いますが、もう年末間近です。
年末といえば、一年の振り返りをする方も多いと思います。
今年は、例年に比べて観に行った映画が多かった気がしました。
自分が今年一番印象に残っているのは、アベンジャーズです。
ということで、今回は、アベンジャーズ劇中に登場するインフィニティ・ストーンを
pug + scssで作ってみました。

## インフィニティ・ストーンって何ぞや
詳しくは[こちら](http://d-kamiichi.com/archives/18013)
今回は、ガントレットに装着されている状態を作ります。

## 完成品
<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="css,result" data-user="harold_winston" data-slug-hash="YzPVYwJ" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="css infinity stone">
  <span>See the Pen <a href="https://codepen.io/harold_winston/pen/YzPVYwJ">
  css infinity stone</a> by  Harold Winston (<a href="https://codepen.io/harold_winston">@harold_winston</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## 概要
今回作成にあたって
https://codepen.io/YusukeNakaya/pen/RjQGzg?editors=1100
↑こちらを参考にさせていただきました。
cssのみで、色々な作品を作ってらっしゃる方です。
しゅごい

## 基本の形を作る
最初に、石の原型を作ります。

```pug:stong.pug
.stone--space
```

```scss:stone.scss

.stone {
  position: relative;
  width: 23vh;
  height: 37vh;
  filter: blur(1px);
  overflow: hidden;
  border-radius: 50%;
  box-shadow: inset 0 0 13px 3px #000;
}
```
<img width="354" alt="pic00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119942/6428ad76-899a-f41c-7c49-f1777165ab86.png">

縦長の楕円形を作ります。サイズはcodepen上でのバランスで設定しています。
ポイントとして、`blur`で少しだけぼかす事で表面の滑らかさを出します。
そして、内に力が溜まってそうな感じを出すために、`box-shadow`を内側に設定しています。

## エネルギー源を作ってみる
内に秘めたるパワー・・・
勝手ではありますが入れてみました。

```pug:stone.pug
.stone--space
  .stone_inner--space
```

```scss:stone.scss
&_inner {
  width: 70%;
  height: 70%;
  filter: blur(3px);
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border-radius: 50px;
    
  &--space {
    @extend .stone_inner;
    background-color: #13B4FF;
  }
}
```
<img width="313" alt="pic01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119942/f7ec41b6-4ccb-2735-00c6-bf07405d1451.png">

scssは追加した内容を抜粋したものです。
インナー部分には、外枠よりも少し強めに`blur`をかけて、色は明るめにしています。

## 輝きの再現
仕上げとなる輝きが反射しているのを再現します。

```pug:stone.pug
.stone--space
  .stone_inner--space
  - for (i = 0; i < 60; i++)
    .cut--space
```

```scss:stone.scss
.cut {
  mix-blend-mode: color-dodge;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  &--space {
    @extend .cut;
      
    @for $i from 1 through 100 {
      &:nth-child(#{$i}) {
        width: random(150) + 200px;
        height: random(300) + 200px;
        clip-path: polygon(
          random(100) + 0% random(100) + 0%,
          random(100) + 0% random(100) + 0%,
          random(100) + 0% random(100) + 0%
        );
        animation: sapphireBlue random(3000) + 2000ms random(1000) * -1ms ease-in-out infinite alternate;
        background: linear-gradient(
            random(360) + 0deg,
            rgba(0, 0, 0, 0.5) 0%,
            rgba(103, 195, 252, 0.5) 8%,
            rgba(38, 0, 255, 0.5) 16%,
            rgba(255, 255, 255, 0.5) 25%,
            rgba(38, 0, 255, 0.5) 34%,
            rgba(103, 195, 252, 0.5) 42%,
            rgba(0,0,0,0.5) 50%
        );
        background-size: 100% 200%;
      }
    }
  }
}
@keyframes sapphireBlue {
  0% {
    background-position: 0% 0%;
  }
  100% {
    background-position: 0% 100%;
  }
}
```
<img width="340" alt="pic02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119942/a2231821-b878-832c-2c1b-0e1206646e32.png">

共通の設定として、positionによる中央配置と`mix-blend-mode`を設定しています。

### mix-blend-mode
> CSS の mix-blend-mode プロパティは、要素の内容物と親要素の内容物や要素の背景をどのように混合するかを設定します。

引用：[mix-blend-mode - CSS: カスケーディングスタイルシート | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/mix-blend-mode)

輝きを再現するために、サイズが様々な多数の要素を重ね合わせるので、変化をつけるために使用しています。

forでwrap内に、複数の要素を`random()`を使用してサイズや配置を設定しています。
clip-pathは、頂点の数を3つに、サイズはランダムで設定しています。

```scss: 
clip-path: polygon(
  random(100) + 0% random(100) + 0%,
  random(100) + 0% random(100) + 0%,
  random(100) + 0% random(100) + 0%
);
```

```scss:
background: linear-gradient(
  random(360) + 0deg,
  rgba(0, 0, 0, 0.5) 0%,
  rgba(103, 195, 252, 0.5) 8%,
  rgba(38, 0, 255, 0.5) 16%,
  rgba(255, 255, 255, 0.5) 25%,
  rgba(38, 0, 255, 0.5) 34%,
  rgba(103, 195, 252, 0.5) 42%,
  rgba(0,0,0,0.5) 50%
);
```
各要素のグラデーション設定は
[Ultimate CSS Gradient Generator](https://www.colorzilla.com/gradient-editor/)
を利用して設定しました。
<img width="450" alt="pic03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119942/95fc92c2-bd70-ad14-031c-d550f9242cfd.png">

設定したパラメータの見た目はこんな感じです。

## 単品が完成
ひとまず、スペース・ストーンが完成しました。
<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="css,result" data-user="harold_winston" data-slug-hash="JjoNMJZ" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="old infinity">
  <span>See the Pen <a href="https://codepen.io/harold_winston/pen/JjoNMJZ">
  old infinity</a> by  Harold Winston (<a href="https://codepen.io/harold_winston">@harold_winston</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


## 全色揃えてみました
<img width="1068" alt="pic04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119942/a749ee04-3f60-0350-0022-748660eefc79.png">
全色verは[こちら](https://codepen.io/harold_winston/pen/gObLpmj)


## ちなみに
実は、冒頭で掲載した完成品は、全色揃えてみた後に、全体的なサイズを小さくし、要素数を減らした内容です。
理由としては、単純に描画数が*6になったことで処理が重くなったからです。
完成品は、mix-blend-modeも`lighten`に変更することで、表面が少し滑らかになった気がします。

## 最後に
以前から、cssで色々作ってみたいと考えていましたが、実際に作ってみると難しいなあと思いました（小並）
今回は参考を見つつ、調査しつつでの作成となりましたが、自分のイメージ力だけで作れるようになってみたいものです。

## おまけ
以前、案件にて余りにもIEへの怒りが爆発した為に生まれました。
<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="css,result" data-user="harold_winston" data-slug-hash="oOJayW" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="internet explorer icon">
  <span>See the Pen <a href="https://codepen.io/harold_winston/pen/oOJayW">
  internet explorer icon</a> by  Harold Winston (<a href="https://codepen.io/harold_winston">@harold_winston</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>