合并冲突
This commit is contained in:
commit
9495c40a9d
BIN
pages/.DS_Store
vendored
BIN
pages/.DS_Store
vendored
Binary file not shown.
BIN
pages/index/.DS_Store
vendored
BIN
pages/index/.DS_Store
vendored
Binary file not shown.
@ -2,16 +2,11 @@
|
|||||||
<view>
|
<view>
|
||||||
<!-- 定义canvas画布 // 设置canvas大小为200x200像素 -->
|
<!-- 定义canvas画布 // 设置canvas大小为200x200像素 -->
|
||||||
<!-- // @touchstart="handleCanvasTouch" -->
|
<!-- // @touchstart="handleCanvasTouch" -->
|
||||||
<canvas
|
<canvas @touchstart="handleTouchStart" @touchmove="handleTouchMove" @touchend="handleTouchEnd" :style="{
|
||||||
@touchstart="handleTouchStart"
|
|
||||||
@touchmove="handleTouchMove"
|
|
||||||
@touchend="handleTouchEnd"
|
|
||||||
:style="{
|
|
||||||
width: 1000 + 'px',
|
width: 1000 + 'px',
|
||||||
height: 800 + 'px',
|
height: 800 + 'px',
|
||||||
transform: `translate(${offsetX}px, ${offsetY}px) scale(${scale})`
|
transform: `translate(${offsetX}px, ${offsetY}px) scale(${scale})`
|
||||||
}"
|
}" canvas-id="canvas" id="canvas"></canvas>
|
||||||
canvas-id="canvas" id="canvas" ></canvas>
|
|
||||||
<!-- 添加一个按钮,用于触发绘图 -->
|
<!-- 添加一个按钮,用于触发绘图 -->
|
||||||
<!-- <button @click="handleDraw">点击绘制圆形</button> -->
|
<!-- <button @click="handleDraw">点击绘制圆形</button> -->
|
||||||
</view>
|
</view>
|
||||||
@ -23,20 +18,24 @@
|
|||||||
onMounted,
|
onMounted,
|
||||||
getCurrentInstance
|
getCurrentInstance
|
||||||
} from 'vue'
|
} from 'vue'
|
||||||
import { onReady } from '@dcloudio/uni-app'
|
import {
|
||||||
|
onReady
|
||||||
const canvasWidth = ref(375) // 动态设置Canvas宽度
|
} from '@dcloudio/uni-app'
|
||||||
const canvasHeight = ref(400) // 动态设置Canvas高度
|
// import { useRafFn } from "./utils.js"
|
||||||
|
const canvasWidth = ref() // 动态设置Canvas宽度
|
||||||
|
const canvasHeight = ref() // 动态设置Canvas高度
|
||||||
const instance = getCurrentInstance()
|
const instance = getCurrentInstance()
|
||||||
const scale = ref(1)
|
const scale = ref(1)
|
||||||
const offsetX = ref(0)
|
const offsetX = ref(0)
|
||||||
const offsetY = ref(0)
|
const offsetY = ref(0)
|
||||||
const lastDistance = ref(-1)
|
const lastDistance = ref(-1)
|
||||||
|
|
||||||
const startX = ref(0)
|
const startX = ref(0)
|
||||||
const startY = ref(0)
|
const startY = ref(0)
|
||||||
const isDragging = ref(false)
|
const isDragging = ref(false)
|
||||||
const imgUrl = ref('https://assets.sx25.troyrc.com/sx25/images/events/XBDT.jpg');
|
const imgUrl = ref('https://assets.sx25.troyrc.com/sx25/images/events/XBDT.jpg'); // 修改为ref
|
||||||
const polygonList = [
|
const blocks = ref(
|
||||||
|
[
|
||||||
{
|
{
|
||||||
"areacode": "ksmj71jukqf7",
|
"areacode": "ksmj71jukqf7",
|
||||||
"areaname": "B2区",
|
"areaname": "B2区",
|
||||||
@ -1888,65 +1887,55 @@
|
|||||||
"hint": "N16区"
|
"hint": "N16区"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
);
|
||||||
async function draw() {
|
async function draw() {
|
||||||
const ctx = uni.createCanvasContext('canvas', instance);
|
const ctx = uni.createCanvasContext('canvas', instance);
|
||||||
ctx.save(); // 保存当前状态
|
ctx.save(); // 保存当前状态
|
||||||
ctx.translate(offsetX.value, offsetY.value); // 应用偏移
|
ctx.translate(offsetX.value, offsetY.value); // 应用偏移
|
||||||
ctx.scale(scale.value, scale.value); // 应用缩放
|
ctx.scale(scale.value, scale.value); // 应用缩放
|
||||||
const res = await uni.getImageInfo({ src: imgUrl.value });
|
const res = await uni.getImageInfo({
|
||||||
ctx.drawImage(res.path, 0, 0); // 根据变换后的坐标系绘制图片
|
src: imgUrl.value
|
||||||
|
});
|
||||||
|
ctx.drawImage(res.path, 0, 0, canvasWidth.value, canvasHeight.value);
|
||||||
ctx.restore(); // 恢复之前保存的状态
|
ctx.restore(); // 恢复之前保存的状态
|
||||||
|
// 绘制每个图形
|
||||||
|
blocks.value.forEach((block) => {
|
||||||
|
ctx.beginPath();
|
||||||
|
// ctx.fillStyle = block.color;
|
||||||
|
// 应用缩放
|
||||||
|
ctx.scale(scale.value, scale.value); // 应用缩放
|
||||||
|
switch (block.hint) {
|
||||||
|
case block.hint: // 四边形
|
||||||
|
for (let i = 0; i < block.polygon.length; i += 2) {
|
||||||
|
const x = block.polygon[i];
|
||||||
|
const y = block.polygon[i + 1];
|
||||||
|
if (i === 0) {
|
||||||
|
ctx.moveTo(x, y);
|
||||||
|
} else {
|
||||||
|
ctx.lineTo(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.closePath();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.restore(); // 恢复缩放前的状态,避免影响其他绘制
|
||||||
|
|
||||||
|
ctx.stroke(); // 绘制边框
|
||||||
|
if (block.color) ctx.fill(); // 如果有填充色就填充
|
||||||
|
});
|
||||||
|
|
||||||
|
ctx.draw()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ctx.draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
// async function draw() {
|
|
||||||
// const ctx = uni.createCanvasContext('canvas', instance) // 创建canvas绘图上下文
|
|
||||||
// ctx.scale(scale.value, scale.value);
|
|
||||||
// const res = await uni.getImageInfo({
|
|
||||||
// src: imgUrl.value,
|
|
||||||
// })
|
|
||||||
// ctx.drawImage(res.path, 0, 0);
|
|
||||||
|
|
||||||
// // ctx.beginPath();
|
|
||||||
// // ctx.moveTo(50, 50); // 左下角点
|
|
||||||
// // ctx.lineTo(150, 50); // 右下角点
|
|
||||||
// // ctx.lineTo(200, 100); // 右上角点
|
|
||||||
// // ctx.lineTo(100, 100); // 左上角点
|
|
||||||
// // ctx.closePath(); // 闭合路径
|
|
||||||
// // ctx.stroke(); // 绘制边框
|
|
||||||
|
|
||||||
// // 先不删
|
|
||||||
// // let xoffset = 0, yoffset = 0, flag = false;
|
|
||||||
// // polygonList.forEach((level, index) => {
|
|
||||||
// // // console.log('level',level)
|
|
||||||
// // ctx.moveTo(level.polygon[0] + xoffset, level.polygon[0] + yoffset)
|
|
||||||
// // level.polygon.forEach((level2,level2Index)=>{
|
|
||||||
// // ctx.beginPath()
|
|
||||||
// // if(level2Index != level.polygon.length ){
|
|
||||||
// // ctx.lineTo(level2 + xoffset, level.polygon[level2Index+1])
|
|
||||||
// // console.log(level2 + xoffset, level.polygon[level2Index+1])
|
|
||||||
// // }else{
|
|
||||||
// // ctx.lineTo(level2 + xoffset, level.polygon[0])
|
|
||||||
// // console.log(level2 + xoffset, level.polygon[0])
|
|
||||||
// // }
|
|
||||||
// // ctx.closePath()
|
|
||||||
// // })
|
|
||||||
// // if(polygonList.length == index){
|
|
||||||
// // flag = true
|
|
||||||
// // }
|
|
||||||
// // })
|
|
||||||
// ctx.draw()
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 处理canvas触摸事件
|
// 处理canvas触摸事件
|
||||||
function handleCanvasTouch(event) {
|
function handleCanvasTouch(event) {
|
||||||
// 获取触摸点的坐标
|
// 获取触摸点的坐标
|
||||||
const x = event.touches[0].x;
|
const x = event.touches[0].x;
|
||||||
const y = event.touches[0].y;
|
const y = event.touches[0].y;
|
||||||
console.log(x,y,'12');
|
console.log(x, y, '12');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1954,6 +1943,26 @@ async function draw() {
|
|||||||
// 触摸开始
|
// 触摸开始
|
||||||
const handleTouchStart = (e) => {
|
const handleTouchStart = (e) => {
|
||||||
console.log('handleTouchStart')
|
console.log('handleTouchStart')
|
||||||
|
// 获取触摸点的坐标
|
||||||
|
const x = e.touches[0].x;
|
||||||
|
const y = e.touches[0].y;
|
||||||
|
// 判断点击位置
|
||||||
|
blocks.value.forEach((block) => {
|
||||||
|
if (isPointInQuadrilateral(x, y, block.polygon)) {
|
||||||
|
uni.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: block.hint,
|
||||||
|
showCancel: true, // 显示取消按钮
|
||||||
|
success: (res) => {
|
||||||
|
if (res.confirm) {
|
||||||
|
console.log('用户点击了“确定”按钮');
|
||||||
|
} else if (res.cancel) {
|
||||||
|
console.log('用户点击了“取消”按钮');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
if (e.touches.length === 1) {
|
if (e.touches.length === 1) {
|
||||||
// 单指拖动
|
// 单指拖动
|
||||||
startX.value = e.touches[0].clientX - offsetX.value
|
startX.value = e.touches[0].clientX - offsetX.value
|
||||||
@ -1971,14 +1980,17 @@ async function draw() {
|
|||||||
|
|
||||||
// 触摸移动
|
// 触摸移动
|
||||||
const handleTouchMove = (e) => {
|
const handleTouchMove = (e) => {
|
||||||
|
console.log('11111');
|
||||||
if (e.touches.length === 1 && isDragging.value) {
|
if (e.touches.length === 1 && isDragging.value) {
|
||||||
// 单指移动逻辑...
|
// 单指移动逻辑...
|
||||||
offsetX.value = e.touches[0].clientX - startX.value;
|
offsetX.value = e.touches[0].clientX - startX.value;
|
||||||
offsetY.value = e.touches[0].clientY - startY.value;
|
offsetY.value = e.touches[0].clientY - startY.value;
|
||||||
} else if (e.touches.length === 2) {
|
} else if (e.touches.length === 2) {
|
||||||
// 双指缩放逻辑...
|
// 双指缩放逻辑...
|
||||||
const x1 = e.touches[0].clientX, y1 = e.touches[0].clientY;
|
const x1 = e.touches[0].clientX,
|
||||||
const x2 = e.touches[1].clientX, y2 = e.touches[1].clientY;
|
y1 = e.touches[0].clientY;
|
||||||
|
const x2 = e.touches[1].clientX,
|
||||||
|
y2 = e.touches[1].clientY;
|
||||||
const distance = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
|
const distance = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
|
||||||
|
|
||||||
if (lastDistance.value > 0) {
|
if (lastDistance.value > 0) {
|
||||||
@ -1989,6 +2001,7 @@ async function draw() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// 触摸结束
|
// 触摸结束
|
||||||
const handleTouchEnd = () => {
|
const handleTouchEnd = () => {
|
||||||
console.log('handleTouchEnd')
|
console.log('handleTouchEnd')
|
||||||
@ -2007,21 +2020,51 @@ async function draw() {
|
|||||||
// },300)
|
// },300)
|
||||||
// // 确保在组件挂载后可以获取到Canvas元素
|
// // 确保在组件挂载后可以获取到Canvas元素
|
||||||
// })
|
// })
|
||||||
|
// useRafFn(() => {
|
||||||
|
// draw()
|
||||||
|
// })
|
||||||
onReady(() => {
|
onReady(() => {
|
||||||
console.log('onReadyonReady');
|
console.log('onReadyonReady');
|
||||||
uni.downloadFile({
|
uni.downloadFile({
|
||||||
url:imgUrl.value,
|
url: imgUrl.value,
|
||||||
success: function (sres) {
|
success: function(sres) {
|
||||||
console.log(sres,'sres');
|
console.log(sres, 'sres');
|
||||||
imgUrl.value = sres.tempFilePath || sres.path
|
imgUrl.value = sres.tempFilePath || sres.path
|
||||||
// setInterval(()=>{
|
// setInterval(()=>{
|
||||||
draw()
|
draw()
|
||||||
// },16)
|
// },16)
|
||||||
},fail:function(fres){
|
},
|
||||||
console.log('fres',fres)
|
fail: function(fres) {
|
||||||
|
console.log('fres', fres)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
function isPointInQuadrilateral(px, py, polygon) {
|
||||||
|
let inside = false;
|
||||||
|
const n = polygon.length / 2; // 因为每两个数表示一个点(x,y)
|
||||||
|
for (let i = 0; i < n; i++) {
|
||||||
|
let p1_x = polygon[2 * i];
|
||||||
|
let p1_y = polygon[2 * i + 1];
|
||||||
|
let p2_x, p2_y;
|
||||||
|
if (i === n - 1) { // 最后一个点与第一个点相连形成闭合
|
||||||
|
p2_x = polygon[0];
|
||||||
|
p2_y = polygon[1];
|
||||||
|
} else {
|
||||||
|
p2_x = polygon[2 * i + 2];
|
||||||
|
p2_y = polygon[2 * i + 3];
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return inside;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
79
pages/index/utils.js
Normal file
79
pages/index/utils.js
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
import { ref, onMounted, onUnmounted } from 'vue'
|
||||||
|
|
||||||
|
export function useElementSize(targetSelector) {
|
||||||
|
const width = ref(0)
|
||||||
|
const height = ref(0)
|
||||||
|
let observer = null
|
||||||
|
|
||||||
|
const updateSize = () => {
|
||||||
|
const query = uni.createSelectorQuery()
|
||||||
|
query.select(targetSelector).boundingClientRect(rect => {
|
||||||
|
if (rect) {
|
||||||
|
width.value = rect.width
|
||||||
|
height.value = rect.height
|
||||||
|
}
|
||||||
|
}).exec()
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
updateSize()
|
||||||
|
// 尝试使用 ResizeObserver(部分小程序基础库支持)
|
||||||
|
if (uni.createIntersectionObserver) {
|
||||||
|
observer = uni.createIntersectionObserver(this, {
|
||||||
|
observeAll: true
|
||||||
|
})
|
||||||
|
observer.relativeToViewport().observe(targetSelector, updateSize)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
observer?.disconnect()
|
||||||
|
})
|
||||||
|
|
||||||
|
return { width, height, updateSize }
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEventListener(target, event, handler) {
|
||||||
|
// 组件内事件
|
||||||
|
if (target.$on) {
|
||||||
|
target.$on(event, handler)
|
||||||
|
const stop = () => target.$off(event, handler)
|
||||||
|
onUnmounted(stop)
|
||||||
|
return stop
|
||||||
|
}
|
||||||
|
// 全局事件(需配合 uni.$emit 使用)
|
||||||
|
else {
|
||||||
|
uni.$on(event, handler)
|
||||||
|
const stop = () => uni.$off(event, handler)
|
||||||
|
onUnmounted(stop)
|
||||||
|
return stop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function useRafFn(fn, { immediate = true } = {}) {
|
||||||
|
let isActive = false
|
||||||
|
let timerId = null
|
||||||
|
|
||||||
|
const loop = () => {
|
||||||
|
if (!isActive) return
|
||||||
|
fn()
|
||||||
|
timerId = setTimeout(loop, 16) // 模拟 60fps
|
||||||
|
}
|
||||||
|
|
||||||
|
const start = () => {
|
||||||
|
if (isActive) return
|
||||||
|
isActive = true
|
||||||
|
loop()
|
||||||
|
}
|
||||||
|
|
||||||
|
const stop = () => {
|
||||||
|
isActive = false
|
||||||
|
clearTimeout(timerId)
|
||||||
|
}
|
||||||
|
|
||||||
|
onUnmounted(stop)
|
||||||
|
immediate && start()
|
||||||
|
|
||||||
|
return { start, stop }
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user