选中
This commit is contained in:
parent
a0129fa7ce
commit
ed07181a5e
@ -21,6 +21,7 @@
|
|||||||
:imgUrl="'https://assets.tech.troyrc.com/sx25/images/events/XBDT.jpg'"
|
:imgUrl="'https://assets.tech.troyrc.com/sx25/images/events/XBDT.jpg'"
|
||||||
:areaData="currentView === 'area' ? seatAreas : []"
|
:areaData="currentView === 'area' ? seatAreas : []"
|
||||||
:seatData="currentView === 'seat' ? seatPositions : []"
|
:seatData="currentView === 'seat' ? seatPositions : []"
|
||||||
|
:selectedCodes="selectedCodes"
|
||||||
/>
|
/>
|
||||||
</view>
|
</view>
|
||||||
<!-- isShowSeat -->
|
<!-- isShowSeat -->
|
||||||
@ -57,7 +58,8 @@ export default {
|
|||||||
seatAreas: [], // 座位区域数据
|
seatAreas: [], // 座位区域数据
|
||||||
currentView:'area',
|
currentView:'area',
|
||||||
seatPositions: [], // 座位数据
|
seatPositions: [], // 座位数据
|
||||||
selectedArea: null // 当前选中分区
|
selectedArea: null, // 当前选中分区
|
||||||
|
selectedCodes: new Set(), // 存储选中的座位code
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -84,9 +86,10 @@ export default {
|
|||||||
// 计算点击坐标(考虑dpr)
|
// 计算点击坐标(考虑dpr)
|
||||||
const x = (e.detail.x - this.containerRect.left) * dpr;
|
const x = (e.detail.x - this.containerRect.left) * dpr;
|
||||||
const y = (e.detail.y - this.containerRect.top) * dpr;
|
const y = (e.detail.y - this.containerRect.top) * dpr;
|
||||||
|
console.log('handleCanvasClick',x,y)
|
||||||
if (this.currentView === 'area') {
|
if (this.currentView === 'area') {
|
||||||
const hitArea = this.$refs.canvasRef.checkHitArea(x, y);
|
const hitArea = this.$refs.canvasRef.checkHitArea(x, y);
|
||||||
|
console.log('handleCanvasClick',hitArea)
|
||||||
if (hitArea) {
|
if (hitArea) {
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: '请确认',
|
title: '请确认',
|
||||||
@ -99,7 +102,6 @@ export default {
|
|||||||
this.currentView = 'seat';
|
this.currentView = 'seat';
|
||||||
this.loadSeatData(hitArea.areacode)
|
this.loadSeatData(hitArea.areacode)
|
||||||
}
|
}
|
||||||
console.log(res,'showModa-- success')
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -107,12 +109,32 @@ export default {
|
|||||||
const hitSeat = this.$refs.canvasRef.checkSeatHit(x, y);
|
const hitSeat = this.$refs.canvasRef.checkSeatHit(x, y);
|
||||||
if (hitSeat) {
|
if (hitSeat) {
|
||||||
console.log('选中座位:', hitSeat);
|
console.log('选中座位:', hitSeat);
|
||||||
|
this.toggleSeatSelection(hitSeat);
|
||||||
// 这里可以添加座位选择逻辑
|
// 这里可以添加座位选择逻辑
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
toggleSeatSelection(seat) {
|
||||||
|
if (seat.status !== 1) return; // 只允许选择可用座位
|
||||||
|
|
||||||
|
if (this.selectedCodes.has(seat.code)) {
|
||||||
|
this.selectedCodes.delete(seat.code);
|
||||||
|
} else {
|
||||||
|
// 限制最多选择4个座位
|
||||||
|
if (this.selectedCodes.size < 4) {
|
||||||
|
this.selectedCodes.add(seat.code);
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: '最多只能选择4个座位',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.$refs.canvasRef.redraw(); // 触发重绘
|
||||||
|
},
|
||||||
|
|
||||||
async getContainerPosition() {
|
async getContainerPosition() {
|
||||||
// 添加重试机制
|
// 添加重试机制
|
||||||
let retryCount = 0;
|
let retryCount = 0;
|
||||||
@ -136,9 +158,9 @@ export default {
|
|||||||
};
|
};
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('获取容器位置失败:', e);
|
console.error('获取容器位置失败:', e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 等待后重试
|
// 等待后重试
|
||||||
await new Promise(r => setTimeout(r, 100));
|
await new Promise(r => setTimeout(r, 100));
|
||||||
@ -147,89 +169,111 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
initGestureHandler() {
|
initGestureHandler() {
|
||||||
try {
|
try {
|
||||||
this.gestureHandler = new GestureHandler(this, this.transformMatrix, {
|
this.gestureHandler = new GestureHandler(this, this.transformMatrix, {
|
||||||
container: this.containerRect
|
container: this.containerRect
|
||||||
});
|
});
|
||||||
} catch (e) {
|
console.log( 'initGestureHandler', this.gestureHandler )
|
||||||
console.error('手势处理器初始化失败:', e);
|
} catch (e) {
|
||||||
// 简化降级方案
|
console.error('手势处理器初始化失败:', e);
|
||||||
this.gestureHandler = {
|
// 简化降级方案
|
||||||
catchEvent: (event) => {
|
this.gestureHandler = {
|
||||||
if (event.touches.length > 0) {
|
catchEvent: this.createGestureFallback(),
|
||||||
this.gestureStatus = "降级模式";
|
setScale: (scale) => {
|
||||||
this.touchPoints = event.touches.length;
|
this.transformMatrix.scale(scale, scale, this.canvasWidth/2, this.canvasHeight/2);
|
||||||
|
this.updateCanvas();
|
||||||
if (event.type === 'touchmove') {
|
},
|
||||||
const firstTouch = event.touches[0];
|
reset: () => {
|
||||||
const x = firstTouch.clientX - this.containerRect.left;
|
this.transformMatrix.reset();
|
||||||
const y = firstTouch.clientY - this.containerRect.top;
|
this.updateCanvas();
|
||||||
|
}
|
||||||
this.transformMatrix.tx = x;
|
}
|
||||||
this.transformMatrix.ty = y;
|
}
|
||||||
this.updateCanvas();
|
},
|
||||||
}
|
|
||||||
}
|
createGestureFallback() {
|
||||||
}
|
let isClick = true;
|
||||||
}
|
let startPoint = null;
|
||||||
}
|
let startTime = null;
|
||||||
},
|
let lastPoint = null;
|
||||||
|
|
||||||
// 事件处理
|
return (event) => {
|
||||||
async handleTouchEvent(event) {
|
const touches = event.touches || [];
|
||||||
if (!this.gestureHandler || !this.containerRect) {
|
|
||||||
await this.getContainerPosition();
|
if (touches.length === 1) {
|
||||||
this.initGestureHandler();
|
const getPoint = (t) => ({
|
||||||
if (event.type === 'touchend' || event.type === 'touchcancel') {
|
x: t.clientX - this.containerRect.left,
|
||||||
this.gestureStatus = '结束';
|
y: t.clientY - this.containerRect.top
|
||||||
this.updateCanvas();
|
});
|
||||||
return;
|
|
||||||
}
|
const currentPoint = getPoint(touches[0]);
|
||||||
}
|
|
||||||
|
if (!startPoint) {
|
||||||
// 记录时间戳
|
startPoint = currentPoint;
|
||||||
const currentTime = Date.now();
|
startTime = Date.now();
|
||||||
|
}
|
||||||
// 更新触点数量
|
|
||||||
this.touchPoints = event.touches.length;
|
const dx = currentPoint.x - startPoint.x;
|
||||||
|
const dy = currentPoint.y - startPoint.y;
|
||||||
// 修正坐标
|
const distance = Math.sqrt(dx * dx + dy * dy);
|
||||||
const correctedTouches = Array.from(event.touches).map(touch => {
|
|
||||||
return {
|
// 如果是点击(移动距离小于阈值且时间短)
|
||||||
...touch,
|
if (isClick && distance < 5 && Date.now() - startTime < 200) {
|
||||||
x: touch.clientX - this.containerRect.left,
|
return; // 不执行移动操作
|
||||||
y: touch.clientY - this.containerRect.top
|
}
|
||||||
};
|
|
||||||
});
|
// 标记为非点击操作
|
||||||
|
isClick = false;
|
||||||
// 创建修正后的事件对象
|
|
||||||
const correctedEvent = {
|
// 执行移动操作
|
||||||
...event,
|
if (lastPoint) {
|
||||||
touches: correctedTouches,
|
const moveDx = currentPoint.x - lastPoint.x;
|
||||||
changedTouches: correctedTouches
|
const moveDy = currentPoint.y - lastPoint.y;
|
||||||
};
|
|
||||||
|
this.transformMatrix.tx += moveDx;
|
||||||
// 传递事件给手势处理器
|
this.transformMatrix.ty += moveDy;
|
||||||
this.gestureHandler.catchEvent(correctedEvent);
|
}
|
||||||
|
|
||||||
// 更新手势状态
|
lastPoint = currentPoint;
|
||||||
if (event.type === 'touchstart') {
|
}
|
||||||
this.gestureStatus = event.touches.length > 1 ? '双指开始' : '单指开始';
|
|
||||||
}
|
// 在触摸结束时重置状态
|
||||||
else if (event.type === 'touchmove') {
|
if (event.type === 'touchend' || event.type === 'touchcancel') {
|
||||||
this.gestureStatus = event.touches.length > 1 ? '双指缩放/移动' : '单指移动';
|
isClick = true;
|
||||||
}
|
startPoint = null;
|
||||||
else {
|
startTime = null;
|
||||||
this.gestureStatus = '结束';
|
lastPoint = null;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
// 限制更新频率
|
},
|
||||||
if (currentTime - this.lastGestureTime > 50) {
|
|
||||||
this.lastGestureTime = currentTime;
|
async handleTouchEvent(event) {
|
||||||
this.updateCanvas();
|
console.log(event,'handleTouchEvent')
|
||||||
}
|
// 更新触点数量
|
||||||
},
|
this.touchPoints = event.touches.length;
|
||||||
|
|
||||||
|
// 仅在触摸开始时重置状态
|
||||||
|
if (event.type === 'touchstart') {
|
||||||
|
this.gestureStatus = event.touches.length > 1 ? '双指开始' : '单指开始';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理事件传递
|
||||||
|
this.gestureHandler?.catchEvent(event);
|
||||||
|
|
||||||
|
// 更新触摸结束状态
|
||||||
|
if (event.type === 'touchend' || event.type === 'touchcancel') {
|
||||||
|
this.gestureStatus = '结束';
|
||||||
|
this.updateCanvas();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 限制更新频率
|
||||||
|
const currentTime = Date.now();
|
||||||
|
if (currentTime - this.lastGestureTime > 50) {
|
||||||
|
this.lastGestureTime = currentTime;
|
||||||
|
this.updateCanvas();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// 更新Canvas
|
// 更新Canvas
|
||||||
updateCanvas() {
|
updateCanvas() {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
@ -595,29 +639,37 @@ export default {
|
|||||||
this.transformMatrix = new TransformMatrix();
|
this.transformMatrix = new TransformMatrix();
|
||||||
|
|
||||||
// 自动居中显示座位区域
|
// 自动居中显示座位区域
|
||||||
this.$nextTick(() => {
|
// 自动居中显示座位区域
|
||||||
if (this.seatPositions.length > 0) {
|
this.$nextTick(() => {
|
||||||
const minX = Math.min(...this.seatPositions.map(s => s.x));
|
if (!this.gestureHandler) {
|
||||||
const maxX = Math.max(...this.seatPositions.map(s => s.x));
|
this.initGestureHandler();
|
||||||
const minY = Math.min(...this.seatPositions.map(s => s.y));
|
}
|
||||||
const maxY = Math.max(...this.seatPositions.map(s => s.y));
|
if (this.seatPositions.length > 0) {
|
||||||
|
// 计算座位区域边界
|
||||||
const centerX = (minX + maxX) / 2;
|
const xs = this.seatPositions.map(s => s.x);
|
||||||
const centerY = (minY + maxY) / 2;
|
const ys = this.seatPositions.map(s => s.y);
|
||||||
|
const minX = Math.min(...xs);
|
||||||
// 计算合适的缩放比例
|
const maxX = Math.max(...xs);
|
||||||
const widthRatio = this.canvasWidth / (maxX - minX + 100);
|
const minY = Math.min(...ys);
|
||||||
const heightRatio = this.canvasHeight / (maxY - minY + 100);
|
const maxY = Math.max(...ys);
|
||||||
const scale = Math.min(widthRatio, heightRatio, 1);
|
|
||||||
|
// 计算中心点
|
||||||
// 应用变换
|
const centerX = (minX + maxX) / 2;
|
||||||
// this.transformMatrix.scale(scale, scale);
|
const centerY = (minY + maxY) / 2;
|
||||||
// this.transformMatrix.translate(
|
|
||||||
// this.canvasWidth/2 - centerX * scale,
|
// 计算合适的缩放比例
|
||||||
// this.canvasHeight/2 - centerY * scale
|
const widthRatio = this.canvasWidth / (maxX - minX + 100);
|
||||||
// );
|
const heightRatio = this.canvasHeight / (maxY - minY + 100);
|
||||||
}
|
const scale = Math.min(widthRatio, heightRatio, 1);
|
||||||
});
|
|
||||||
|
// 应用变换
|
||||||
|
// this.transformMatrix.scale(scale, scale);
|
||||||
|
// this.transformMatrix.translate(
|
||||||
|
// this.canvasWidth/2 - centerX * scale,
|
||||||
|
// this.canvasHeight/2 - centerY * scale
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -4,7 +4,8 @@ class GestureHandler {
|
|||||||
this.containerRect = container;
|
this.containerRect = container;
|
||||||
this.panThreshold = 5;
|
this.panThreshold = 5;
|
||||||
this.panStarted = false;
|
this.panStarted = false;
|
||||||
|
// 保存父组件上下文
|
||||||
|
this.context = context;
|
||||||
// 判断是否是小程序环境
|
// 判断是否是小程序环境
|
||||||
this.isMiniProgram = typeof wx !== 'undefined' || typeof uni !== 'undefined';
|
this.isMiniProgram = typeof wx !== 'undefined' || typeof uni !== 'undefined';
|
||||||
|
|
||||||
@ -52,66 +53,63 @@ class GestureHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建小程序专用的简化手势处理器
|
createSimpleGestureHandler() {
|
||||||
createSimpleGestureHandler() {
|
let isClick = true;
|
||||||
let isClick = true;
|
let startPoint = null;
|
||||||
let startPoint = null;
|
let startTime = null;
|
||||||
let startTime = null;
|
let lastPoint = null;
|
||||||
let lastPoint = null;
|
|
||||||
|
return (event) => {
|
||||||
return (event) => {
|
// 移除了视图判断
|
||||||
const touches = event.touches || [];
|
const touches = event.touches || [];
|
||||||
|
|
||||||
if (touches.length === 1) {
|
if (touches.length === 1) {
|
||||||
const getPoint = (t) => ({
|
const getPoint = (t) => ({
|
||||||
x: t.x || (t.clientX - this.containerRect.left),
|
x: t.x || (t.clientX - this.containerRect.left),
|
||||||
y: t.y || (t.clientY - this.containerRect.top)
|
y: t.y || (t.clientY - this.containerRect.top)
|
||||||
});
|
});
|
||||||
|
|
||||||
const currentPoint = getPoint(touches[0]);
|
const currentPoint = getPoint(touches[0]);
|
||||||
|
|
||||||
// 第一次触摸
|
if (!startPoint) {
|
||||||
if (!startPoint) {
|
startPoint = currentPoint;
|
||||||
startPoint = currentPoint;
|
startTime = Date.now();
|
||||||
startTime = Date.now();
|
}
|
||||||
}
|
|
||||||
|
const dx = currentPoint.x - startPoint.x;
|
||||||
// 计算移动距离
|
const dy = currentPoint.y - startPoint.y;
|
||||||
const dx = currentPoint.x - startPoint.x;
|
const distance = Math.sqrt(dx * dx + dy * dy);
|
||||||
const dy = currentPoint.y - startPoint.y;
|
|
||||||
const distance = Math.sqrt(dx * dx + dy * dy);
|
// 区分点击和拖拽
|
||||||
|
if (isClick && distance < 5 && Date.now() - startTime < 200) {
|
||||||
// 如果是点击(移动距离小于阈值且时间短)
|
return;
|
||||||
if (isClick && distance < 5 && Date.now() - startTime < 200) {
|
}
|
||||||
return; // 不执行移动操作
|
|
||||||
}
|
isClick = false;
|
||||||
|
|
||||||
// 标记为非点击操作
|
if (lastPoint) {
|
||||||
isClick = false;
|
const moveDx = currentPoint.x - lastPoint.x;
|
||||||
|
const moveDy = currentPoint.y - lastPoint.y;
|
||||||
// 执行移动操作
|
|
||||||
if (lastPoint) {
|
this.transformMatrix.tx += moveDx;
|
||||||
const moveDx = currentPoint.x - lastPoint.x;
|
this.transformMatrix.ty += moveDy;
|
||||||
const moveDy = currentPoint.y - lastPoint.y;
|
}
|
||||||
|
|
||||||
this.transformMatrix.tx += moveDx;
|
lastPoint = currentPoint;
|
||||||
this.transformMatrix.ty += moveDy;
|
} else if (touches.length > 1) {
|
||||||
}
|
this._handlePinch(touches);
|
||||||
|
}
|
||||||
lastPoint = currentPoint;
|
|
||||||
} else if (touches.length > 1) {
|
// 重置状态
|
||||||
this._handlePinch(touches);
|
if (event.type === 'touchend' || event.type === 'touchcancel') {
|
||||||
}
|
isClick = true;
|
||||||
|
startPoint = null;
|
||||||
// 在触摸结束时重置状态
|
startTime = null;
|
||||||
if (event.type === 'touchend' || event.type === 'touchcancel') {
|
lastPoint = null;
|
||||||
isClick = true;
|
}
|
||||||
startPoint = null;
|
};
|
||||||
startTime = null;
|
}
|
||||||
lastPoint = null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
setupGestures() {
|
setupGestures() {
|
||||||
// 平移手势
|
// 平移手势
|
||||||
|
@ -27,7 +27,8 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
areaData:{},
|
areaData:{},
|
||||||
seatData:{}
|
seatData:{},
|
||||||
|
selectedCodes:{}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -37,10 +38,17 @@ export default {
|
|||||||
canvasDisplayWidth: 800, // 默认显示尺寸
|
canvasDisplayWidth: 800, // 默认显示尺寸
|
||||||
canvasDisplayHeight: 600,
|
canvasDisplayHeight: 600,
|
||||||
canvasActualWidth: 800, // 实际像素尺寸
|
canvasActualWidth: 800, // 实际像素尺寸
|
||||||
canvasActualHeight: 600
|
canvasActualHeight: 600,
|
||||||
|
nowSelectedCodes:this.selectedCodes
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
selectedCodes:{
|
||||||
|
handler(newVal) {
|
||||||
|
this.nowSelectedCodes = newVal
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
imgUrl: {
|
imgUrl: {
|
||||||
handler(newUrl) {
|
handler(newUrl) {
|
||||||
if (newUrl) this.loadImage(newUrl);
|
if (newUrl) this.loadImage(newUrl);
|
||||||
@ -83,6 +91,13 @@ export default {
|
|||||||
this.initCanvas();
|
this.initCanvas();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
|
invertPoint(x, y) {
|
||||||
|
// 注意:直接使用矩阵的逆转换,不需要除以dpr
|
||||||
|
const inverted = this.matrix.invertPoint(x, y);
|
||||||
|
return inverted;
|
||||||
|
},
|
||||||
|
|
||||||
// 添加点击检测方法
|
// 添加点击检测方法
|
||||||
checkHitArea(x, y) {
|
checkHitArea(x, y) {
|
||||||
if (!this.areaData) return null;
|
if (!this.areaData) return null;
|
||||||
@ -302,26 +317,62 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
drawSeats() {
|
drawSeats() {
|
||||||
// 获取当前缩放比例
|
this.ctx.save();
|
||||||
const scale = Math.sqrt(this.matrix.a * this.matrix.a + this.matrix.b * this.matrix.b);
|
|
||||||
|
// 应用变换矩阵
|
||||||
this.seatData.forEach(seat => {
|
const { a, b, c, d, tx, ty } = this.matrix;
|
||||||
// 使用原始坐标(变换矩阵会自动应用)
|
this.ctx.setTransform(a, b, c, d, tx, ty);
|
||||||
const x = seat.x;
|
|
||||||
const y = seat.y;
|
// 获取当前缩放比例
|
||||||
|
const scale = Math.sqrt(a * a + b * b);
|
||||||
this.ctx.beginPath();
|
|
||||||
// 根据缩放调整座位大小
|
this.seatData.forEach(seat => {
|
||||||
const radius = 8 / scale;
|
const x = seat.x;
|
||||||
this.ctx.arc(x, y, radius, 0, Math.PI * 2);
|
const y = seat.y;
|
||||||
|
|
||||||
this.ctx.fillStyle = seat.status === 1 ? '#4cd964' : '#dd524d';
|
// 根据缩放调整座位大小
|
||||||
this.ctx.fill();
|
const radius = 8 / scale;
|
||||||
|
|
||||||
// 仅在缩放足够大时显示文字
|
console.log(this.nowSelectedCodes,'nowSelectedCodesnowSelectedCodesnowSelectedCodes')
|
||||||
|
// 修改1:为选中座位添加特殊样式
|
||||||
});
|
if (this.nowSelectedCodes.has(seat.code) && seat.status === 1) {
|
||||||
|
// 1. 绘制金色边框
|
||||||
|
this.ctx.beginPath();
|
||||||
|
this.ctx.arc(x, y, radius + 1, 0, Math.PI * 2);
|
||||||
|
this.ctx.strokeStyle = '#FFD700'; // 金色
|
||||||
|
this.ctx.lineWidth = 2 / scale;
|
||||||
|
this.ctx.stroke();
|
||||||
|
|
||||||
|
// 2. 绘制半透明金色背景
|
||||||
|
this.ctx.beginPath();
|
||||||
|
this.ctx.arc(x, y, radius, 0, Math.PI * 2);
|
||||||
|
this.ctx.fillStyle = 'rgba(255, 215, 0, 0.3)';
|
||||||
|
this.ctx.fill();
|
||||||
|
|
||||||
|
// 3. 绘制白色对勾(缩小版)
|
||||||
|
this.ctx.strokeStyle = '#fff';
|
||||||
|
this.ctx.lineWidth = 1 / scale;
|
||||||
|
this.ctx.lineCap = 'round';
|
||||||
|
this.ctx.beginPath();
|
||||||
|
this.ctx.moveTo(x - 2.5, y);
|
||||||
|
this.ctx.lineTo(x - 0.5, y + 1.5);
|
||||||
|
this.ctx.lineTo(x + 2.5, y - 2);
|
||||||
|
this.ctx.stroke();
|
||||||
|
} else {
|
||||||
|
// 普通座位的绘制保持不变
|
||||||
|
this.ctx.beginPath();
|
||||||
|
this.ctx.arc(x, y, radius, 0, Math.PI * 2);
|
||||||
|
this.ctx.fillStyle = seat.status === 1 ? '#4cd964' : '#dd524d';
|
||||||
|
this.ctx.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 仅在缩放足够大时显示文字
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
this.ctx.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
@ -1 +1 @@
|
|||||||
{"version":3,"file":"gesture-canvas-page.js","sources":["pages/index/gesture-canvas-page.vue?type=page"],"sourcesContent":["import MiniProgramPage from '/Users/sunmeng/Desktop/wx/canvas/pages/index/gesture-canvas-page.vue'\nwx.createPage(MiniProgramPage)"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,GAAG,WAAW,eAAe;"}
|
{"version":3,"file":"gesture-canvas-page.js","sources":["pages/index/gesture-canvas-page.vue?type=page"],"sourcesContent":["import MiniProgramPage from '/Users/sunmeng/Desktop/wx/canvas/pages/index/gesture-canvas-page.vue'\nwx.createPage(MiniProgramPage)"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,GAAG,WAAW,eAAe;"}
|
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
|||||||
{"version":3,"file":"transform-canvas.js","sources":["/Users/sunmeng/Desktop/wx/canvas/pages/index/transform-canvas.vue?type=component"],"sourcesContent":["import Component from '/Users/sunmeng/Desktop/wx/canvas/pages/index/transform-canvas.vue'\nwx.createComponent(Component)"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,GAAG,gBAAgB,SAAS;"}
|
{"version":3,"file":"transform-canvas.js","sources":["/Users/sunmeng/Desktop/wx/canvas/pages/index/transform-canvas.vue?type=component"],"sourcesContent":["import Component from '/Users/sunmeng/Desktop/wx/canvas/pages/index/transform-canvas.vue'\nwx.createComponent(Component)"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,GAAG,gBAAgB,SAAS;"}
|
@ -6882,7 +6882,7 @@ function initOnError() {
|
|||||||
function initRuntimeSocketService() {
|
function initRuntimeSocketService() {
|
||||||
const hosts = "127.0.0.1,172.10.0.127";
|
const hosts = "127.0.0.1,172.10.0.127";
|
||||||
const port = "8090";
|
const port = "8090";
|
||||||
const id = "mp-weixin_8j0jyd";
|
const id = "mp-weixin_3NWJxu";
|
||||||
const lazy = typeof swan !== "undefined";
|
const lazy = typeof swan !== "undefined";
|
||||||
let restoreError = lazy ? () => {
|
let restoreError = lazy ? () => {
|
||||||
} : initOnError();
|
} : initOnError();
|
||||||
|
@ -23,8 +23,10 @@ const _sfc_main = {
|
|||||||
currentView: "area",
|
currentView: "area",
|
||||||
seatPositions: [],
|
seatPositions: [],
|
||||||
// 座位数据
|
// 座位数据
|
||||||
selectedArea: null
|
selectedArea: null,
|
||||||
// 当前选中分区
|
// 当前选中分区
|
||||||
|
selectedCodes: /* @__PURE__ */ new Set()
|
||||||
|
// 存储选中的座位code
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
@ -42,8 +44,10 @@ const _sfc_main = {
|
|||||||
const dpr = this.$refs.canvasRef.dpr || 1;
|
const dpr = this.$refs.canvasRef.dpr || 1;
|
||||||
const x = (e.detail.x - this.containerRect.left) * dpr;
|
const x = (e.detail.x - this.containerRect.left) * dpr;
|
||||||
const y = (e.detail.y - this.containerRect.top) * dpr;
|
const y = (e.detail.y - this.containerRect.top) * dpr;
|
||||||
|
common_vendor.index.__f__("log", "at pages/index/gesture-canvas-page.vue:89", "handleCanvasClick", x, y);
|
||||||
if (this.currentView === "area") {
|
if (this.currentView === "area") {
|
||||||
const hitArea = this.$refs.canvasRef.checkHitArea(x, y);
|
const hitArea = this.$refs.canvasRef.checkHitArea(x, y);
|
||||||
|
common_vendor.index.__f__("log", "at pages/index/gesture-canvas-page.vue:92", "handleCanvasClick", hitArea);
|
||||||
if (hitArea) {
|
if (hitArea) {
|
||||||
common_vendor.index.showModal({
|
common_vendor.index.showModal({
|
||||||
title: "请确认",
|
title: "请确认",
|
||||||
@ -55,17 +59,34 @@ const _sfc_main = {
|
|||||||
this.currentView = "seat";
|
this.currentView = "seat";
|
||||||
this.loadSeatData(hitArea.areacode);
|
this.loadSeatData(hitArea.areacode);
|
||||||
}
|
}
|
||||||
common_vendor.index.__f__("log", "at pages/index/gesture-canvas-page.vue:102", res, "showModa-- success");
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (this.currentView === "seat") {
|
} else if (this.currentView === "seat") {
|
||||||
const hitSeat = this.$refs.canvasRef.checkSeatHit(x, y);
|
const hitSeat = this.$refs.canvasRef.checkSeatHit(x, y);
|
||||||
if (hitSeat) {
|
if (hitSeat) {
|
||||||
common_vendor.index.__f__("log", "at pages/index/gesture-canvas-page.vue:109", "选中座位:", hitSeat);
|
common_vendor.index.__f__("log", "at pages/index/gesture-canvas-page.vue:111", "选中座位:", hitSeat);
|
||||||
|
this.toggleSeatSelection(hitSeat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
toggleSeatSelection(seat) {
|
||||||
|
if (seat.status !== 1)
|
||||||
|
return;
|
||||||
|
if (this.selectedCodes.has(seat.code)) {
|
||||||
|
this.selectedCodes.delete(seat.code);
|
||||||
|
} else {
|
||||||
|
if (this.selectedCodes.size < 4) {
|
||||||
|
this.selectedCodes.add(seat.code);
|
||||||
|
} else {
|
||||||
|
common_vendor.index.showToast({
|
||||||
|
title: "最多只能选择4个座位",
|
||||||
|
icon: "none"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.$refs.canvasRef.redraw();
|
||||||
|
},
|
||||||
async getContainerPosition() {
|
async getContainerPosition() {
|
||||||
let retryCount = 0;
|
let retryCount = 0;
|
||||||
const maxRetries = 3;
|
const maxRetries = 3;
|
||||||
@ -87,7 +108,7 @@ const _sfc_main = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
common_vendor.index.__f__("error", "at pages/index/gesture-canvas-page.vue:140", "获取容器位置失败:", e);
|
common_vendor.index.__f__("error", "at pages/index/gesture-canvas-page.vue:162", "获取容器位置失败:", e);
|
||||||
}
|
}
|
||||||
await new Promise((r) => setTimeout(r, 100));
|
await new Promise((r) => setTimeout(r, 100));
|
||||||
retryCount++;
|
retryCount++;
|
||||||
@ -98,59 +119,75 @@ const _sfc_main = {
|
|||||||
this.gestureHandler = new pages_index_gestureHandler.GestureHandler(this, this.transformMatrix, {
|
this.gestureHandler = new pages_index_gestureHandler.GestureHandler(this, this.transformMatrix, {
|
||||||
container: this.containerRect
|
container: this.containerRect
|
||||||
});
|
});
|
||||||
|
common_vendor.index.__f__("log", "at pages/index/gesture-canvas-page.vue:176", "initGestureHandler", this.gestureHandler);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
common_vendor.index.__f__("error", "at pages/index/gesture-canvas-page.vue:155", "手势处理器初始化失败:", e);
|
common_vendor.index.__f__("error", "at pages/index/gesture-canvas-page.vue:178", "手势处理器初始化失败:", e);
|
||||||
this.gestureHandler = {
|
this.gestureHandler = {
|
||||||
catchEvent: (event) => {
|
catchEvent: this.createGestureFallback(),
|
||||||
if (event.touches.length > 0) {
|
setScale: (scale) => {
|
||||||
this.gestureStatus = "降级模式";
|
this.transformMatrix.scale(scale, scale, this.canvasWidth / 2, this.canvasHeight / 2);
|
||||||
this.touchPoints = event.touches.length;
|
this.updateCanvas();
|
||||||
if (event.type === "touchmove") {
|
},
|
||||||
const firstTouch = event.touches[0];
|
reset: () => {
|
||||||
const x = firstTouch.clientX - this.containerRect.left;
|
this.transformMatrix.reset();
|
||||||
const y = firstTouch.clientY - this.containerRect.top;
|
this.updateCanvas();
|
||||||
this.transformMatrix.tx = x;
|
|
||||||
this.transformMatrix.ty = y;
|
|
||||||
this.updateCanvas();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 事件处理
|
createGestureFallback() {
|
||||||
async handleTouchEvent(event) {
|
let isClick = true;
|
||||||
if (!this.gestureHandler || !this.containerRect) {
|
let startPoint = null;
|
||||||
await this.getContainerPosition();
|
let startTime = null;
|
||||||
this.initGestureHandler();
|
let lastPoint = null;
|
||||||
if (event.type === "touchend" || event.type === "touchcancel") {
|
return (event) => {
|
||||||
this.gestureStatus = "结束";
|
const touches = event.touches || [];
|
||||||
this.updateCanvas();
|
if (touches.length === 1) {
|
||||||
return;
|
const getPoint = (t) => ({
|
||||||
|
x: t.clientX - this.containerRect.left,
|
||||||
|
y: t.clientY - this.containerRect.top
|
||||||
|
});
|
||||||
|
const currentPoint = getPoint(touches[0]);
|
||||||
|
if (!startPoint) {
|
||||||
|
startPoint = currentPoint;
|
||||||
|
startTime = Date.now();
|
||||||
|
}
|
||||||
|
const dx = currentPoint.x - startPoint.x;
|
||||||
|
const dy = currentPoint.y - startPoint.y;
|
||||||
|
const distance = Math.sqrt(dx * dx + dy * dy);
|
||||||
|
if (isClick && distance < 5 && Date.now() - startTime < 200) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
isClick = false;
|
||||||
|
if (lastPoint) {
|
||||||
|
const moveDx = currentPoint.x - lastPoint.x;
|
||||||
|
const moveDy = currentPoint.y - lastPoint.y;
|
||||||
|
this.transformMatrix.tx += moveDx;
|
||||||
|
this.transformMatrix.ty += moveDy;
|
||||||
|
}
|
||||||
|
lastPoint = currentPoint;
|
||||||
|
}
|
||||||
|
if (event.type === "touchend" || event.type === "touchcancel") {
|
||||||
|
isClick = true;
|
||||||
|
startPoint = null;
|
||||||
|
startTime = null;
|
||||||
|
lastPoint = null;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
const currentTime = Date.now();
|
|
||||||
this.touchPoints = event.touches.length;
|
|
||||||
const correctedTouches = Array.from(event.touches).map((touch) => {
|
|
||||||
return {
|
|
||||||
...touch,
|
|
||||||
x: touch.clientX - this.containerRect.left,
|
|
||||||
y: touch.clientY - this.containerRect.top
|
|
||||||
};
|
|
||||||
});
|
|
||||||
const correctedEvent = {
|
|
||||||
...event,
|
|
||||||
touches: correctedTouches,
|
|
||||||
changedTouches: correctedTouches
|
|
||||||
};
|
};
|
||||||
this.gestureHandler.catchEvent(correctedEvent);
|
},
|
||||||
|
async handleTouchEvent(event) {
|
||||||
|
var _a;
|
||||||
|
common_vendor.index.__f__("log", "at pages/index/gesture-canvas-page.vue:251", event, "handleTouchEvent");
|
||||||
|
this.touchPoints = event.touches.length;
|
||||||
if (event.type === "touchstart") {
|
if (event.type === "touchstart") {
|
||||||
this.gestureStatus = event.touches.length > 1 ? "双指开始" : "单指开始";
|
this.gestureStatus = event.touches.length > 1 ? "双指开始" : "单指开始";
|
||||||
} else if (event.type === "touchmove") {
|
|
||||||
this.gestureStatus = event.touches.length > 1 ? "双指缩放/移动" : "单指移动";
|
|
||||||
} else {
|
|
||||||
this.gestureStatus = "结束";
|
|
||||||
}
|
}
|
||||||
|
(_a = this.gestureHandler) == null ? void 0 : _a.catchEvent(event);
|
||||||
|
if (event.type === "touchend" || event.type === "touchcancel") {
|
||||||
|
this.gestureStatus = "结束";
|
||||||
|
this.updateCanvas();
|
||||||
|
}
|
||||||
|
const currentTime = Date.now();
|
||||||
if (currentTime - this.lastGestureTime > 50) {
|
if (currentTime - this.lastGestureTime > 50) {
|
||||||
this.lastGestureTime = currentTime;
|
this.lastGestureTime = currentTime;
|
||||||
this.updateCanvas();
|
this.updateCanvas();
|
||||||
@ -491,7 +528,7 @@ const _sfc_main = {
|
|||||||
};
|
};
|
||||||
this.seatAreas = response.data;
|
this.seatAreas = response.data;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
common_vendor.index.__f__("error", "at pages/index/gesture-canvas-page.vue:574", "加载区域数据失败:", e);
|
common_vendor.index.__f__("error", "at pages/index/gesture-canvas-page.vue:618", "加载区域数据失败:", e);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async loadSeatData(areaCode) {
|
async loadSeatData(areaCode) {
|
||||||
@ -512,11 +549,16 @@ const _sfc_main = {
|
|||||||
});
|
});
|
||||||
this.transformMatrix = new pages_index_transformMatrix.TransformMatrix();
|
this.transformMatrix = new pages_index_transformMatrix.TransformMatrix();
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
|
if (!this.gestureHandler) {
|
||||||
|
this.initGestureHandler();
|
||||||
|
}
|
||||||
if (this.seatPositions.length > 0) {
|
if (this.seatPositions.length > 0) {
|
||||||
const minX = Math.min(...this.seatPositions.map((s) => s.x));
|
const xs = this.seatPositions.map((s) => s.x);
|
||||||
const maxX = Math.max(...this.seatPositions.map((s) => s.x));
|
const ys = this.seatPositions.map((s) => s.y);
|
||||||
const minY = Math.min(...this.seatPositions.map((s) => s.y));
|
const minX = Math.min(...xs);
|
||||||
const maxY = Math.max(...this.seatPositions.map((s) => s.y));
|
const maxX = Math.max(...xs);
|
||||||
|
const minY = Math.min(...ys);
|
||||||
|
const maxY = Math.max(...ys);
|
||||||
const centerX = (minX + maxX) / 2;
|
const centerX = (minX + maxX) / 2;
|
||||||
const centerY = (minY + maxY) / 2;
|
const centerY = (minY + maxY) / 2;
|
||||||
const widthRatio = this.canvasWidth / (maxX - minX + 100);
|
const widthRatio = this.canvasWidth / (maxX - minX + 100);
|
||||||
@ -525,7 +567,7 @@ const _sfc_main = {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
common_vendor.index.__f__("error", "at pages/index/gesture-canvas-page.vue:624", "加载座位数据失败:", e);
|
common_vendor.index.__f__("error", "at pages/index/gesture-canvas-page.vue:676", "加载座位数据失败:", e);
|
||||||
common_vendor.index.showToast({ title: "加载座位失败", icon: "none" });
|
common_vendor.index.showToast({ title: "加载座位失败", icon: "none" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -549,7 +591,8 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|||||||
matrix: $data.transformMatrix,
|
matrix: $data.transformMatrix,
|
||||||
imgUrl: "https://assets.tech.troyrc.com/sx25/images/events/XBDT.jpg",
|
imgUrl: "https://assets.tech.troyrc.com/sx25/images/events/XBDT.jpg",
|
||||||
areaData: $data.currentView === "area" ? $data.seatAreas : [],
|
areaData: $data.currentView === "area" ? $data.seatAreas : [],
|
||||||
seatData: $data.currentView === "seat" ? $data.seatPositions : []
|
seatData: $data.currentView === "seat" ? $data.seatPositions : [],
|
||||||
|
selectedCodes: $data.selectedCodes
|
||||||
}),
|
}),
|
||||||
h: common_vendor.o((...args) => $options.handleTouchEvent && $options.handleTouchEvent(...args)),
|
h: common_vendor.o((...args) => $options.handleTouchEvent && $options.handleTouchEvent(...args)),
|
||||||
i: common_vendor.o((...args) => $options.handleTouchEvent && $options.handleTouchEvent(...args)),
|
i: common_vendor.o((...args) => $options.handleTouchEvent && $options.handleTouchEvent(...args)),
|
||||||
|
@ -6,9 +6,10 @@ class GestureHandler {
|
|||||||
this.containerRect = container;
|
this.containerRect = container;
|
||||||
this.panThreshold = 5;
|
this.panThreshold = 5;
|
||||||
this.panStarted = false;
|
this.panStarted = false;
|
||||||
|
this.context = context;
|
||||||
this.isMiniProgram = typeof common_vendor.wx$1 !== "undefined" || typeof common_vendor.index !== "undefined";
|
this.isMiniProgram = typeof common_vendor.wx$1 !== "undefined" || typeof common_vendor.index !== "undefined";
|
||||||
if (this.isMiniProgram) {
|
if (this.isMiniProgram) {
|
||||||
common_vendor.index.__f__("log", "at pages/index/gesture-handler.js:13", "小程序环境,使用降级手势处理器");
|
common_vendor.index.__f__("log", "at pages/index/gesture-handler.js:14", "小程序环境,使用降级手势处理器");
|
||||||
this.catchEvent = this.createSimpleGestureHandler();
|
this.catchEvent = this.createSimpleGestureHandler();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -35,17 +36,16 @@ class GestureHandler {
|
|||||||
"../../common/vendor.js".then((n) => n.index_es).then((AnyTouch) => {
|
"../../common/vendor.js".then((n) => n.index_es).then((AnyTouch) => {
|
||||||
this.at = new AnyTouch.default(atOptions);
|
this.at = new AnyTouch.default(atOptions);
|
||||||
this.setupGestures();
|
this.setupGestures();
|
||||||
common_vendor.index.__f__("log", "at pages/index/gesture-handler.js:44", "AnyTouch手势处理器已初始化");
|
common_vendor.index.__f__("log", "at pages/index/gesture-handler.js:45", "AnyTouch手势处理器已初始化");
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
common_vendor.index.__f__("error", "at pages/index/gesture-handler.js:46", "AnyTouch加载失败:", e);
|
common_vendor.index.__f__("error", "at pages/index/gesture-handler.js:47", "AnyTouch加载失败:", e);
|
||||||
this.catchEvent = this.createSimpleGestureHandler();
|
this.catchEvent = this.createSimpleGestureHandler();
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
common_vendor.index.__f__("error", "at pages/index/gesture-handler.js:50", "AnyTouch初始化失败:", e);
|
common_vendor.index.__f__("error", "at pages/index/gesture-handler.js:51", "AnyTouch初始化失败:", e);
|
||||||
this.catchEvent = this.createSimpleGestureHandler();
|
this.catchEvent = this.createSimpleGestureHandler();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 创建小程序专用的简化手势处理器
|
|
||||||
createSimpleGestureHandler() {
|
createSimpleGestureHandler() {
|
||||||
let isClick = true;
|
let isClick = true;
|
||||||
let startPoint = null;
|
let startPoint = null;
|
||||||
@ -135,7 +135,7 @@ class GestureHandler {
|
|||||||
this.catchEvent(event);
|
this.catchEvent(event);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
common_vendor.index.__f__("error", "at pages/index/gesture-handler.js:178", "手势处理错误:", e);
|
common_vendor.index.__f__("error", "at pages/index/gesture-handler.js:176", "手势处理错误:", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 基础平移手势处理
|
// 基础平移手势处理
|
||||||
|
@ -21,7 +21,8 @@ const _sfc_main = {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
areaData: {},
|
areaData: {},
|
||||||
seatData: {}
|
seatData: {},
|
||||||
|
selectedCodes: {}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -33,10 +34,17 @@ const _sfc_main = {
|
|||||||
canvasDisplayHeight: 600,
|
canvasDisplayHeight: 600,
|
||||||
canvasActualWidth: 800,
|
canvasActualWidth: 800,
|
||||||
// 实际像素尺寸
|
// 实际像素尺寸
|
||||||
canvasActualHeight: 600
|
canvasActualHeight: 600,
|
||||||
|
nowSelectedCodes: this.selectedCodes
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
selectedCodes: {
|
||||||
|
handler(newVal) {
|
||||||
|
this.nowSelectedCodes = newVal;
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
imgUrl: {
|
imgUrl: {
|
||||||
handler(newUrl) {
|
handler(newUrl) {
|
||||||
if (newUrl)
|
if (newUrl)
|
||||||
@ -81,12 +89,16 @@ const _sfc_main = {
|
|||||||
this.initCanvas();
|
this.initCanvas();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
invertPoint(x, y) {
|
||||||
|
const inverted = this.matrix.invertPoint(x, y);
|
||||||
|
return inverted;
|
||||||
|
},
|
||||||
// 添加点击检测方法
|
// 添加点击检测方法
|
||||||
checkHitArea(x, y) {
|
checkHitArea(x, y) {
|
||||||
if (!this.areaData)
|
if (!this.areaData)
|
||||||
return null;
|
return null;
|
||||||
const inverted = this.matrix.invertPoint(x, y, this.dpr);
|
const inverted = this.matrix.invertPoint(x, y, this.dpr);
|
||||||
common_vendor.index.__f__("log", "at pages/index/transform-canvas.vue:92", "checkHitArea", inverted);
|
common_vendor.index.__f__("log", "at pages/index/transform-canvas.vue:107", "checkHitArea", inverted);
|
||||||
for (const area of this.areaData) {
|
for (const area of this.areaData) {
|
||||||
if (this.pointInPolygon(inverted.x, inverted.y, area.polygon)) {
|
if (this.pointInPolygon(inverted.x, inverted.y, area.polygon)) {
|
||||||
return area;
|
return area;
|
||||||
@ -173,7 +185,7 @@ const _sfc_main = {
|
|||||||
});
|
});
|
||||||
this.redraw();
|
this.redraw();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
common_vendor.index.__f__("error", "at pages/index/transform-canvas.vue:223", "图片加载失败:", e);
|
common_vendor.index.__f__("error", "at pages/index/transform-canvas.vue:238", "图片加载失败:", e);
|
||||||
this.image = null;
|
this.image = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -242,16 +254,40 @@ const _sfc_main = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
drawSeats() {
|
drawSeats() {
|
||||||
const scale = Math.sqrt(this.matrix.a * this.matrix.a + this.matrix.b * this.matrix.b);
|
this.ctx.save();
|
||||||
|
const { a, b, c, d, tx, ty } = this.matrix;
|
||||||
|
this.ctx.setTransform(a, b, c, d, tx, ty);
|
||||||
|
const scale = Math.sqrt(a * a + b * b);
|
||||||
this.seatData.forEach((seat) => {
|
this.seatData.forEach((seat) => {
|
||||||
const x = seat.x;
|
const x = seat.x;
|
||||||
const y = seat.y;
|
const y = seat.y;
|
||||||
this.ctx.beginPath();
|
|
||||||
const radius = 8 / scale;
|
const radius = 8 / scale;
|
||||||
this.ctx.arc(x, y, radius, 0, Math.PI * 2);
|
if (this.nowSelectedCodes.has(seat.code) && seat.status === 1) {
|
||||||
this.ctx.fillStyle = seat.status === 1 ? "#4cd964" : "#dd524d";
|
this.ctx.beginPath();
|
||||||
this.ctx.fill();
|
this.ctx.arc(x, y, radius + 1, 0, Math.PI * 2);
|
||||||
|
this.ctx.strokeStyle = "#FFD700";
|
||||||
|
this.ctx.lineWidth = 2 / scale;
|
||||||
|
this.ctx.stroke();
|
||||||
|
this.ctx.beginPath();
|
||||||
|
this.ctx.arc(x, y, radius, 0, Math.PI * 2);
|
||||||
|
this.ctx.fillStyle = "rgba(255, 215, 0, 0.3)";
|
||||||
|
this.ctx.fill();
|
||||||
|
this.ctx.strokeStyle = "#fff";
|
||||||
|
this.ctx.lineWidth = 1 / scale;
|
||||||
|
this.ctx.lineCap = "round";
|
||||||
|
this.ctx.beginPath();
|
||||||
|
this.ctx.moveTo(x - 2.5, y);
|
||||||
|
this.ctx.lineTo(x - 0.5, y + 1.5);
|
||||||
|
this.ctx.lineTo(x + 2.5, y - 2);
|
||||||
|
this.ctx.stroke();
|
||||||
|
} else {
|
||||||
|
this.ctx.beginPath();
|
||||||
|
this.ctx.arc(x, y, radius, 0, Math.PI * 2);
|
||||||
|
this.ctx.fillStyle = seat.status === 1 ? "#4cd964" : "#dd524d";
|
||||||
|
this.ctx.fill();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
this.ctx.restore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user