長年の課題
複数のピースを一枚にまとめ集合画像にしたとき、クリップして部分的に表示することができず悩んでいました。今回、以下のような2行5列にまとめた10枚の動物の画像を1枚ずつ表示できたので備忘録として残します。
img要素にposition absoluteを指定し、clip:rectにより取り出すエリアを設定し、位置のずれをtopとleftによって調整して期待した動作を得ました。今回、clip領域を計算により決定せずに、泥臭い方法ながらテーブルを参照する方式に変えたところ思うような動作になりました。以前はcanvasのdrawImage関数を用いて切り抜けていましたが、canvasに頼ることがないので積年の悩みが解消しました。以下にコードを示します。
サンプルコード
<html> <body> <button onclick="setClip();">開始</button> <span id="num" style="color:red">⓿</span> <span style="font-size:10px"> ©TacM,2018 Ver0.01</span><br /> <div style="position:relative; width: 750px; height: 300px; border: 0px solid gray;"> <img id="sample" width="750px" height="300px" style="position:absolute; top:-150px; left:-300px; clip:rect(150px,450px,300px,300px)" src="https://aidesign.lolipop.jp/wp-content/uploads/2015/08/animal10.png"> </div> </body> <script type="text/javascript" charset="Shift_JIS"> const SUJI = "\u24ff\u2776\u2777\u2778\u2779\u277a\u277b\u277c\u277d\u277e"; //0123456789 const rectT=[ 'rect( 0px, 150px, 150px, 0px)', 'rect( 0px, 300px, 150px, 150px)', 'rect( 0px, 450px, 150px, 300px)', 'rect( 0px, 600px, 150px, 450px)', 'rect( 0px, 750px, 150px, 600px)', 'rect(150px, 150px, 300px, 0px)', 'rect(150px, 300px, 300px, 150px)', 'rect(150px, 450px, 300px, 300px)', 'rect(150px, 600px, 300px, 450px)', 'rect(150px, 750px, 300px, 600px)']; var v=0; var p = document.getElementById( "sample" ); function setClip(){ console.log("V="+v+" : "+rectT[v]); document.getElementById("num").innerHTML=SUJI.substr(v, 1); p.style.clip = rectT[v]; p.style.left = -(v%5)*150+'px'; p.style.top = -Math.floor(v/5)*150+'px'; if(++v < 10) setTimeout(setClip, 1000); else v = 0; } </script> </html>
動作結果
⓿
©TacM,2018 Ver0.01