Image Glass – 小さく表示された画像の一部を元のサイズで拡大表示する

Tool

Webページに小さく表示された画像の一部をオリジナルサイズで拡大表示するための JSライブラリです(ブックマークレットとしても使用可)。このサイトでも使っています。

どういうものかよくわかるように下に大きめな画像を載せておきます。そこにマウスカーソルを移動してみてください。カーソル部分の画像が拡大表示されます。

拡大表示といっても Webページに載せて小さく表示された画像をオリジナルサイズで等倍表示しているので正確に言うと拡大ではないのですが、基本大きく見えるようになるので拡大という言葉を使っています。

使い方

上にも書いたように画像にマウスカーソルを移動するだけです。元のサイズより小さく表示されている画像の場合、カーソルが乗っている部分が小窓に拡大表示されます。縮小表示されていない画像ではなにもしません。

画像が小窓に拡大表示されているときに Shiftキーを押すと、押している間は小窓がカーソルに追従しなくなります。そのとき小窓をクリックするとオリジナル画像が新規タブに表示されます。

導入方法

「Image Glass」は、サイト製作者がサイトに導入して使うのが基本ですが、「Image Glass」を導入していないサイトでもユーザーが同じことができるように、ブラウザにブックマークレットとして入れることが出来るようにもなっています。

ブラウザに入れるほうが簡単なのでまずこちらから説明します。

ユーザーがブラウザに入れて使用する

下にある「ImageGlass」のリンクを右クリックしてブックマークするか、ブックマークバーにリンクをD&Dして登録します。あとは使いたいページでブックマークした「ImageGlass」をクリックするだけで使えます。

ImageGlass

ブックマークレットと拡張機能のちがい

いちばん大きな違いは、ブラウザでページが開かれたときに、拡張機能は自動的に読み込まれるのに対し、ブックマークレットはユーザーが使いたいブックマークレットを自分でクリックするまで、そのページに読み込まれないということです。

サイト製作者がサイトに導入する

body内の最後に、スクリプトを貼り付けるか JSファイルを読み込むかすれば動きます。

WordPressでサイト全体に適用する

「Image Glass」を WordPressに導入するには、プラグインを使うのが簡単だと思います。使用しているテーマが bodyの最後に JavaScriptを追加できるならそちらを使ってください。

当サイトでは「Scripts n Styles」プラグインを使って「Image Glass」を読み込んでいます。具体的には、「Scripts n Styles」を新規追加・有効化する。左側のWordPressメニューの「ツール」に「Scrips n Styles」という項目が追加されるのでそれをクリック。開かれたページの下の方に「Scripts(end of the body tag:)」というエリアがあるので そこにコピペする。

次のスクリプトを bodyの最後に読み込まれるようにします。

const RND_STR = "2q79n";
const IMG_WND_W = 300;			// 等倍表示小窓幅
const IMG_WND_H = 150;

const IMG_AREA_W = 50000;		// 見えない画像エリア幅
const IMG_AREA_H = 50000;
const IMG_AREA_OFF = 5000;		// オフセットページと離す距離

oMove = {
	lastElement: null,
};

oImg = {
	el: null,		// ターゲットのimg要素
	src: "",		// 画像url
	px: 0,			// 画像のページ内座標
	py: 0,
	dw: 0,			// 画像表示サイズ
	dh: 0,
	ow: 0,			// 画像オリジナルサイズ
	oh: 0,

	wnd: null,		// 画像窓の div要素
	area: null,		// オリジナルサイズ取得用の img要素
};

// 初期設定
(function(){
	// 画像を入れてオリジナルサイズ取得用の要素を生成する
	let div = document.createElement("div");
	div.style.cssText = `width:${IMG_AREA_W}px; height:${IMG_AREA_H}px; position:fixed; top:${-(IMG_AREA_H + IMG_AREA_OFF)}px; left:0;`;
	document.body.appendChild(div);
	oImg.area = new Image();
	div.appendChild(oImg.area);

	// 画像窓用の要素を生成する
	oImg.wnd = document.createElement("div");
	oImg.wnd.id = "imgg"+RND_STR;
	oImg.wnd.style.cssText = `width:${IMG_WND_W}px; height:${IMG_WND_H}px; overflow:hidden; position:fixed; top: -1000px; right: -1000px; background-repeat: no-repeat; outline:2px outset rgba(255,255,255,0.4); z-index:10000; background-color:rgba(0,0,0,.5); backdrop-filter: blur(3px);`;
	document.body.appendChild(oImg.wnd);
}());

// カーソルが画像上を動いてるならときの処理
document.addEventListener('mousemove', (e)=> {
	if(e.shiftKey)
		return;
	if(e.target !== oMove.lastElement){
		// ちがう要素に変わった
		if(oMove.lastElement){		// null対策
			// 前要素が画像なら小窓非表示
			if(oImg.el)
				oImg.wnd.style.display = "none";
		}
		// 対象画像 null, 現要素保存
		oImg.el = null;
		oMove.lastElement = e.target;

		if(e.target.tagName.toLowerCase() === "img"){
			// 画像をオリジナルサイズで見えないエリアに読み込む
			oImg.area.src = e.target.src;
			// 画像の表示サイズ・画像要素・画像のパスを保存
			oImg.dw = e.target.offsetWidth;
			oImg.dh = e.target.offsetHeight;
			oImg.src = e.target.src;
		}
	}
	// カーソルが画像上にある場合
	if(oImg.el){
		// 画像上のカーソル座標
		let ex = e.clientX - oImg.px;
		let ey = e.clientY - oImg.py;
		let scaleX = (oImg.ow / oImg.dw)*(-1);
		let scaleY = (oImg.oh / oImg.dh)*(-1);
		// 画像を等倍表示
		oImg.wnd.style.backgroundPosition = (ex*scaleX + IMG_WND_W/2) + "px " + (ey*scaleY + IMG_WND_H/2) + "px";

		// 小窓移動
		oImg.wnd.style.top = (e.clientY - IMG_WND_H*9/8) + "px";
		oImg.wnd.style.left = (e.clientX - IMG_WND_W/2) + "px";
	}
});

