クロッピングメカニズムを実装する
要件:
- 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メソッドを呼び出してリアルタイムプレビューを提供する必要があります。
移動中のクロッピング領域の座標 = 前回記録された位置 + (現在のマウス位置 - マウスが押されたときの位置)