175 lines
6.3 KiB
JavaScript
175 lines
6.3 KiB
JavaScript
"use strict";
|
|
const common_vendor = require("../../common/vendor.js");
|
|
const _sfc_main = {
|
|
data() {
|
|
return {
|
|
ctx: null,
|
|
canvasWidth: 0,
|
|
canvasHeight: 0,
|
|
seatSize: 30,
|
|
gap: 10,
|
|
rows: 8,
|
|
cols: 10,
|
|
seats: [],
|
|
selectedSeats: [],
|
|
touchStartX: 0,
|
|
touchStartY: 0,
|
|
offsetX: 0,
|
|
offsetY: 0,
|
|
scale: 1
|
|
};
|
|
},
|
|
onReady() {
|
|
this.initSeats();
|
|
this.initCanvas();
|
|
},
|
|
methods: {
|
|
initSeats() {
|
|
for (let i = 0; i < this.rows; i++) {
|
|
this.seats[i] = [];
|
|
for (let j = 0; j < this.cols; j++) {
|
|
const isSold = Math.random() < 0.2;
|
|
this.seats[i][j] = {
|
|
row: i,
|
|
col: j,
|
|
status: isSold ? "sold" : "available",
|
|
// available, selected, sold
|
|
x: 0,
|
|
y: 0
|
|
};
|
|
}
|
|
}
|
|
},
|
|
async initCanvas() {
|
|
const { canvas, width, height } = await this.getCanvasNode("seatCanvas");
|
|
this.canvasWidth = width;
|
|
this.canvasHeight = height;
|
|
this.ctx = canvas.getContext("2d");
|
|
const totalWidth = this.cols * (this.seatSize + this.gap) - this.gap;
|
|
const totalHeight = this.rows * (this.seatSize + this.gap) - this.gap;
|
|
this.offsetX = (this.canvasWidth - totalWidth) / 2;
|
|
this.offsetY = (this.canvasHeight - totalHeight) / 2;
|
|
this.drawSeats();
|
|
},
|
|
getCanvasNode(id) {
|
|
return new Promise((resolve) => {
|
|
const query = common_vendor.index.createSelectorQuery().in(this);
|
|
query.select(`#${id}`).fields({ node: true, size: true }).exec((res) => {
|
|
common_vendor.index.__f__("log", "at pages/index/index.vue:94", "给我看看", res);
|
|
common_vendor.index.__f__("log", "at pages/index/index.vue:95", "给我看看", res);
|
|
common_vendor.index.__f__("log", "at pages/index/index.vue:96", "给我看看", res);
|
|
common_vendor.index.__f__("log", "at pages/index/index.vue:97", "给我看看", res);
|
|
common_vendor.index.__f__("log", "at pages/index/index.vue:98", "给我看看", res);
|
|
common_vendor.index.__f__("log", "at pages/index/index.vue:99", "给我看看", res);
|
|
const canvas = res[0].node;
|
|
const width = res[0].width;
|
|
const height = res[0].height;
|
|
canvas.width = width * common_vendor.index.getSystemInfoSync().pixelRatio;
|
|
canvas.height = height * common_vendor.index.getSystemInfoSync().pixelRatio;
|
|
resolve({ canvas, width, height });
|
|
});
|
|
});
|
|
},
|
|
drawSeats() {
|
|
if (!this.ctx)
|
|
return;
|
|
this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
|
|
this.ctx.save();
|
|
this.ctx.translate(this.offsetX, this.offsetY);
|
|
this.ctx.scale(this.scale, this.scale);
|
|
for (let i = 0; i < this.rows; i++) {
|
|
for (let j = 0; j < this.cols; j++) {
|
|
const seat = this.seats[i][j];
|
|
const x = j * (this.seatSize + this.gap);
|
|
const y = i * (this.seatSize + this.gap);
|
|
seat.x = x;
|
|
seat.y = y;
|
|
switch (seat.status) {
|
|
case "available":
|
|
this.ctx.fillStyle = "#4CAF50";
|
|
break;
|
|
case "selected":
|
|
this.ctx.fillStyle = "#2196F3";
|
|
break;
|
|
case "sold":
|
|
this.ctx.fillStyle = "#9E9E9E";
|
|
break;
|
|
}
|
|
this.ctx.beginPath();
|
|
this.ctx.roundRect(x, y, this.seatSize, this.seatSize, 4);
|
|
this.ctx.fill();
|
|
this.ctx.fillStyle = "#FFFFFF";
|
|
this.ctx.font = "12px Arial";
|
|
this.ctx.textAlign = "center";
|
|
this.ctx.textBaseline = "middle";
|
|
this.ctx.fillText(
|
|
`${String.fromCharCode(65 + i)}${j + 1}`,
|
|
x + this.seatSize / 2,
|
|
y + this.seatSize / 2
|
|
);
|
|
}
|
|
}
|
|
this.ctx.restore();
|
|
},
|
|
handleTouchStart(e) {
|
|
this.touchStartX = e.touches[0].x;
|
|
this.touchStartY = e.touches[0].y;
|
|
},
|
|
handleTouchMove(e) {
|
|
const touchX = e.touches[0].x;
|
|
const touchY = e.touches[0].y;
|
|
const dx = touchX - this.touchStartX;
|
|
const dy = touchY - this.touchStartY;
|
|
this.offsetX += dx;
|
|
this.offsetY += dy;
|
|
const minX = this.canvasWidth - (this.cols * (this.seatSize + this.gap) - this.gap) * this.scale;
|
|
const minY = this.canvasHeight - (this.rows * (this.seatSize + this.gap) - this.gap) * this.scale;
|
|
this.offsetX = Math.max(minX, Math.min(0, this.offsetX));
|
|
this.offsetY = Math.max(minY, Math.min(0, this.offsetY));
|
|
this.touchStartX = touchX;
|
|
this.touchStartY = touchY;
|
|
this.drawSeats();
|
|
},
|
|
handleTouchEnd(e) {
|
|
const touchX = e.changedTouches[0].x;
|
|
const touchY = e.changedTouches[0].y;
|
|
const canvasX = (touchX - this.offsetX) / this.scale;
|
|
const canvasY = (touchY - this.offsetY) / this.scale;
|
|
for (let i = 0; i < this.rows; i++) {
|
|
for (let j = 0; j < this.cols; j++) {
|
|
const seat = this.seats[i][j];
|
|
if (canvasX >= seat.x && canvasX <= seat.x + this.seatSize && canvasY >= seat.y && canvasY <= seat.y + this.seatSize) {
|
|
this.toggleSeatSelection(seat);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
},
|
|
toggleSeatSelection(seat) {
|
|
if (seat.status === "sold")
|
|
return;
|
|
if (seat.status === "available") {
|
|
seat.status = "selected";
|
|
this.selectedSeats.push(`${String.fromCharCode(65 + seat.row)}${seat.col + 1}`);
|
|
} else {
|
|
seat.status = "available";
|
|
this.selectedSeats = this.selectedSeats.filter(
|
|
(s) => s !== `${String.fromCharCode(65 + seat.row)}${seat.col + 1}`
|
|
);
|
|
}
|
|
this.drawSeats();
|
|
}
|
|
}
|
|
};
|
|
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
return {
|
|
a: common_vendor.o((...args) => $options.handleTouchStart && $options.handleTouchStart(...args)),
|
|
b: common_vendor.o((...args) => $options.handleTouchMove && $options.handleTouchMove(...args)),
|
|
c: common_vendor.o((...args) => $options.handleTouchEnd && $options.handleTouchEnd(...args)),
|
|
d: common_vendor.t($data.selectedSeats.join(", ") || "无")
|
|
};
|
|
}
|
|
const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);
|
|
wx.createPage(MiniProgramPage);
|
|
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/index/index.js.map
|