IE に なんちゃって text-shadow: を実装する試み

IE になんちゃって text-shadow: を実装する目処が付いた。

currentStyle.display が "inline" なら "inline-block"に、IE6,IE7で currentStyle.width が "auto" ならstyle.zoom = 1 にするといいらしい。

コードはこんな感じ。ShadowフィルタとMotionBlurフィルタの2つを使用してる。
Shadowフィルタで影の色を、MotionBlurフィルタで擬似的なボカシを表現しようとしている。Blurフィルタというまさにそのもののフィルタもあるんだけど、影だけでなく、元の文字列自体が読めなくなるので使えないんだな。

var _mm = uuMeta,
    TRANSPARENT = "transparent",
    DXIMG = "DXImageTransform.Microsoft.",
    SHADOW = DXIMG + "Shadow",
    MOTIONBLUR = DXIMG + "MotionBlur";

function setTextShadowIE(elm, color, ox, oy, blur) {
  if (!color.length) {
    color[0] = TRANSPARENT;
    ox[0] = 0;
    oy[0] = 0;
    blur[0] = 0;
  }

  var es = elm.style, obj,
      x = uuStyle.toPixel(elm, ox[0]),
      y = uuStyle.toPixel(elm, oy[0]),
      rgba = (typeof color[0] === "string") ? uuColor.parse(color[0], 1)
                                            : color[0],
      dir = Math.atan2(y, x) * (180 / Math.PI) + 90;

  if (es.uutextshadow === void 0) {
    if (es.filter.indexOf(SHADOW) < 0) {
      es.filter += " progid:" + SHADOW + "(color=transparent)";
    }
    if (es.filter.indexOf(MOTIONBLUR) < 0) {
      es.filter += " progid:" + MOTIONBLUR + "()";
    }
    if (elm.currentStyle.display === "inline") {
      elm.style.display = "inline-block";
    }
    if (!_mm.iemode8 && elm.currentStyle.width === "auto") {
      es.zoom = 1; // IE6, IE7: force "hasLayout"
    }
  }

  es.uutextshadow = { color: color, ox: ox, oy: oy, blur: blur };

  obj = elm.filters.item(SHADOW);
  obj.Color = uuColor.hex(rgba);
  obj.Direction = dir;
  obj.Strength = Math.max(Math.abs(x), Math.abs(y));
  obj.Enabled = !rgba.a ? false : true;

  obj = elm.filters.item(MOTIONBLUR);
  obj.Add = true;
  obj.Direction = dir;
  obj.Strength = Math.min(uuStyle.toPixel(elm, blur[0]) / 2.5, 10);
  obj.Enabled = !rgba.a ? false : true;
}

制限事項は

  • 影は最大で1つのみ。
  • IE6, IE7 で width: をpx単位で設定しないとレイアウトが崩れる場合がある(em単位だとダメなケースがあるみたい)
    • 色々やったけど完全に救う方法が見つからなかった。単純に zoom = 1 を設定するとさらに悪化するケースまで見つかった。
  • canvas要素の上に配置すると、ジャギる(ことがある)。
    • VML, Silverlight と Filter は元々相性最悪なので、alpha値が絡むと大体ジャギる。


参考

text-shadow: を上手く使うとこういうことができるそうです。…が、なんちゃって実装なので、残念ながらほとんど対応できません。

http://maettig.com/code/css/text-shadow.html

text-shadow: を実装しているブラウザ