// カーソルが画像上を通ると、mousemoveイベントで画像が oImg.areaに読み込まれ、ここに来る
oImg.area.addEventListener('load', (e)=> {
	// 画像のオリジナルサイズ
	let rect = oImg.area.getBoundingClientRect();
	oImg.ow = rect.width;
	oImg.oh = rect.height;

	if(oImg.ow !== oImg.dw || oImg.oh !== oImg.dh){
		// 画像データをオブジェクトにセット
		oImg.el = oMove.lastElement;
		// 画像のページ座標
		let rect = oImg.el.getBoundingClientRect();
		oImg.px = rect.left;
		oImg.py = rect.top;

		oImg.wnd.style.backgroundImage = "url(" + oImg.src + ")";
		oImg.wnd.style.display = "block";
	}else
		oImg.el = null;
});

// スクロール時の処理
// 小窓で画像を表示中にスクロールしてカーソルが画像外に出ても小窓は表示されたまま の対策
document.addEventListener("scroll", (event) => {
	oImg.wnd.style.display = "none";
	oMove.lastElement = null;
});

oImg.wnd.addEventListener('click', (e)=> {
	// 小窓を非表示
	oImg.wnd.style.display = "none";
	oImg.el = null;
	// 別タブにオリジナル画像表示
	window.open(oImg.src, '_blank');
	e.preventDefault();
});

ミニサイズ版

中身はブックマークレットとまったく同じですが、これを貼っても動作します。

javascript:(function(){eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('i H="11";i p=12;i q=13;i I=J;i y=J;i K=14;j={k:b,};3={c:b,d:"",7:0,A:0,r:0,s:0,t:0,u:0,6:b,l:b,};(15(){f m=n.L("m");m.a.M=`B:${I}7;C:${y}7;N:O;v:${-(y+K)}7;D:0;`;n.P.E(m);3.l=16 17();m.E(3.l);3.6=n.L("m");3.6.18="19"+H;3.6.a.M=`B:${p}7;C:${q}7;1a:1b;N:O;v:-Q;1c:-Q;R-S:1d-S;1e:1f 1g T(F,F,F,0.4);z-1h:1i;R-1j:T(0,0,0,.5);1k-1l:1m(1n);`;n.P.E(3.6)}());n.w(\'1o\',(e)=>{g(e.1p)1q;g(e.h!==j.k){g(j.k){g(3.c)3.6.a.x="G"}3.c=b;j.k=e.h;g(e.h.1r.1s()==="1t"){3.l.d=e.h.d;3.r=e.h.1u;3.s=e.h.1v;3.d=e.h.d}}g(3.c){f U=e.V-3.7;f W=e.X-3.A;f Y=(3.t/3.r)*(-1);f Z=(3.u/3.s)*(-1);3.6.a.1w=(U*Y+p/2)+"7 "+(W*Z+q/2)+"7";3.6.a.v=(e.X-q*9/8)+"7";3.6.a.D=(e.V-p/2)+"7"}});3.l.w(\'1x\',(e)=>{f o=3.l.10();3.t=o.B;3.u=o.C;g(3.t!==3.r||3.u!==3.s){3.c=j.k;f o=3.c.10();3.7=o.D;3.A=o.v;3.6.a.1y="1z("+3.d+")";3.6.a.x="1A"}1B 3.c=b});n.w("1C",(1D)=>{3.6.a.x="G";j.k=b});3.6.w(\'1E\',(e)=>{3.6.a.x="G";3.c=b;1F.1G(3.d,\'1H\');e.1I()});',62,107,'|||oImg|||wnd|px|||style|null|el|src||let|if|target|const|oMove|lastElement|area|div|document|rect|IMG_WND_W|IMG_WND_H|dw|dh|ow|oh|top|addEventListener|display|IMG_AREA_H||py|width|height|left|appendChild|255|none|RND_STR|IMG_AREA_W|50000|IMG_AREA_OFF|createElement|cssText|position|fixed|body|1000px|background|repeat|rgba|ex|clientX|ey|clientY|scaleX|scaleY|getBoundingClientRect|2q79n|300|150|5000|function|new|Image|id|imgg|overflow|hidden|right|no|outline|2px|outset|index|10000|color|backdrop|filter|blur|3px|mousemove|shiftKey|return|tagName|toLowerCase|img|offsetWidth|offsetHeight|backgroundPosition|load|backgroundImage|url|block|else|scroll|event|click|window|open|_blank|preventDefault'.split('|'),0,{}))})();

プラグインを使いたくない人は、自力で function.phpを書き換えて JSファイルを bodyの最後に読み込んでください。

ダウンロード

コメント