当前位置: 首页 > java >正文

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();});
http://www.xdnf.cn/news/1141.html

相关文章:

  • 车载软件架构 --- 驾驶员不感知的控制器软件运行
  • Sentinel源码—8.限流算法和设计模式总结一
  • Java中的方法重写(Override)与方法重载(Overload)详解
  • CSI D-PHY 散谈
  • 【Linux网络】各版本TCP服务器构建 - 从理解到实现
  • 云原生周刊:KubeSphere 平滑升级
  • UWB与GPS技术融合的室内外无缝定位方案
  • QT6 源(43):class QGroupBox : public QWidget ,最常用的容器类 QGroupBox 的源码
  • 网络编程基础
  • mybatis-plus开发orm
  • Word处理控件Spire.Doc系列教程:C# 为 Word 文档设置背景颜色或背景图片
  • 静压模型SWASH学习(9)——平底水槽高频驻波算例(Standing short wave in closed basin)
  • Django 入门实战:从环境搭建到构建你的第一个 Web 应用
  • PyTorch卷积层填充(Padding)与步幅(Stride)详解及代码示例
  • 一款丰富的工作流自动化平台 | N8N 83.6K ⭐
  • 基于外部中中断机制,实现以下功能: 1.按键1,按下和释放后,点亮LED 2.按键2,按下和释放后,熄灭LED 3.按键3,按下和释放后,使得LED闪烁
  • Android 中实现图片翻转动画(卡片翻转效果)
  • react使用01
  • 基于微信小程序的走失儿童帮助系统-项目分享
  • PerfettoSQL
  • 火山引擎实时语音合成WebSocket V3协议Python实现demo
  • redis数据类型-基数统计HyperLogLog
  • 搜索引擎的高级语法
  • 前端性能优化全攻略:JavaScript 优化、DOM 操作、内存管理、资源压缩与合并、构建工具及性能监控
  • 复刻低成本机械臂 SO-ARM100 3D 打印篇
  • RHCE 作业二(密钥登录实验)
  • XPath 语法入门
  • day35图像处理OpenCV
  • docker镜像新增加用户+sudo权限,无dockerfile
  • osxcross 搭建 macOS 交叉编译环境