目录
- canvas绘制裁剪框:
- 拖拽改变框的大小:
- 圆圈样式:
- 方块样式:
canvas绘制裁剪框:
// 绘制裁剪框
const drawCropRect = (ctx: CanvasRenderingContext2D): void => {
if (cropRect.value.width > 0 && cropRect.value.height > 0) {
if (canvas.value) {
ctx.strokeStyle = "yellow";
ctx.fillStyle = "rgba(0,0,0,0.3)";
ctx.fillRect(0, 0, canvas.value.width, canvas.value.height);
ctx.clearRect(cropRect.value.x, cropRect.value.y, cropRect.value.width, cropRect.value.height);
ctx.strokeRect(cropRect.value.x, cropRect.value.y, cropRect.value.width, cropRect.value.height);
}
// 编辑模式下绘制小圆圈调整裁剪框大小
if (isEditMode.value) {
const handleSize = 4;
const handles = [
{ x: cropRect.value.x, y: cropRect.value.y }, // 左上
{ x: cropRect.value.x + cropRect.value.width, y: cropRect.value.y }, // 右上
{ x: cropRect.value.x, y: cropRect.value.y + cropRect.value.height }, // 左下
{ x: cropRect.value.x + cropRect.value.width, y: cropRect.value.y + cropRect.value.height }, // 右下
{ x: cropRect.value.x + cropRect.value.width / 2, y: cropRect.value.y }, // 上中
{ x: cropRect.value.x + cropRect.value.width / 2, y: cropRect.value.y + cropRect.value.height }, // 下中
{ x: cropRect.value.x, y: cropRect.value.y + cropRect.value.height / 2 }, // 左中
{ x: cropRect.value.x + cropRect.value.width, y: cropRect.value.y + cropRect.value.height / 2 } // 右中
];
handles.forEach(handle => {
const rectX = handle.x - handleSize / 2;
const rectY = handle.y - handleSize / 2;
ctx.fillStyle = "yellow";
ctx.strokeStyle = "yellow";
ctx.lineWidth = 1;
ctx.fillRect(rectX, rectY, handleSize, handleSize); // 绘制实心方形
ctx.strokeRect(rectX, rectY, handleSize, handleSize); // 绘制边框方形
ctx.fill();
ctx.stroke();
});
}
}
拖拽改变框的大小:
在编辑模式下,我们需要通过勾股定理判断我们是在拖拽这些 左上 左下 右上 右下 上中 下中 左中 右中的小方块。。
// 处理鼠标按下事件
const handleMouseDown = (event: MouseEvent): void => {
if (!isEditMode.value) {
// 记录鼠标拖拽的起始X,Y的位置
isDragging.value = true;
startX.value = event.offsetX;
startY.value = event.offsetY;
} else {
// 编辑模式检查鼠标是否在调整小圈上
const handleSize = 4;
const handles = [
{ x: cropRect.value.x, y: cropRect.value.y }, // 左上
{ x: cropRect.value.x + cropRect.value.width, y: cropRect.value.y }, // 右上
{ x: cropRect.value.x, y: cropRect.value.y + cropRect.value.height }, // 左下
{ x: cropRect.value.x + cropRect.value.width, y: cropRect.value.y + cropRect.value.height }, // 右下
{ x: cropRect.value.x + cropRect.value.width / 2, y: cropRect.value.y }, // 上中
{ x: cropRect.value.x + cropRect.value.width / 2, y: cropRect.value.y + cropRect.value.height }, // 下中
{ x: cropRect.value.x, y: cropRect.value.y + cropRect.value.height / 2 }, // 左中
{ x: cropRect.value.x + cropRect.value.width, y: cropRect.value.y + cropRect.value.height / 2 } // 右中
];
for (let i = 0; i < handles.length; i++) {
const handle = handles[i];
const distance = Math.sqrt(Math.pow(event.offsetX - handle.x, 2) + Math.pow(event.offsetY - handle.y, 2));
if (distance < handleSize) {
// 鼠标在小圈上进行调整矩形
isResizing.value = true;
resizeHandle.value = i.toString();
startX.value = event.offsetX;
startY.value = event.offsetY;
return;
}
}
}
圆圈样式:
const handleSize = 4;
const handles = [
{ x: cropRect.value.x, y: cropRect.value.y }, // 左上
{ x: cropRect.value.x + cropRect.value.width, y: cropRect.value.y }, // 右上
{ x: cropRect.value.x, y: cropRect.value.y + cropRect.value.height }, // 左下
{ x: cropRect.value.x + cropRect.value.width, y: cropRect.value.y + cropRect.value.height }, // 右下
{ x: cropRect.value.x + cropRect.value.width / 2, y: cropRect.value.y }, // 上中
{ x: cropRect.value.x + cropRect.value.width / 2, y: cropRect.value.y + cropRect.value.height }, // 下中
{ x: cropRect.value.x, y: cropRect.value.y + cropRect.value.height / 2 }, // 左中
{ x: cropRect.value.x + cropRect.value.width, y: cropRect.value.y + cropRect.value.height / 2 } // 右中
];
handles.forEach(handle => {
ctx.beginPath();
ctx.arc(handle.x, handle.y, handleSize, 0, 2 * Math.PI);
ctx.fill();
ctx.stroke();
});
方块样式:
const handleSize = 4;
const handles = [
{ x: cropRect.value.x, y: cropRect.value.y }, // 左上
{ x: cropRect.value.x + cropRect.value.width, y: cropRect.value.y }, // 右上
{ x: cropRect.value.x, y: cropRect.value.y + cropRect.value.height }, // 左下
{ x: cropRect.value.x + cropRect.value.width, y: cropRect.value.y + cropRect.value.height }, // 右下
{ x: cropRect.value.x + cropRect.value.width / 2, y: cropRect.value.y }, // 上中
{ x: cropRect.value.x + cropRect.value.width / 2, y: cropRect.value.y + cropRect.value.height }, // 下中
{ x: cropRect.value.x, y: cropRect.value.y + cropRect.value.height / 2 }, // 左中
{ x: cropRect.value.x + cropRect.value.width, y: cropRect.value.y + cropRect.value.height / 2 } // 右中
];
handles.forEach(handle => {
const rectX = handle.x - handleSize / 2;
const rectY = handle.y - handleSize / 2;
ctx.fillStyle = "yellow";
ctx.strokeStyle = "yellow";
ctx.lineWidth = 1;
ctx.fillRect(rectX, rectY, handleSize, handleSize); // 绘制实心方形
ctx.strokeRect(rectX, rectY, handleSize, handleSize); // 绘制边框方形
ctx.fill();
ctx.stroke();
});