長年の課題
複数のピースを一枚にまとめ集合画像にしたとき、クリップして部分的に表示することができず悩んでいました。今回、以下のような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