クロッピングメカニズムを実装する
要件:
- JavaScriptのCanvas APIを使った描画と画像操作に精通していること。
機能:
- 表示された画像にクロッピング領域を追加し、この領域をドラッグ可能にする。これにより、ユーザーはクロッピングするための希望の領域を選択する柔軟性が得られる。
main.js
に関連するメソッドを追加する。
cutImage
メソッドを作成する
cutImage
メソッドは主に2つのタスクを担当します。1つはマスク層を作成することで、もう1つはCSSのbackground
プロパティを使って選択されたクロッピング領域のリアルタイムプレビューを提供することです。
cutImage: function () {
var t = this;
t.editBox.height = t.imgHeight;
t.editBox.width = t.imgWidth;
t.editBox.style.display = "block";
t.editBox.style.left = t.px;
t.editBox.style.top = t.py;
var cover = t.editBox.getContext("2d");
cover.fillStyle = "rgba(0, 0, 0, 0.5)";
cover.fillRect(0, 0, t.imgWidth, t.imgHeight);
cover.clearRect(t.sx, t.sy, t.sHeight, t.sWidth);
document.getElementById("show_edit").style.background =
"url(" + t.imgUrl + ")" + -t.sx + "px " + -t.sy + "px no-repeat";
document.getElementById("show_edit").style.height = t.sHeight + "px";
document.getElementById("show_edit").style.width = t.sWidth + "px";
},
drag
メソッドを作成する
drag: function () {
var t = this;
var draging = false;
var startX = 0;
var startY = 0;
document.getElementById("cover_box").onmousemove = function (e) {
var pageX = e.pageX - (t.regional.offsetLeft + this.offsetLeft);
var pageY = e.pageY - (t.regional.offsetTop + this.offsetTop);
if (
pageX > t.sx &&
pageX < t.sx + t.sWidth &&
pageY > t.sy &&
pageY < t.sy + t.sHeight
) {
this.style.cursor = "move";
this.onmousedown = function () {
draging = true;
t.ex = t.sx;
t.ey = t.sy;
startX = e.pageX - (t.regional.offsetLeft + this.offsetLeft);
startY = e.pageY - (t.regional.offsetTop + this.offsetTop);
};
window.onmouseup = function () {
draging = false;
};
if (draging) {
if (t.ex + (pageX - startX) < 0) {
t.sx = 0;
} else if (t.ex + (pageX - startX) + t.sWidth > t.imgWidth) {
t.sx = t.imgWidth - t.sWidth;
} else {
t.sx = t.ex + (pageX - startX);
}
if (t.ey + (pageY - startY) < 0) {
t.sy = 0;
} else if (t.ey + (pageY - startY) + t.sHeight > t.imgHeight) {
t.sy = t.imgHeight - t.sHeight;
} else {
t.sy = t.ey + (pageY - startY);
}
t.cutImage();
}
} else {
this.style.cursor = "auto";
}
};
},
このメソッドを理解するには、以下のポイントを把握する必要があります。
var pageX = e.pageX - (t.regional.offsetLeft + this.offsetLeft);
var pageY = e.pageY - (t.regional.offsetTop + this.offsetTop);
上記の2行のコードでは、マウスと背景画像の間の距離を取得しています。e.pageX
はマウスからブラウザの左エッジまでの距離を表し、t.regional.offsetLeft + this.offsetLeft
は画像からブラウザの左エッジまでの距離を計算します。同様に、上の距離も導き出せます。
if ( pageX > t.sx && pageX < t.sx + t.sWidth && pageY > t.sy && pageY < t.sy + t.sHeight )
マウスと背景画像の間の距離を理解していれば、これは簡単に把握できます。これは、マウスが画像の領域内にあるかどうかを判断します。
t.ex = t.sx;
t.ey = t.sy;
startX = e.pageX - (t.regional.offsetLeft + this.offsetLeft);
startY = e.pageY - (t.regional.offsetTop + this.offsetTop);
これらの2つのコードスニペットは注目に値します。最初の2行は、前回のスクリーンショットの座標(前回なかった場合は初期座標)を記録します。次の2行は、マウスが押されたときの座標を記録します。console.log()
を使って個別にこれらの値を確認することができます。
if (draging) {
if (t.ex + (pageX - startX) < 0) {
t.sx = 0;
} else if (t.ex + (pageX - startX) + t.sWidth > t.imgWidth) {
t.sx = t.imgWidth - t.sWidth;
} else {
t.sx = t.ex + (pageX - startX);
}
if (t.ey + (pageY - startY) < 0) {
t.sy = 0;
} else if (t.ey + (pageY - startY) + t.sHeight > t.imgHeight) {
t.sy = t.imgHeight - t.sHeight;
} else {
t.sy = t.ey + (pageY - startY);
}
t.cutImage();
}
上記のコードは基本的に次のように言っています。ドラッグ中は、座標の変化に基づいてt.sx
とt.sy
の値をリアルタイムで更新し、cutImage
メソッドを呼び出してリアルタイムプレビューを提供する必要があります。
移動中のクロッピング領域の座標 = 前回記録された位置 + (現在のマウス位置 - マウスが押されたときの位置)