HSV色空間はこんなところでも役立つよ。ちらしの裏

今日もHTML5::Canvasネタです。

uupaa-excanvas.js は、テキスト + シャドウを自前でレンダリングしています(in VMLモード)。
VML自体は、不透明度をサポートしているのですが、テキスト要素に不透明度を設定しても無視されるという制限があります。

影の部分はテキスト要素を重ね打ちして表現しているのですが、テキストに不透明度を設定できないため、重ね打ちした影のほうが、テキストよりも目立ってしまうという問題が起きてました。

不透明度が無いなら色でごまかせばいいじゃない。

ここは一つ『不透明度のかわりに 色(彩度と明るさ)を調整してエッジをぼかす』ってのにトライしてみました。

やってることは簡単で、
ShadowColor(RGB色空間) を HSV 色空間に変換し、彩度と明度を適当に調整した後で、再度RGB色空間にマップし直しています。

      srgba = uuCanvas.toRGBA(sc[0]); // ← sc[0] がShadowColor
      // dark color arrange to value+30%
      // eg: #000000(black) -> #4c4c4c(Value+30%)
      if (srgba.r + srgba.g + srgba.b < 0x50) {
        srgba = uuCanvas.arrangeColor(srgba, 0, 0, 30); // Value+30%
      }

      for (; si < _sw; so += sd, --sx, --sy, ++si, --sii) {
        // arrangeColor() は HSV 空間上で、色相, 彩度, 明度を調整する関数
        shex = uuCanvas.toHex(
            uuCanvas.arrangeColor(srgba,
                                  0, si * 10 - 40, sii * 12 - 15)); // 値は超適当

        rv.push('<v:shape style="z-index:', zindex,
                ';position:absolute;width:', w, 'px;height:', h,
                'px;left:', x + sx - offX,
                'px;top:', y + sy, 'px;',
                VML_FILL,
                '" coordSize="21600,21600" o:spt="136" fillColor="', shex,
//              VML_OPACITY, so.toFixed(2),
                '"><v:textpath style="font:', font.css, '" string="', text,
                VML_END_SHAPE);
      }

反省会

  • 着想から実装まで4時間