メモを揉め

お勉強の覚書。

StylusでスキューモーフィックなCSS3ジェネレータを作った(続き)

前回のエントリー

githubにアップしました。

Demo: Cassette Deck Controls

各ボタンの記号はFont Awesomeです。
このブログでも使用しています
PlayとRecのボタンは<input type="checkbox" style="display: none;"><label>を組み合わせて作っています。

WEBdev: cssだけでcheckboxやradioのデザインを変更

このジェネレータで出来ること

スキューモーフィックなボタン等のGUICSSで描画できます。

基本

stylusで書くことが前提。
${prefix}_skeu等のプレースホルダ@extendするとスタイルが適用される。
{prefix}にはテーマの名前を指定する。

内部でnib*1を使っているのでその機能は全て使える。

// テーマをインポート
@import '../import_theme/pink.styl'

// skeu.stylを読み込む
@import '../../stylus/skeu.styl'

// 任意の要素にスタイルを適用する
.button
  size 80px auto  // width, heightを設定するnibの省略記法
  @extend $pink_skeu
  &:hover
    @extend $pink_skeu_hover
  &:active
    @extend $pink_skeu_active

バリエーション

ノーマル

.button
  @extend $pink_skeu

usual

両端が連結可能

.button
  @extend $pink_skeu_chain

chain

左端が連結可能

.button
  @extend $pink_skeu_chain_l

chain left

右端が連結可能

.button
  @extend $pink_skeu_chain_r

chain right

他上記バリエーションにホバー時のスタイルを適用した物。

.button
  @extend $pink_skeu_hover
  
.button
  @extend $pink_skeu_chain_hover
  
.button
  @extend $pink_skeu_chain_l_hover
  
.button
  @extend $pink_skeu_chain_r_hover

アクティブ

.button
  @extend $pink_skeu_active

active

円形

.button
  @extend $pink_skeu
  circle()
  size 80px 80px

circle

テクスチャ(画像)

$texture = 'image'
$texture_param = '../../images/stone.png'
$image_size = '100px 100px'

texture image

テクスチャ(CSSパターンによるストライプ)

$texture = 'tl_stripe_abs'
$texture_param = 2

texture image

ビネット効果

$vignette_effect = .9

vignette

ホワイトの拡散

$diffusion = .8

diffusion

実装部分

Stylusでの色定義

カラーコードをそのまま扱うより意図が分かりやすい。
実際これだけでもStylusを使う気になる。

通常のプログラミングと少し質が違うのか、意図を正確にネーミングするのが難しかった。

Hail2u.net: Sassでの色管理

他の記事のCSSでの変数命名についての考察もとても参考になる。
この辺の事、BEMとかのCSSでの命名規則についてもちゃんと勉強しないといけないと思う。
今回は自分の中でなんとなくフィーリングがつかめれば良しとする。

$indirect_base     = blend(rgba(spin(complement($theme_color), $spin_mod), .2), saturate(darken($theme_color, 5), 9))
$edge_reflection   = rgba(255,255,255,.2)
$middle_tone       = saturate(blend(lighten(rgba(spin(complement($base_color), $spin_mod*3), .3), 5%), lighten($base_color, 10%)), 3)
$top_highlight     = rgba(255,255,255,1)
$bottom_shadow     = black
$bottom_reflection = rgba(255,255,255,.8)
$indirect_light    = rgba($indirect_base, .6)
$indirect_shadow   = rgba(0,0,0,.25)
$inner_reflection  = rgba(255,255,255, $diffusion)
$top_saturator     = hsla(hue($theme_color) - $spin_mod*5, 100%, 11%, 1)
$top_inner_light   = rgba(255,255,255,.03)
$top_reflection    = transparentify(blend(rgba($indirect_base, .1), $theme_color), .8)
$bottom_tone       = rgba(0,0,0,.4)

レイヤーの詳細

テキスト

text-shadowを使って立体感を出す。

text-shadow:
  0px -1px 0px $bottom_shadow,
  0px -2px 0px $indirect_light,
  0px -3px 0px $middle_tone,
  0px 1px 0px $indirect_light,
  0px 3px rgba(0,0,0,.2);

ピクセル数をハードコーディングしたままなので、UIの大きさの変化に対応出来ない。
もしまた使うことがあれば調整出来るようにしたい。

ディテール

box-shadowinsetを重ねてフチの部分のディテールを表現する。

box-shadow:
  -1px   0px   0px   0px $edge_reflected   inset,
  -4px   0px   2px  -2px $middle_tone      inset,
   1px   0px   0px   0px $edge_reflected   inset,
   4px   0px   2px  -2px $middle_tone      inset,
   0px   1px   0px   0px $middle_tone      inset,
   0px   2px   0px   0px $top_highlight    inset,
   0px  -1px   0px   0px $bottom_shadow    inset,
   0px -10px   5px  -8px $bottom_reflected inset,
   0px   0px  30px   5px $indirect_light   inset,
   0px   0px  30px   5px $indirect_shadow  inset,
   0px   0px  40px  15px $inner_reflection inset,
   0px   5px   5px  -5px $top_saturator    inset,
   0px   5px   5px   0px $top_inner_light  inset,
   0px  -5px   0px   0px $bottom_tone      inset,
   0px  $shadow_length 5px   0px $drop_shadow;

ピクセル数をハードコーディ(ry

ビネット効果

これが映り込みの上の層にあるのはディテールの表現とぶつかるところをぼかすため。

radial-gradient(transparent, rgba($base_color, $vignette_effect))

映り込み

中央から上側にグラデーションを掛けて、光の反射が下層のテクスチャを隠す様子を表現する。

reflect_blend(o, a)
  transparentify(blend(rgba($top_highlight, o), $theme_color), a)

linear-gradient(top, reflect_blend($top_blend, $top_alpha) 0%, reflect_blend($bottom_blend, $bottom_alpha) 50%, transparent 50%)'

テクスチャ

質感を加える部分、CSSパターンを使うと色々な表現が出来る

flare(n)
  m = 100 / n
  str = ''
  for i in (0..n)
    if even(i)
      c = rgba($peak, $texture_opacity)
    else
      c = rgba($gutter, $texture_opacity)
    if i isnt n
      str += '' + c + ' ' + m * i + '%, '
    else
      str += c
  linear-gradient(left, str)

flare(5)

下地色

ベースとなる色のベタ塗り、カラーファイルで定義する。

// theme color
$theme_color = #a9a19c

// modulation config
$lightness_mod  = -38
$saturation_mod = 0
$spin_mod       = -5deg

// text color
$txt_color = black

余談

途中中だるみでモチベーションが著しく下がった。
少なくとも自分は使うだろうと思えるならいいけど、それも無くなって来ちゃって。

でもゴールデンウィーク中の書き散らかしたコードのままほっといたら、それこそ何やってたのか思い出せなくなって、せっかくの成果物も無駄になってしまう。
将来また同じような事を考えそうな自分に宛てて書くつもりでREADMEを書きましたとさ。

READMEを英語で書くようにしてて、ほとんど英作文の練習だったけどそれはむしろ楽しめるようになってきた。
英語が恥ずかしいことになっていたら教えていだだけると幸いです。

npmの名前空間

それとnpmには今ものすごい宣伝されているprivate modulesのパブリック版、scoped modulesで公開しました

以前の記事ではじめてnpmモジュールを公開したのですが、ちょうどこの直後にThe npm Blogsolving npm’s hard problem: naming packagesという記事が公開されました。

もうタイミングが良すぎるというか、名前空間汚染すんなって名指しで言われたような気がして怖かった。

*1:Stylusの便利メソッド集的なユーティリティライブラリ