<template> <view> <!-- 定义canvas画布 // 设置canvas大小为200x200像素 --> <canvas @touchstart="handleCanvasTouch" @touchmove="handleCanvasTouchMove" @touchend="handleCanvasTouchEnd" canvas-id="canvas" id="canvas" style="border: 1px solid red;height: 600px;width: 1000px;"></canvas> <!-- 添加一个按钮,用于触发绘图 --> <button @click="handleDraw">点击绘制圆形</button> </view> </template> <script setup> import { ref, onMounted, getCurrentInstance } from 'vue' // 平移和缩放状态 const translateX = ref(0); const translateY = ref(0); const scale = ref(1); const canvasWidth = ref(375) // 动态设置Canvas宽度 const canvasHeight = ref(400) // 动态设置Canvas高度 const instance = getCurrentInstance() // 定义图形数组 const blocks = ref([{ points: [{ x: 50, y: 50 }, // 左下角点 { x: 150, y: 50 }, // 右下角点 { x: 200, y: 100 }, // 右上角点 { x: 100, y: 100 }, // 左上角点 ], message: '点击了四边形', type: 'quadrilateral' }]); async function draw() { // 设置平移和缩放 const imgUrl = "https://assets.sx25.troyrc.com/sx25/images/events/XBDT.jpg" const ctx = uni.createCanvasContext('canvas', instance) // 创建canvas绘图上下文 ctx.translate(translateX.value, translateY.value ); ctx.scale(scale.value, scale.value); const res = await uni.getImageInfo({ src: imgUrl, }) ctx.drawImage(res.path, 0, 0,canvasWidth.value ,canvasHeight.value); // 绘制每个图形 blocks.value.forEach((block) => { ctx.beginPath(); ctx.fillStyle = block.color; switch (block.type) { case 'quadrilateral': // 四边形 ctx.moveTo(block.points[0].x, block.points[0].y); for (let i = 1; i < block.points.length; i++) { ctx.lineTo(block.points[i].x, block.points[i].y); } ctx.closePath(); break; } ctx.stroke(); // 绘制边框 }); ctx.draw() } // 处理canvas触摸移动事件 function handleCanvasTouchMove(event) { if (event.touches.length === 1) { // 单指平移 translateX.value += event.touches[0].x - event.touches[0].startX; translateY.value += event.touches[0].y - event.touches[0].startY; } else if (event.touches.length === 2) { // 双指缩放 const distance1 = Math.sqrt( (event.touches[0].x - event.touches[1].x) ** 2 + (event.touches[0].y - event.touches[1].y) ** 2 ); const distance2 = Math.sqrt( (event.touches[0].startX - event.touches[1].startX) ** 2 + (event.touches[0].startY - event.touches[1].startY) ** 2 ); scale.value *= distance1 / distance2; } draw(); // 重新绘制 } // 处理canvas触摸结束事件 function handleCanvasTouchEnd(event) { // 保存当前触摸点的初始位置 event.touches.forEach((touch) => { touch.startX = touch.x; touch.startY = touch.y; }); } // 处理canvas触摸事件 function handleCanvasTouch(event) { // 获取触摸点的坐标 const x = event.touches[0].x; const y = event.touches[0].y; // 判断点击位置 blocks.value.forEach((block) => { if (isPointInQuadrilateral(x, y, block.points)) { uni.showModal({ title: '提示', content: block.message, showCancel: true, // 显示取消按钮 success: (res) => { if (res.confirm) { console.log('用户点击了“确定”按钮'); } else if (res.cancel) { console.log('用户点击了“取消”按钮'); } }, }); } }); } // 按钮点击事件处理函数 const handleDraw = () => { draw(); // 调用绘图函数 } onMounted(() => { draw() // 确保在组件挂载后可以获取到Canvas元素 }) // 判断点是否在四边形内 function isPointInQuadrilateral(px, py, points) { let inside = false; const n = points.length; let p1 = points[0]; for (let i = 1; i <= n; i++) { let p2 = points[i % n]; if (py > Math.min(p1.y, p2.y) && py <= Math.max(p1.y, p2.y) && px <= Math.max(p1.x, p2.x)) { if (p1.y !== p2.y) { let xinters = (py - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x; if (p1.x === p2.x || px <= xinters) { inside = !inside; } } } p1 = p2; } return inside; } </script> <style scoped> button { margin-top: 10px; } </style>