vue3+canvas裁剪框样式【前端】
目录
- 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();});