excanvas.js のバグ/不具合とその解決方法

IE用のCoverFlowを実装がてらVMLを勉強中です。

今日は、excanvas.js(version 0.2)や、その根底にあるVMLの問題とその解決方法を列挙してみます。

  • [VML] oval stroke="false"が無視され線が描画される
    • strokeサブエレメントを追加し、<v_:stroke on="false" weight="0pt" /> などと指定すると線が描画されなくなる
      • stroked="f" を指定すると線が描画されなくなります。W3Cに提出された仕様は"stroke"、MSの仕様では"stroked"でした。
  • [excanvas.js] 円形グラデーション createRadialGradient() の描画が仕様と違う。

IE6 + excanvas.js(ver0.2)で描画

Firefox3で描画

    • VMLはovalでgradientradialを指定すると円形グラデーションを描画可能。
    • (がんばれば)ほぼ同じ描画が可能なことが判明。

IE6 + excanvas.js(ver0.2 + パッチ)で描画

  • [excanvas.js] 線形グラデーション createLinearGradient() で addColorStop が使えない。
    • これもVMLレベルで実装可能。
  • [excanvas.js] 線形グラデーション createLinearGradient() で 縦のグラデーションしか描画できない。
    • これもVMLレベルで実装可能。
  • drawImage() の第一引数に canvas が指定できないので、canvas間で画像をコピーできない。
    • 未解決
  • [excanvas.js] globalCompositeOperation が機能しない "source-over"(デフォルト)のみ使用可能。
    • VMLレベルで解決可能な気がしたけど、方法はちょっとド忘れ。
  • [excanvas.js] strokeStyle や fillStyle に "pink" 等の WebNamedColor を指定しても無視される。
    • CSS1Levelの基本16色しか指定できないため、"pink","skyblue"や"rgba(100%,100%,100%,1)などが指定不能
      • uupaa.js (ver0.5) で実装した uu.module.color が色辞書による変換をサポート。
  • VMLのcolorsプロパティ(addColorStop 相当のもの)がサポートするグラデーションカラー()の書式。
    • OK: colors="0% white, 50% blue, 100% red"
    • OK: colors="0 white; 0.5 blue; 1.0 red" ← セミコロン(";")でセパレート
    • OK: colors="0 white, .5 blue; 1 red"
    • OK: colors="0 rgb(255,255,255), 0.5 #00f, 1.0 #ff0000"
    • NG: colors="0 rgba(255,255,255,1), 0.5 blue, 1.0 red"
  • fill, type="tile", opacity="0.5" とするとcolorで指定した色(デフォルトは白)が混ざった状態で描画されてしまう。opacity="1.0"だとブレンドされない。
    • 現状では回避不能Excelなどでも画像を敷き詰めた状態(テクスチャを張る)で、透明度を選択できないため、tile + opacityの組み合わせでは透明度だけ変化させることができない。
    • color="#eef" (灰色がかった薄い青)などの目立たない色を指定するか、opacity="1.0" 固定にするかの二択。
      • VML要素自体をdiv要素で包み、progid:DXImageTransform.Microsoft.Alpha(Opacity=50)やprogid:DXImageTransform.Microsoft.BasicImage(Opacity=0.5)で透過する方法も試してみたが、逆効果で、黒く反転 + ジャギーが発生した。

      • type="tile" opacity="0.5" color="#ccf"を指定した場合の描画結果

    • 全体をgroupで包み、groupの不透明度を変更するも効果なし
 <g_vml_:shape style="position:absolute;width:10;height:10;"
         filled="t" stroked="f" coordorigin="0,0" coordsize="100,100"
         opacity="0.5" path="〜">
   <g_vml_:fill type="tile" src="〜"
           color="#eef" opacity="1.0" />
 </g_vml_:shape>

           ↓↓↓

 <g_vml_:group style="position:absolute;width:10;height:10;"
         filled="t" stroked="f" coordorigin="0,0" coordsize="10,10"
         opacity="0.5">
   <g_vml_:shape style="position:absolute;width:10;height:10;"
           filled="t" stroked="f" coordorigin="0,0" coordsize="100,100"
           // opacity="0.5"
           path="〜">
     <g_vml_:fill type="tile" src="〜"
             // color="#eef"
             // opacity="1.0"
             />
   </g_vml_:shape>
 </g_vml:group>

HTML5::canavas は低レベルAPIのみの仕様なので、ラッパーライブラリが無いとちょっと不便です。
ですので、見つかった問題とその修正方法を、Googleの中の人にパッチで送るか、uupaa.js側で実装するかはまだ未定です。

色々あったら、また追記していきます。