CSSで色相環を作る

前回[「CSS三角形の角度を決めて表示させるSTYLUS MIXIN」](http://qiita.com/kobaatsu/items/b58d442bc2e41bcdecc7)の応用編です。

# 作り方

## html
三角形が入るコンテナを360個ばかり用意します。
と書くとアレですが、jadeなら一瞬です。

```lang:jade
ul
  - var i = 1
  while i <= 360
    li
    - i++
```

```lang:html
<ul>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  ...
```

こうなります。

## CSS

### 三角形を作る
頂点の角度が1度になるように作ります。色は仮です。

```lang:stylus
ul
  top 20px
  left 120px
  position relative
li
  width 0
  height 0
  position absolute
  border-style solid
  border-width 115px 1px 0
  border-color #f00 transparent transparent
```

これで360個の三角形が重なった物ができます。

![スクリーンショット 2016-03-29 17.29.30.png](https://qiita-image-store.s3.amazonaws.com/0/21634/87b5b0ca-906d-5f4d-967b-db8f4615a8ed.png)

なんだか一本線にしか見えませんが。

### 1度ずつずらして三百六十角形を作る

ということで360個ばかり `transform` を設定します。
と書くとまったくアレですがstylusなら一瞬です。
頂点の部分を中心にして`rotate()`させたいので、`transform-origin`を設定しておきます。
translate3d()つけるとキレイな感じに回転させられますのでそのように。

```lang:stylus
li
  transform-origin 50% 100%
  for i in (1..360)
    &:nth-of-type({i})
      transform rotate(i deg) translate3d(0, 0, 0)
```

```lang:css
li:nth-of-type(1) {
  -webkit-transform: rotate(1deg) translate3d(0, 0, 0);
          transform: rotate(1deg) translate3d(0, 0, 0);
}
li:nth-of-type(2) {
  -webkit-transform: rotate(2deg) translate3d(0, 0, 0);
          transform: rotate(2deg) translate3d(0, 0, 0);
}
li:nth-of-type(3) {
  -webkit-transform: rotate(3deg) translate3d(0, 0, 0);
          transform: rotate(3deg) translate3d(0, 0, 0);
}
...
```

イテレーション万歳。

![スクリーンショット 2016-03-29 18.55.08.png](https://qiita-image-store.s3.amazonaws.com/0/21634/4c30192e-2733-30ef-38f6-8f8f143984a8.png)

円のように見えますが、いちおう三百六十角形です。

### グラデーションを作る

ボーダーにグラデーションを付けるやり方はまあいろいろあったりなかったりしますが、ここはせっかくなので `border-image` を使ってみましょう。ちょっといろいろ書き換えます。

```lang:stylus
li
  width 0
  height 0
  position absolute
  border-style solid
  border-width 115px 1px
  // border-color #f00 transparent transparent
  border-image linear-gradient(to bottom, black, white) 100% / 115px 1px 0
  transform-origin 50% 100%
  for i in (1..360)
    &:nth-of-type({i})
      transform rotate(i deg) translate3d(0, 0, 0)
```

`border-image` の書き方でちょっと悩みましたが、スライス部分と別に `border-image` 内で線幅を設定することでうまくいきました。~~ので、線色と線幅を削除します。~~`border-color`を削除して、`border-width`は環境によって線が表示されなくなるので残します。

![スクリーンショット 2016-03-29 19.05.14.png](https://qiita-image-store.s3.amazonaws.com/0/21634/6f32b016-a41e-db1d-acaf-205562c37b61.png)

### 色を加える

あとはたいていお気づきだと思いますが、stylusのイテレーションのところにhslで色を指定してやるだけです。イテレーション万歳。

```lang:stylus
li
  for i in (1..360)
    &:nth-of-type({i})
      border-image linear-gradient(to bottom, hsl(i, 100%, 50%), #FFF) 100% / 115px 1px 0
```

![スクリーンショット 2016-03-29 19.08.29.png](https://qiita-image-store.s3.amazonaws.com/0/21634/359b9b67-2ad6-a45a-1138-64115f5b104c.png)

ちょっと滑らかさに欠けますが、これでひとまず完成です。
なんの役に立つのかは聞かないでください。パフォーマンスも大してよくありません。ChromeとSafariでしか動作確認していません。

# おまけ

こんなのを作ってみました。

```lang:jade
| Saturation:
- var s = 0
while s <= 100
  if s == 100
    - chk = true
  input.sat(id="sat"+s, type="radio", name="sat", value=s, class="sat"+s, checked=chk)
  label(for="sat"+s)= s
    | %
  - s += 10
```

![スクリーンショット 2016-03-30 8.03.38.png](https://qiita-image-store.s3.amazonaws.com/0/21634/40d71c1e-82af-fe38-2d23-f827ba1c644c.png)

```lang:stylus
ul
  for s in (0..10)
    .sat{s*10}:checked ~ &
        filter saturate(s/10)
```
CSSフィルターをつかって彩度を変更できます。本当は明度も変えたかったのですけれど、半ば意地でCSSだけで動くようにしたのでムリでした。だからそれが(略

![スクリーンショット 2016-03-30 8.03.51.png](https://qiita-image-store.s3.amazonaws.com/0/21634/d589a6f6-9623-59fe-a5d3-abe30e0707d1.png)

完成品はこちらにあります。
[色相環を作る](http://codepen.io/kobaatsu/pen/EKvjYM)