yamachan Ajax/.NET/C# メモ

2007-03-01

[JS] 画像に簡単に効果をつけるクラス

画像にちょっとした効果をつけたいという要望はけっこうあります。 良く使う効果を簡単に記述できるようなコード、ImgTool を作成してみました。

まずは、マウスを重ねると画像が変わるという効果です。 ボタンなんかで、よく使用しますね。


<img src="search_glass.gif"
onload="new jp.rinco.ImgTool(this,'search_orange.gif');"
/>

onload の部分が、今回作成した ImgTool を使用している部分です。 最初の引数は this、二番目の引数にはマウスを重ねている間に表示する画像を指定します。 簡単でしょ?

次は、マウスを重ねているあいだだけ、画像を拡大表示する効果です。


<img src="yamachan1.jpg" width="43" height="55"
onload="new jp.rinco.ImgTool(this, 5);"
/>

さきほどの画像のかわりに、5 という数値を指定しています。 これは拡大する倍数で、この例ではマウスを重ねると5倍の大きさになります。

次は同じような例ですが、倍数ではなく、拡大したときの横幅、縦幅をドットで指定します。


<img src="yamachan1.jpg" width="43" height="55"
onload="new jp.rinco.ImgTool(this, 215, 62);"
/>

どうでしょう、マウスを重ねると画像が横に伸びたでしょうか?

さて、これまでの例は onload にコードを記載していましたが、画像の id を指定して、後から効果を加えることもできます。


<img src="yamachan1.jpg" id="ImgTool-sample" />

<script>
var it = new jp.rinco.ImgTool('ImgTool-sample');
it.overSrc = "search_orange.gif";
it.overBorder = "solid 2px red";
it.downWidth = it.width * 3;
it.downHeight = it.height * 3;
</script>

今回はマウスを重ねると画像が変わり、赤い枠がつきます。 また画像をクリックしている間、三倍に拡大表示します。

現在の ImgTool では、以下のパラメーターを設定することができます。

* 画像の初期設定値 (参照のみ)

width, height, src, border, color, bgcolor

* マウスオーバー時の設定

overWidth, overHeight, overSrc
overBorder, overColor, overBackgroundColor

* マウスクリック時の設定

downWidth, downHeight, downSrc
downBorder, downColor, downBackgroundColor

実際のコードは以下になります。 長いので、効果の数は減らしてあります。 完全なコードに興味のある方は、yamachan_common.js ファイルを参照してください。

まずは最初の初期化部分です。 画像の最初の状態を保存しておき、また初期化の際の引数を処理しています。

jp.rinco.ImgTool = function(t, p1, p2) {
if (typeof(t) == 'string')
this.target = document.getElementById(t);
else
this.target = t;
this.src = this.target.src;
if (this.target.style.width == "")
this.width = this.target.width;
else
this.width = this.target.style.width;
if (this.target.style.height == "")
this.height = this.target.height;
else
this.height = this.target.style.height;
this.overWidth = "";
this.overHeight = "";
this.overSrc = "";

if (p1 != undefined) {
if (typeof(p1) == 'string')
this.overSrc = p1;
else {
if (p2 == undefined) {
this.overWidth = this.FxMulti(this.width, p1);
this.overHeight = this.FxMulti(this.height,p1);
} else {
this.overWidth = p1;
this.overHeight = p2;
}
}
}

引き続き、クラス初期化の後半です。 イベント処理をおこなう関数を定義しています。

スタイルの変更は最初、foo.style.setAttribute(t,v); のように実行していましたが、Firefox では動作しないようです。 悩んだ結果、対象のイメージ内で eval() を実行するという荒業で実装してみました。 (^-^;

 this.target.evalAttribute = function(t, v, d) {
if (v != "") {
if (d == undefined) {
eval("this." + t + "='" + v + "'");
} else {
eval("this." + t + "='" + d + "'");
}
}
}
this.target.evalAttribute("style.width",
this.Fx(this.width));
this.target.evalAttribute("style.height",
this.Fx(this.height));

this.onmouseover = function() {
this.target.evalAttribute("style.width",
this.Fx(this.overWidth));
this.target.evalAttribute("style.height",
this.Fx(this.overHeight));
this.target.evalAttribute("src", this.overSrc);
}
this.onmouseout = function() {
this.target.evalAttribute("style.width",
this.overWidth, this.Fx(this.width));
this.target.evalAttribute("style.height",
this.overHeight, this.Fx(this.height));
this.target.evalAttribute("src",
this.overSrc, this.src);
}

this.target.aImgTool = this;
this.target.onmouseover = function() {
this.aImgTool.onmouseover();
}
this.target.onmouseout = function() {
this.aImgTool.onmouseout();
}
}

最後にご紹介するのは、prototype で定義した補助関数です。

今回、いったん作成したコードを、Firefox で動作させるのに苦労しました。 特に「FireFoxの標準モードでは、style.width,heightに数値での設定ができない」という制限に気がつくまでが長かった...。

Fx() は上記の制限に対応するための quick hack で、数値を渡すと px 表記に変換して返すだけの補助関数です。

FxMulti() も似たようなもので、px などの余分な文字が指定されていた場合でも、正常に掛け算を実行するだけの補助関数です。 引数に倍率を指定した場合に使用しています。

jp.rinco.ImgTool.prototype.Fx = function(v) {
if (typeof(v) == "number")
return v + "px";
else
return v;
}

jp.rinco.ImgTool.prototype.FxMulti = function(v, m) {
if (typeof(v) == "number")
return eval(v + "*" + m);
var myReg = new RegExp("[0-9]+", "i");
if (!myReg.test(v))
return "error";

var ret = eval(myReg.exec(v) + "*" + m);
return RegExp.leftContext + ret + RegExp.rightContext;
}

ちなみに今回のオブジェクトは、画像が主なターゲットと想定して作成したため、ImgTool という名前になっています。 が、画像以外に使用してもかまいません。

DIV タグに使用した例
 マウスを上に
 マウスをクリック