实现裁剪机制
要求:
- 熟悉JavaScript中的Canvas API,用于绘图和图像操作。
功能:
- 在显示的图像上添加一个裁剪区域,并使该区域可拖动。这为用户提供了选择所需裁剪区域的灵活性。
在main.js
中添加相关方法。
- 创建一个
cutImage
方法
cutImage
方法主要负责两项任务:一是创建一个遮罩层,二是使用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);
通过以上两行代码,我们获取了鼠标与背景图像之间的距离。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);
这两段代码值得注意。前两行记录了上一次截图时的坐标(如果没有上一次截图,则是初始坐标);后两行记录了鼠标按下时的坐标。你可以分别使用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
方法以提供实时预览。
移动过程中裁剪区域的坐标 = 上次记录的位置 + (当前鼠标位置 - 鼠标按下时的位置)