Compare commits
4 Commits
main_canva
...
main_canva
Author | SHA1 | Date | |
---|---|---|---|
63f31530fc | |||
a2f3daa2ce | |||
8cba464fc0 | |||
4242018a6d |
@ -7,7 +7,13 @@
|
||||
"transformPx" : false,
|
||||
/* 5+App特有相关 */
|
||||
"app-plus" : {
|
||||
"usingComponents" : true,
|
||||
"canvas2d": true,
|
||||
"optimization": {
|
||||
"subPackages": true
|
||||
},
|
||||
"usingComponents": {
|
||||
"canvas": true
|
||||
},
|
||||
"nvueStyleCompiler" : "uni-app",
|
||||
"compilerVersion" : 3,
|
||||
"splashscreen" : {
|
||||
|
@ -1,11 +1,17 @@
|
||||
{
|
||||
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||
{
|
||||
"path": "pages/index/step2",
|
||||
"style": {
|
||||
"navigationBarTitleText": "fu"
|
||||
}
|
||||
},{
|
||||
"path": "pages/index/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "uni-app"
|
||||
}
|
||||
}
|
||||
|
||||
],
|
||||
"globalStyle": {
|
||||
"navigationBarTextStyle": "black",
|
||||
|
@ -1,46 +1,310 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- 定义canvas画布 // 设置canvas大小为200x200像素 -->
|
||||
<canvas canvas-id="canvas" id="canvas" style="width: 200px; height: 200px;"></canvas>
|
||||
|
||||
<!-- 添加一个按钮,用于触发绘图 -->
|
||||
<button @click="handleDraw()">点击绘制圆形</button>
|
||||
<view class="container">
|
||||
<view class="screen">银幕</view>
|
||||
<canvas
|
||||
canvas-id="seatCanvas"
|
||||
type="2d"
|
||||
class="seat-canvas"
|
||||
@touchstart="handleTouchStart"
|
||||
@touchmove="handleTouchMove"
|
||||
@touchend="handleTouchEnd"
|
||||
></canvas>
|
||||
<view class="legend">
|
||||
<view class="legend-item">
|
||||
<view class="seat-icon available"></view>
|
||||
<text>可选</text>
|
||||
</view>
|
||||
<view class="legend-item">
|
||||
<view class="seat-icon selected"></view>
|
||||
<text>已选</text>
|
||||
</view>
|
||||
<view class="legend-item">
|
||||
<view class="seat-icon sold"></view>
|
||||
<text>已售</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="selected-seats">
|
||||
<text>已选座位:{{ selectedSeats.join(', ') || '无' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
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() {
|
||||
// 获取canvas上下文
|
||||
const { canvas, width, height } = await this.getCanvasNode('seatCanvas')
|
||||
this.canvasWidth = width
|
||||
this.canvasHeight = height
|
||||
this.ctx = canvas.getContext('2d')
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
} from 'vue'
|
||||
// 计算初始偏移使座位居中
|
||||
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
|
||||
|
||||
// 定义绘图函数
|
||||
function draw() {
|
||||
const ctx = uni.createCanvasContext('canvas') // 创建canvas绘图上下文
|
||||
this.drawSeats()
|
||||
},
|
||||
getCanvasNode(id) {
|
||||
return new Promise((resolve) => {
|
||||
const query = uni.createSelectorQuery().in(this)
|
||||
query.select(`#${id}`)
|
||||
.fields({ node: true, size: true })
|
||||
.exec((res) => {
|
||||
console.log('给我看看',res)
|
||||
console.log('给我看看',res)
|
||||
console.log('给我看看',res)
|
||||
console.log('给我看看',res)
|
||||
console.log('给我看看',res)
|
||||
console.log('给我看看',res)
|
||||
const canvas = res[0].node
|
||||
const width = res[0].width
|
||||
const height = res[0].height
|
||||
// 设置canvas实际宽高
|
||||
canvas.width = width * uni.getSystemInfoSync().pixelRatio
|
||||
canvas.height = height * uni.getSystemInfoSync().pixelRatio
|
||||
resolve({ canvas, width, height })
|
||||
})
|
||||
})
|
||||
},
|
||||
drawSeats() {
|
||||
if (!this.ctx) return
|
||||
|
||||
// 绘制外圆
|
||||
ctx.beginPath() // 开始路径
|
||||
ctx.arc(100, 100, 80, 0, Math.PI * 2) // 在坐标(100, 100)处绘制半径为80的圆形
|
||||
ctx.setFillStyle('rgba(0, 0, 0, 1)') // 设置填充颜色为黑色,无透明度
|
||||
ctx.fill() // 填充所创建的路径
|
||||
// 清空画布
|
||||
this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
|
||||
|
||||
// 绘制内圆以形成环形效果
|
||||
ctx.beginPath() // 开始新的路径
|
||||
ctx.arc(100, 100, 75, 0, Math.PI * 2) // 在相同中心点(100, 100),但半径为60的圆形
|
||||
ctx.setFillStyle('white') // 设置填充颜色为白色
|
||||
ctx.fill() // 填充以“清除”内部区域,形成环形
|
||||
ctx.draw() // 将上述所有操作提交到canvas进行渲染
|
||||
// 保存当前状态
|
||||
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
|
||||
}
|
||||
|
||||
// 按钮点击事件处理函数
|
||||
const handleDraw = () => {
|
||||
draw(); // 调用绘图函数
|
||||
// 绘制座位
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 20rpx;
|
||||
height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
<style scoped>
|
||||
/* 样式部分 */
|
||||
button {
|
||||
margin-top: 10px;
|
||||
/* 给按钮设置一些上边距以避免过于紧凑 */
|
||||
.screen {
|
||||
width: 80%;
|
||||
height: 40rpx;
|
||||
background: linear-gradient(to bottom, #ccc, #fff);
|
||||
margin-bottom: 40rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
border-radius: 8rpx;
|
||||
box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.seat-canvas {
|
||||
width: 100%;
|
||||
height: 500rpx;
|
||||
background-color: #fff;
|
||||
margin-bottom: 20rpx;
|
||||
border-radius: 8rpx;
|
||||
box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.legend {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.legend-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0 20rpx;
|
||||
}
|
||||
|
||||
.seat-icon {
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
margin-right: 10rpx;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
.available {
|
||||
background-color: #4CAF50;
|
||||
}
|
||||
|
||||
.selected {
|
||||
background-color: #2196F3;
|
||||
}
|
||||
|
||||
.sold {
|
||||
background-color: #9E9E9E;
|
||||
}
|
||||
|
||||
.selected-seats {
|
||||
padding: 20rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 8rpx;
|
||||
width: 90%;
|
||||
text-align: center;
|
||||
box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
</style>
|
428
pages/index/step2.vue
Normal file
428
pages/index/step2.vue
Normal file
@ -0,0 +1,428 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<canvas
|
||||
canvas-id="selectCanvas"
|
||||
id="selectCanvas"
|
||||
type="2d"
|
||||
disable-scroll="true"
|
||||
@touchstart="handleTouchStart"
|
||||
:style="{
|
||||
width: canvasWidth + 'px',
|
||||
height: canvasHeight + 'px'
|
||||
}"
|
||||
></canvas>
|
||||
|
||||
<view class="selection-info" v-if="selectedArea">
|
||||
当前选中:{{selectedArea.areaname}} (剩余:{{selectedArea.remain}})
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
canvasWidth: 300,
|
||||
canvasHeight: 400,
|
||||
ctx: null,
|
||||
areas: [], // 从接口获取的区域数据
|
||||
selectedArea: null,
|
||||
colorMap: {
|
||||
'A区': '#FF5252',
|
||||
'B区': '#4CAF50',
|
||||
'C区': '#2196F3',
|
||||
'D区': '#FFC107'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
async onLoad() {
|
||||
// 模拟API请求
|
||||
await this.loadAreaData();
|
||||
},
|
||||
|
||||
onReady() {
|
||||
setTimeout(() => {
|
||||
this.initCanvas().catch(e => {
|
||||
console.error('初始化失败:', e);
|
||||
uni.showToast({
|
||||
title: '画布初始化失败',
|
||||
icon: 'none'
|
||||
});
|
||||
});
|
||||
}, 300);
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 模拟加载区域数据
|
||||
async loadAreaData() {
|
||||
try {
|
||||
// 这里替换为您的实际API请求
|
||||
const data = [{
|
||||
"areacode": "lg0umpjukrdn",
|
||||
"areaname": "C4区",
|
||||
"description": "C4区",
|
||||
"remain": 94,
|
||||
"polygon": [131, 184, 130, 196, 146, 201, 174, 208, 174, 215, 215, 215, 258, 215, 258, 205, 257, 192, 258, 184, 215, 184, 174, 184, 131, 184]
|
||||
}, {
|
||||
"areacode": "pnk4022gt71m",
|
||||
"areaname": "A4区-一层",
|
||||
"description": "A4区-一层",
|
||||
"remain": 0,
|
||||
"polygon": [490, 464, 490, 475, 490, 488, 490, 499, 532, 499, 572, 499, 614, 499, 614, 488, 599, 480, 586, 474, 572, 464, 532, 464, 490, 464]
|
||||
}, {
|
||||
"areacode": "e0jhx1sa8194",
|
||||
"areaname": "D1区-一层",
|
||||
"description": "D1区-一层",
|
||||
"remain": 247,
|
||||
"polygon": [604, 345, 603, 385, 604, 396, 624, 439, 643, 437, 644, 417, 643, 396, 644, 367, 644, 344, 616, 345, 644, 346, 630, 344, 604, 345]
|
||||
}, {
|
||||
"areacode": "qxhs4574ffrh",
|
||||
"areaname": "D1区-二层",
|
||||
"description": "D1区-二层",
|
||||
"remain": 191,
|
||||
"polygon": [648, 349, 648, 386, 648, 425, 648, 452, 668, 452, 668, 462, 674, 462, 674, 425, 674, 386, 674, 349, 666, 349, 656, 349, 648, 349]
|
||||
}, {
|
||||
"areacode": "ar2q2e74ffrj",
|
||||
"areaname": "D2区-二层",
|
||||
"description": "D2区-二层",
|
||||
"remain": 122,
|
||||
"polygon": [647, 240, 648, 270, 648, 309, 648, 350, 657, 350, 665, 350, 673, 350, 673, 309, 673, 270, 673, 229, 667, 229, 667, 239, 647, 240]
|
||||
}, {
|
||||
"areacode": "qar2r374ffrl",
|
||||
"areaname": "D2区-一层",
|
||||
"description": "D2区-一层",
|
||||
"remain": 153,
|
||||
"polygon": [617, 266, 605, 285, 606, 303, 606, 342, 626, 341, 645, 342, 643, 341, 642, 302, 642, 278, 642, 263, 642, 249, 626, 248, 617, 266]
|
||||
}, {
|
||||
"areacode": "fpfaxmsa816f",
|
||||
"areaname": "A2区-一层",
|
||||
"description": "A2区-一层",
|
||||
"remain": 0,
|
||||
"polygon": [269, 463, 269, 476, 269, 488, 269, 501, 301, 501, 332, 501, 364, 501, 364, 488, 364, 476, 364, 463, 332, 463, 301, 463, 269, 463]
|
||||
}, {
|
||||
"areacode": "tse56pjukrdx",
|
||||
"areaname": "C3区",
|
||||
"description": "C3区",
|
||||
"remain": 215,
|
||||
"polygon": [279, 141, 279, 174, 266, 173, 265, 180, 308, 180, 339, 180, 369, 180, 369, 167, 369, 154, 369, 141, 339, 141, 308, 141, 279, 141]
|
||||
}, {
|
||||
"areacode": "lpkym7ej0kmd",
|
||||
"areaname": "B1区-一层",
|
||||
"description": "B1区-一层",
|
||||
"remain": 248,
|
||||
"polygon": [104, 250, 104, 282, 104, 313, 104, 345, 118, 345, 131, 345, 145, 345, 145, 313, 145, 288, 138, 276, 131, 263, 123, 250, 104, 250]
|
||||
}, {
|
||||
"areacode": "r6xrfc2gt71x",
|
||||
"areaname": "C3区",
|
||||
"description": "C3区",
|
||||
"remain": 143,
|
||||
"polygon": [269, 186, 269, 196, 269, 207, 269, 217, 300, 217, 333, 217, 364, 217, 364, 207, 364, 196, 364, 186, 333, 186, 300, 186, 269, 186]
|
||||
}, {
|
||||
"areacode": "h84jstej0kmf",
|
||||
"areaname": "C1区",
|
||||
"description": "C1区",
|
||||
"remain": 337,
|
||||
"polygon": [477, 133, 476, 168, 491, 168, 491, 179, 519, 178, 690, 179, 689, 170, 660, 170, 659, 140, 670, 140, 670, 134, 530, 134, 477, 133]
|
||||
}, {
|
||||
"areacode": "tqaegcej0kmg",
|
||||
"areaname": "A2区-二层",
|
||||
"description": "A2区-二层",
|
||||
"remain": 0,
|
||||
"polygon": [278, 514, 277, 526, 256, 525, 256, 542, 289, 542, 311, 542, 311, 531, 364, 533, 364, 525, 352, 525, 352, 513, 303, 513, 278, 514]
|
||||
}, {
|
||||
"areacode": "606fa9ej0kmh",
|
||||
"areaname": "A3区-一层",
|
||||
"description": "A3区-一层",
|
||||
"remain": 0,
|
||||
"polygon": [384, 466, 384, 477, 384, 489, 384, 500, 416, 500, 447, 500, 479, 500, 479, 489, 479, 477, 479, 466, 447, 466, 416, 466, 384, 466]
|
||||
}, {
|
||||
"areacode": "2x9j4bej0km8",
|
||||
"areaname": "B1区-二层",
|
||||
"description": "B1区-二层",
|
||||
"remain": 192,
|
||||
"polygon": [74, 231, 73, 270, 73, 304, 73, 340, 84, 340, 91, 340, 101, 340, 101, 304, 101, 283, 100, 239, 80, 238, 80, 230, 74, 231]
|
||||
}, {
|
||||
"areacode": "81mj022gt723",
|
||||
"areaname": "A4区-二层",
|
||||
"description": "A4区-二层",
|
||||
"remain": 0,
|
||||
"polygon": [513, 511, 513, 525, 493, 525, 493, 547, 556, 547, 624, 547, 657, 546, 657, 513, 687, 513, 688, 501, 489, 500, 490, 511, 513, 511]
|
||||
}, {
|
||||
"areacode": "f217dy2gt72f",
|
||||
"areaname": "C2区",
|
||||
"description": "C2区",
|
||||
"remain": 136,
|
||||
"polygon": [372, 144, 372, 156, 372, 168, 372, 180, 403, 180, 434, 180, 481, 180, 481, 175, 467, 175, 467, 144, 434, 144, 403, 144, 372, 144]
|
||||
}, {
|
||||
"areacode": "crxllrjukre8",
|
||||
"areaname": "A3区-二层",
|
||||
"description": "A3区-二层",
|
||||
"remain": 0,
|
||||
"polygon": [386, 515, 387, 528, 376, 527, 376, 535, 436, 533, 436, 545, 486, 545, 486, 534, 486, 526, 463, 526, 464, 515, 411, 515, 386, 515]
|
||||
}, {
|
||||
"areacode": "kb8wtgjukre9",
|
||||
"areaname": "C2区",
|
||||
"description": "C2区",
|
||||
"remain": 144,
|
||||
"polygon": [386, 186, 386, 197, 386, 206, 386, 217, 416, 217, 448, 217, 478, 217, 478, 206, 478, 197, 478, 186, 448, 186, 416, 186, 386, 186]
|
||||
}, {
|
||||
"areacode": "0wrt1djukrea",
|
||||
"areaname": "C1区",
|
||||
"description": "C1区",
|
||||
"remain": 60,
|
||||
"polygon": [496, 184, 496, 194, 496, 205, 496, 215, 571, 214, 572, 204, 587, 205, 598, 202, 614, 194, 614, 184, 574, 184, 536, 184, 496, 184]
|
||||
}, {
|
||||
"areacode": "hya95p74ffs3",
|
||||
"areaname": "B2区-二层",
|
||||
"description": "B2区-二层",
|
||||
"remain": 191,
|
||||
"polygon": [73, 337, 73, 378, 72, 415, 73, 457, 78, 457, 78, 449, 100, 449, 101, 415, 100, 394, 101, 337, 92, 337, 82, 337, 73, 337]
|
||||
}, {
|
||||
"areacode": "rrw413jukre2",
|
||||
"areaname": "A1区-一层",
|
||||
"description": "A1区-一层",
|
||||
"remain": 0,
|
||||
"polygon": [256, 465, 256, 476, 256, 489, 256, 499, 213, 499, 172, 499, 129, 499, 129, 485, 144, 479, 158, 473, 172, 465, 213, 465, 256, 465]
|
||||
}, {
|
||||
"areacode": "sagsr1sa816m",
|
||||
"areaname": "C4区",
|
||||
"description": "C4区",
|
||||
"remain": 490,
|
||||
"polygon": [88, 139, 89, 171, 61, 172, 60, 181, 224, 181, 259, 182, 259, 174, 273, 173, 272, 154, 273, 131, 77, 132, 77, 139, 88, 139]
|
||||
}, {
|
||||
"areacode": "eqk4nyjukre4",
|
||||
"areaname": "B2区一层",
|
||||
"description": "B2区一层",
|
||||
"remain": 247,
|
||||
"polygon": [104, 344, 104, 376, 104, 406, 104, 438, 123, 438, 128, 425, 134, 415, 143, 399, 144, 376, 144, 344, 130, 344, 118, 344, 104, 344]
|
||||
}, {
|
||||
"areacode": "rrtc9e2gt72d",
|
||||
"areaname": "A1区-二层",
|
||||
"description": "A1区-二层",
|
||||
"remain": 0,
|
||||
"polygon": [62, 501, 62, 509, 90, 510, 89, 549, 250, 548, 250, 527, 231, 528, 230, 510, 254, 509, 254, 501, 191, 501, 125, 501, 62, 501]
|
||||
}]
|
||||
this.areas = data.map(area => ({
|
||||
...area,
|
||||
color: this.getAreaColor(area.areaname),
|
||||
// 转换多边形为绘制路径
|
||||
path: this.parsePolygon(area.polygon)
|
||||
}));
|
||||
} catch (error) {
|
||||
console.error('数据加载失败:', error);
|
||||
}
|
||||
},
|
||||
|
||||
// 根据区域名称获取颜色
|
||||
getAreaColor(name) {
|
||||
for (const [key, value] of Object.entries(this.colorMap)) {
|
||||
if (name.includes(key)) return value;
|
||||
}
|
||||
return '#9E9E9E'; // 默认颜色
|
||||
},
|
||||
|
||||
// 解析多边形数据
|
||||
parsePolygon(points) {
|
||||
const path = [];
|
||||
// 检查输入数据
|
||||
if (!points || !Array.isArray(points) || points.length % 2 !== 0) {
|
||||
console.error('无效的多边形数据:', points);
|
||||
return path;
|
||||
}
|
||||
|
||||
for (let i = 0; i < points.length; i += 2) {
|
||||
// 确保坐标是数字
|
||||
const x = Number(points[i]);
|
||||
const y = Number(points[i+1]);
|
||||
if (!isNaN(x) && !isNaN(y)) {
|
||||
path.push({ x, y });
|
||||
} else {
|
||||
console.warn('忽略无效坐标:', points[i], points[i+1]);
|
||||
}
|
||||
}
|
||||
|
||||
// 确保多边形闭合
|
||||
if (path.length > 0 &&
|
||||
(path[0].x !== path[path.length-1].x ||
|
||||
path[0].y !== path[path.length-1].y)) {
|
||||
path.push({...path[0]});
|
||||
}
|
||||
|
||||
return path;
|
||||
},
|
||||
|
||||
async initCanvas() {
|
||||
try {
|
||||
// 获取Canvas节点
|
||||
const canvasNode = await new Promise((resolve, reject) => {
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query.select('#selectCanvas')
|
||||
.fields({ node: true, size: true })
|
||||
.exec(res => {
|
||||
res[0]?.node ? resolve(res[0].node) : reject('Canvas节点获取失败');
|
||||
});
|
||||
});
|
||||
|
||||
// 获取系统信息
|
||||
const systemInfo = uni.getSystemInfoSync();
|
||||
|
||||
// 设置Canvas的显示尺寸(CSS像素)
|
||||
this.canvasWidth = systemInfo.windowWidth;
|
||||
this.canvasHeight = systemInfo.windowHeight * 0.8;
|
||||
|
||||
// 设置Canvas的实际像素尺寸(考虑设备像素比)
|
||||
const dpr = systemInfo.pixelRatio || 1;
|
||||
canvasNode.width = this.canvasWidth * dpr;
|
||||
canvasNode.height = this.canvasHeight * dpr;
|
||||
|
||||
// 初始化上下文
|
||||
this.ctx = uni.createCanvasContext('selectCanvas', this);
|
||||
|
||||
// 缩放上下文以匹配设备像素比
|
||||
this.ctx.scale(dpr, dpr);
|
||||
|
||||
// 绘制内容
|
||||
this.drawAllAreas();
|
||||
|
||||
} catch (error) {
|
||||
console.error('初始化失败:', error);
|
||||
this.useFallbackRender();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// 绘制所有区域
|
||||
drawAllAreas() {
|
||||
// 清空画布
|
||||
this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
|
||||
|
||||
// 绘制背景
|
||||
this.ctx.setFillStyle('#f5f5f5');
|
||||
this.ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight);
|
||||
|
||||
// 绘制所有区域
|
||||
this.areas.forEach(area => {
|
||||
this.drawArea(area);
|
||||
});
|
||||
|
||||
this.ctx.draw();
|
||||
},
|
||||
|
||||
// 绘制单个区域
|
||||
drawArea(area) {
|
||||
this.ctx.beginPath();
|
||||
this.ctx.moveTo(area.path[0].x, area.path[0].y);
|
||||
|
||||
for (let i = 1; i < area.path.length; i++) {
|
||||
this.ctx.lineTo(area.path[i].x, area.path[i].y);
|
||||
}
|
||||
|
||||
this.ctx.closePath();
|
||||
this.ctx.setFillStyle(area.color);
|
||||
this.ctx.fill();
|
||||
|
||||
// 如果是选中状态,添加边框
|
||||
if (this.selectedArea === area) {
|
||||
this.ctx.setStrokeStyle('#000000');
|
||||
this.ctx.setLineWidth(2);
|
||||
this.ctx.stroke();
|
||||
}
|
||||
},
|
||||
|
||||
// 检查点击了哪个区域
|
||||
async checkAreaSelection(x, y) {
|
||||
return new Promise((resolve) => {
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query.select('#selectCanvas')
|
||||
.boundingClientRect(rect => {
|
||||
if (!rect) return resolve(null);
|
||||
|
||||
// 转换坐标到Canvas坐标系
|
||||
const canvasX = x - rect.left;
|
||||
const canvasY = y - rect.top;
|
||||
|
||||
// 使用isPointInPath检测(简化版)
|
||||
const clickedArea = this.areas.find(area =>
|
||||
this.isPointInPolygon(canvasX, canvasY, area.path)
|
||||
);
|
||||
|
||||
resolve(clickedArea);
|
||||
})
|
||||
.exec();
|
||||
});
|
||||
},
|
||||
|
||||
// 判断点是否在多边形内
|
||||
isPointInPolygon(x, y, polygon) {
|
||||
// 添加参数检查
|
||||
if (!polygon || !Array.isArray(polygon) || polygon.length < 3) {
|
||||
console.warn('无效的多边形数据', polygon);
|
||||
return false;
|
||||
}
|
||||
|
||||
let inside = false;
|
||||
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
||||
const xi = polygon[i].x, yi = polygon[i].y;
|
||||
const xj = polygon[j].x, yj = polygon[j].y;
|
||||
|
||||
// 添加坐标检查
|
||||
if (isNaN(xi) || isNaN(yi) || isNaN(xj) || isNaN(yj)) {
|
||||
console.warn('无效的坐标点', {xi, yi, xj, yj});
|
||||
return false;
|
||||
}
|
||||
|
||||
const intersect = ((yi > y) !== (yj > y))
|
||||
&& (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
|
||||
if (intersect) inside = !inside;
|
||||
}
|
||||
return inside;
|
||||
},
|
||||
// 处理触摸开始
|
||||
async handleTouchStart(e) {
|
||||
const touch = e.touches[0];
|
||||
const clickedArea = await this.checkAreaSelection(touch.clientX, touch.clientY);
|
||||
|
||||
if (clickedArea) {
|
||||
this.selectedArea = clickedArea;
|
||||
this.drawAllAreas();
|
||||
|
||||
uni.showToast({
|
||||
title: `选中: ${clickedArea.areaname}`,
|
||||
icon: 'none'
|
||||
});
|
||||
|
||||
// 返回选中区域数据
|
||||
this.$emit('area-selected', {
|
||||
areacode: clickedArea.areacode,
|
||||
areaname: clickedArea.areaname,
|
||||
remain: clickedArea.remain
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
canvas {
|
||||
width: 100%;
|
||||
height: 80%;
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.selection-info {
|
||||
padding: 15px;
|
||||
background-color: #fff;
|
||||
border-top: 1px solid #eee;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
11
unpackage/dist/dev/.nvue/app.css.js
vendored
Normal file
11
unpackage/dist/dev/.nvue/app.css.js
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __commonJS = (cb, mod) => function __require() {
|
||||
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
||||
};
|
||||
var require_app_css = __commonJS({
|
||||
"app.css.js"(exports) {
|
||||
const _style_0 = {};
|
||||
exports.styles = [_style_0];
|
||||
}
|
||||
});
|
||||
export default require_app_css();
|
2
unpackage/dist/dev/.nvue/app.js
vendored
Normal file
2
unpackage/dist/dev/.nvue/app.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
Promise.resolve("./app.css.js").then(() => {
|
||||
});
|
1
unpackage/dist/dev/.sourcemap/mp-weixin-devtools/index.js.map
vendored
Normal file
1
unpackage/dist/dev/.sourcemap/mp-weixin-devtools/index.js.map
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"names":["canvasWidth","common_vendor","ref","canvasHeight","draw","ctx","index","createCanvasContext","__f__","beginPath","arc","Math","PI","setFillStyle","fill","setTimeout","handleDraw","onMounted"],"sources":["index.vue"],"sourcesContent":["<template>\n\t<view>\n\t\t<!-- 定义canvas画布 // 设置canvas大小为200x200像素 -->\n\t\t<canvas canvas-id=\"canvas\" id=\"canvas\" style=\"width: 200px; height: 200px;border: 1px solid red;\" :width=\"canvasWidth\" :height=\"canvasHeight\"></canvas>\n\n\t\t<!-- 添加一个按钮,用于触发绘图 -->\n\t\t<button @click=\"handleDraw\">点击绘制圆形</button>\n\t</view>\n</template>\n\n<script setup>\n\timport { ref, onMounted } from 'vue'\n\n\tconst canvasWidth = ref(200) // 动态设置Canvas宽度\n\tconst canvasHeight = ref(200) // 动态设置Canvas高度\n\n\t// 定义绘图函数\n\tfunction draw() {\n\t\tconst ctx = uni.createCanvasContext('canvas',this) // 创建canvas绘图上下文\r\n\t\tconsole.log(ctx,'12');\r\n\t\t// 绘制外圆\n\t\tctx.beginPath() // 开始路径\n\t\tctx.arc(100, 100, 80, 0, Math.PI * 2) // 在坐标(100, 100)处绘制半径为80的圆形\n\t\tctx.setFillStyle('rgba(0, 0, 0, 1)') // 设置填充颜色为黑色,无透明度\n\t\tctx.fill() // 填充所创建的路径\n\t\t\n\t\t// 绘制内圆以形成环形效果\n\t\tctx.beginPath() // 开始新的路径\n\t\tctx.arc(100, 100, 75, 0, Math.PI * 2) // 在相同中心点(100, 100),但半径为60的圆形\n\t\tctx.setFillStyle('white') // 设置填充颜色为白色\n\t\tctx.fill() // 填充以“清除”内部区域,形成环形\r\n\t\tctx.draw(false, setTimeout(()=>{\r\n\t\t console.log(3)\r\n\t\t},300))\r\n\t}\n\n\t// 按钮点击事件处理函数\n\tconst handleDraw = () => {\r\n\t\tconsole.log('111111');\n\t\tdraw(); // 调用绘图函数\r\n\t\tconsole.log('222222222');\n\t}\n\n\tonMounted(() => {\r\n\t\t// 确保在组件挂载后可以获取到Canvas元素\n\t})\n</script>\n\n<style scoped>\n\tbutton {\n\t\tmargin-top: 10px;\n\t}\n</style>"],"mappings":";;;;;;;IAaC,IAAMA,WAAA,GAAcC,aAAA,CAAGC,GAAA,CAAC,GAAG;IAC3B,IAAMC,YAAA,GAAeF,aAAA,CAAGC,GAAA,CAAC,GAAG;IAG5B,SAASE,KAAA,EAAO;MACf,IAAMC,GAAA,GAAMJ,aAAA,CAAGK,KAAA,CAACC,mBAAA,CAAoB,UAAS,IAAI;MACjDN,aAAA,CAAAK,KAAA,CAAAE,KAAA,uCAAYH,GAAA,EAAI,IAAI;MAEpBA,GAAA,CAAII,SAAA,EAAW;MACfJ,GAAA,CAAIK,GAAA,CAAI,KAAK,KAAK,IAAI,GAAGC,IAAA,CAAKC,EAAA,GAAK,CAAC;MACpCP,GAAA,CAAIQ,YAAA,CAAa,kBAAkB;MACnCR,GAAA,CAAIS,IAAA,EAAM;MAGVT,GAAA,CAAII,SAAA,EAAW;MACfJ,GAAA,CAAIK,GAAA,CAAI,KAAK,KAAK,IAAI,GAAGC,IAAA,CAAKC,EAAA,GAAK,CAAC;MACpCP,GAAA,CAAIQ,YAAA,CAAa,OAAO;MACxBR,GAAA,CAAIS,IAAA,EAAM;MACVT,GAAA,CAAID,IAAA,CAAK,OAAOW,UAAA,CAAW,YAAI;QAC3Bd,aAAA,CAAAK,KAAA,CAAYE,KAAA,wCAAC;MAChB,GAAC,GAAG,CAAC;IACN;IAGD,IAAMQ,UAAA,GAAa,SAAbA,WAAA,EAAmB;MACxBf,aAAA,CAAAK,KAAA,CAAYE,KAAA,+CAAQ;MACpBJ,IAAA;MACAH,aAAA,CAAAK,KAAA,CAAAE,KAAA,uCAAY,WAAW;IACvB;IAEDP,aAAA,CAAAgB,SAAA,CAAU,YAAM,CAEjB,CAAE","ignoreList":[]}
|
@ -1 +1 @@
|
||||
{"version":3,"names":["draw","ctx","common_vendor","index","createCanvasContext","beginPath","arc","Math","PI","setFillStyle","setFillRule","fill","onMounted","wx","createPage","_sfc_main"],"sources":["index.vue","cGFnZXMvaW5kZXgvaW5kZXgudnVl"],"sourcesContent":["<template>\n\t<view>\n\t\t<canvas \n\t\t\tcanvas-id=\"canvas\" \n\t\t\tstyle=\"width: 100px; height: 100px;\"\n\t\t></canvas>\n\t</view>\n</template>\n\n<script setup>\nimport { onMounted } from 'vue'\n\nfunction draw() {\n\tconst ctx = uni.createCanvasContext('canvas')\n\n\tctx.beginPath()\n\tctx.arc(50, 50, 30, 0, Math.PI * 2, true)\n\tctx.arc(50, 50, 15, 0, Math.PI * 2, true)\n\tctx.setFillStyle('black')\n\tctx.setFillRule('evenodd') // 设置填充规则\n\tctx.fill()\n\n\tctx.draw()\n}\n\nonMounted(() => {\n\tdraw()\n})\n</script>\n\n<style scoped>\n</style>","import MiniProgramPage from 'C:/Users/hp/Desktop/app/canvas/pages/index/index.vue'\nwx.createPage(MiniProgramPage)"],"mappings":";;;;;;;IAYA,SAASA,KAAA,EAAO;MACf,IAAMC,GAAA,GAAMC,aAAA,CAAAC,KAAA,CAAIC,mBAAA,CAAoB,QAAQ;MAE5CH,GAAA,CAAII,SAAA,EAAW;MACfJ,GAAA,CAAIK,GAAA,CAAI,IAAI,IAAI,IAAI,GAAGC,IAAA,CAAKC,EAAA,GAAK,GAAG,IAAI;MACxCP,GAAA,CAAIK,GAAA,CAAI,IAAI,IAAI,IAAI,GAAGC,IAAA,CAAKC,EAAA,GAAK,GAAG,IAAI;MACxCP,GAAA,CAAIQ,YAAA,CAAa,OAAO;MACxBR,GAAA,CAAIS,WAAA,CAAY,SAAS;MACzBT,GAAA,CAAIU,IAAA,EAAM;MAEVV,GAAA,CAAID,IAAA,EAAM;IACX;IAEAE,aAAA,CAAAU,SAAA,CAAU,YAAM;MACfZ,IAAA,EAAM;IACP,CAAC;;;;;;AC1BDa,EAAA,CAAGC,UAAA,CAAWC,SAAe","ignoreList":[]}
|
||||
{"version":3,"names":["wx","createPage","index","MiniProgramPage"],"sources":["cGFnZXMvaW5kZXgvaW5kZXgudnVl"],"sourcesContent":["import MiniProgramPage from 'C:/Users/hp/Desktop/app/canvas/pages/index/index.vue'\nwx.createPage(MiniProgramPage)"],"mappings":";;;;AACAA,EAAA,CAAGC,UAAA,CAAWC,KAAA,CAAeC,eAAA","ignoreList":[]}
|
@ -1 +1 @@
|
||||
{"version":3,"file":"app.js","sources":["App.vue","main.js"],"sourcesContent":["<script>\r\n\texport default {\r\n\t\tonLaunch: function() {\r\n\t\t\tconsole.log('App Launch')\r\n\t\t},\r\n\t\tonShow: function() {\r\n\t\t\tconsole.log('App Show')\r\n\t\t},\r\n\t\tonHide: function() {\r\n\t\t\tconsole.log('App Hide')\r\n\t\t}\r\n\t}\r\n</script>\r\n\r\n<style>\r\n\t/*每个页面公共css */\r\n</style>\n","import App from './App'\n\n// #ifndef VUE3\nimport Vue from 'vue'\nimport './uni.promisify.adaptor'\nVue.config.productionTip = false\nApp.mpType = 'app'\nconst app = new Vue({\n ...App\n})\napp.$mount()\n// #endif\n\n// #ifdef VUE3\nimport { createSSRApp } from 'vue'\nexport function createApp() {\n const app = createSSRApp(App)\n return {\n app\n }\n}\n// #endif"],"names":["uni","createSSRApp","App"],"mappings":";;;;;;AACC,MAAK,YAAU;AAAA,EACd,UAAU,WAAW;AACpBA,kBAAAA,MAAA,MAAA,OAAA,gBAAY,YAAY;AAAA,EACxB;AAAA,EACD,QAAQ,WAAW;AAClBA,kBAAAA,MAAY,MAAA,OAAA,gBAAA,UAAU;AAAA,EACtB;AAAA,EACD,QAAQ,WAAW;AAClBA,kBAAAA,MAAY,MAAA,OAAA,iBAAA,UAAU;AAAA,EACvB;AACD;ACIM,SAAS,YAAY;AAC1B,QAAM,MAAMC,cAAY,aAACC,SAAG;AAC5B,SAAO;AAAA,IACL;AAAA,EACD;AACH;AACC,YAAO,IAAA,MAAA,MAAA;;"}
|
||||
{"version":3,"file":"app.js","sources":["App.vue","main.js"],"sourcesContent":["<script>\r\n\texport default {\r\n\t\tonLaunch: function() {\r\n\t\t\tconsole.log('App Launch')\r\n\t\t},\r\n\t\tonShow: function() {\r\n\t\t\tconsole.log('App Show')\r\n\t\t},\r\n\t\tonHide: function() {\r\n\t\t\tconsole.log('App Hide')\r\n\t\t}\r\n\t}\r\n</script>\r\n\r\n<style>\r\n\t/*每个页面公共css */\r\n</style>\n","import App from './App'\n\n// #ifndef VUE3\nimport Vue from 'vue'\nimport './uni.promisify.adaptor'\nVue.config.productionTip = false\nApp.mpType = 'app'\nconst app = new Vue({\n ...App\n})\napp.$mount()\n// #endif\n\n// #ifdef VUE3\nimport { createSSRApp } from 'vue'\nexport function createApp() {\n const app = createSSRApp(App)\n return {\n app\n }\n}\n// #endif"],"names":["uni","createSSRApp","App"],"mappings":";;;;;;;AACC,MAAK,YAAU;AAAA,EACd,UAAU,WAAW;AACpBA,kBAAAA,MAAA,MAAA,OAAA,gBAAY,YAAY;AAAA,EACxB;AAAA,EACD,QAAQ,WAAW;AAClBA,kBAAAA,MAAY,MAAA,OAAA,gBAAA,UAAU;AAAA,EACtB;AAAA,EACD,QAAQ,WAAW;AAClBA,kBAAAA,MAAY,MAAA,OAAA,iBAAA,UAAU;AAAA,EACvB;AACD;ACIM,SAAS,YAAY;AAC1B,QAAM,MAAMC,cAAY,aAACC,SAAG;AAC5B,SAAO;AAAA,IACL;AAAA,EACD;AACH;AACC,YAAO,IAAA,MAAA,MAAA;;"}
|
File diff suppressed because one or more lines are too long
1
unpackage/dist/dev/.sourcemap/mp-weixin/index.js.map
vendored
Normal file
1
unpackage/dist/dev/.sourcemap/mp-weixin/index.js.map
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sources":["pages/index/index.vue"],"sourcesContent":["<template>\n\t<view>\n\t\t<!-- 定义canvas画布 // 设置canvas大小为200x200像素 -->\n\t\t<canvas canvas-id=\"canvas\" id=\"canvas\" style=\"width: 200px; height: 200px;border: 1px solid red;\" :width=\"canvasWidth\" :height=\"canvasHeight\"></canvas>\n\n\t\t<!-- 添加一个按钮,用于触发绘图 -->\n\t\t<button @click=\"handleDraw\">点击绘制圆形</button>\n\t</view>\n</template>\n\n<script setup>\n\timport { ref, onMounted ,getCurrentInstance } from 'vue'\n\n\tconst canvasWidth = ref(200) // 动态设置Canvas宽度\n\tconst canvasHeight = ref(200) // 动态设置Canvas高度\n\tconst instance = getCurrentInstance() \n\t// 定义绘图函数\n\tfunction draw() {\n\t\tconst ctx = uni.createCanvasContext('canvas',instance) // 创建canvas绘图上下文\r\n\t\tconsole.log(ctx,'12');\r\n\t\t// 绘制外圆\n\t\tctx.beginPath() // 开始路径\n\t\tctx.arc(100, 100, 80, 0, Math.PI * 2) // 在坐标(100, 100)处绘制半径为80的圆形\n\t\tctx.setFillStyle('rgba(0, 0, 0, 1)') // 设置填充颜色为黑色,无透明度\n\t\tctx.fill() // 填充所创建的路径\n\t\t\n\t\t// 绘制内圆以形成环形效果\n\t\tctx.beginPath() // 开始新的路径\n\t\tctx.arc(100, 100, 75, 0, Math.PI * 2) // 在相同中心点(100, 100),但半径为60的圆形\n\t\tctx.setFillStyle('white') // 设置填充颜色为白色\n\t\tctx.fill() // 填充以“清除”内部区域,形成环形\r\n\t\tctx.draw()\r\n\t}\n\n\t// 按钮点击事件处理函数\n\tconst handleDraw = () => {\r\n\t\tconsole.log('111111');\n\t\tdraw(); // 调用绘图函数\r\n\t\tconsole.log('222222222');\n\t}\n\n\tonMounted(() => {\r\n\t\t// 确保在组件挂载后可以获取到Canvas元素\n\t})\n</script>\n\n<style scoped>\n\tbutton {\n\t\tmargin-top: 10px;\n\t}\n</style>"],"names":["ref","getCurrentInstance","uni","onMounted"],"mappings":";;;;;AAaC,UAAM,cAAcA,cAAG,IAAC,GAAG;AAC3B,UAAM,eAAeA,cAAG,IAAC,GAAG;AAC5B,UAAM,WAAWC,cAAAA,mBAAoB;AAErC,aAAS,OAAO;AACf,YAAM,MAAMC,cAAG,MAAC,oBAAoB,UAAS,QAAQ;AACrDA,oBAAA,MAAA,MAAA,OAAA,+BAAY,KAAI,IAAI;AAEpB,UAAI,UAAW;AACf,UAAI,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,KAAK,CAAC;AACpC,UAAI,aAAa,kBAAkB;AACnC,UAAI,KAAM;AAGV,UAAI,UAAW;AACf,UAAI,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,KAAK,CAAC;AACpC,UAAI,aAAa,OAAO;AACxB,UAAI,KAAM;AACV,UAAI,KAAM;AAAA,IACV;AAGD,UAAM,aAAa,MAAM;AACxBA,oBAAAA,MAAY,MAAA,OAAA,+BAAA,QAAQ;AACpB;AACAA,oBAAAA,MAAA,MAAA,OAAA,+BAAY,WAAW;AAAA,IACvB;AAEDC,kBAAAA,UAAU,MAAM;AAAA,IAEjB,CAAE;;;;;;;;;;;;"}
|
@ -1 +1 @@
|
||||
{"version":3,"file":"index.js","sources":["pages/index/index.vue","../../HBuilderX/plugins/uniapp-cli-vite/uniPage:/cGFnZXMvaW5kZXgvaW5kZXgudnVl"],"sourcesContent":["<template>\r\n\t<view>\r\n\t\t<!-- 定义canvas画布 // 设置canvas大小为200x200像素 -->\r\n\t\t<canvas canvas-id=\"canvas\" id=\"canvas\" style=\"width: 200px; height: 200px;\"></canvas>\r\n\r\n\t\t<!-- 添加一个按钮,用于触发绘图 -->\r\n\t\t<button @click=\"handleDraw()\">点击绘制圆形</button>\r\n\t</view>\r\n</template>\r\n\r\n<script setup>\r\n\timport {\r\n\t\tref\r\n\t} from 'vue'\r\n\r\n\t// 定义绘图函数\r\n\tfunction draw() {\r\n\t\tconst ctx = uni.createCanvasContext('canvas') // 创建canvas绘图上下文\r\n\r\n\t\t// 绘制外圆\r\n\t\tctx.beginPath() // 开始路径\r\n\t\tctx.arc(100, 100, 80, 0, Math.PI * 2) // 在坐标(100, 100)处绘制半径为80的圆形\r\n\t\tctx.setFillStyle('rgba(0, 0, 0, 1)') // 设置填充颜色为黑色,无透明度\r\n\t\tctx.fill() // 填充所创建的路径\r\n\t\t\r\n\t\t// 绘制内圆以形成环形效果\r\n\t\tctx.beginPath() // 开始新的路径\r\n\t\tctx.arc(100, 100, 75, 0, Math.PI * 2) // 在相同中心点(100, 100),但半径为60的圆形\r\n\t\tctx.setFillStyle('white') // 设置填充颜色为白色\r\n\t\tctx.fill() // 填充以“清除”内部区域,形成环形\r\n\t\tctx.draw() // 将上述所有操作提交到canvas进行渲染\r\n\t}\r\n\r\n\t// 按钮点击事件处理函数\r\n\tconst handleDraw = () => {\r\n\t\tdraw(); // 调用绘图函数\r\n\t}\r\n</script>\r\n\r\n<style scoped>\r\n\t/* 样式部分 */\r\n\tbutton {\r\n\t\tmargin-top: 10px;\r\n\t\t/* 给按钮设置一些上边距以避免过于紧凑 */\r\n\t}\r\n</style>","import MiniProgramPage from 'C:/Users/hp/Desktop/app/canvas/pages/index/index.vue'\nwx.createPage(MiniProgramPage)"],"names":["uni"],"mappings":";;;;;AAgBC,aAAS,OAAO;AACf,YAAM,MAAMA,cAAAA,MAAI,oBAAoB,QAAQ;AAG5C,UAAI,UAAW;AACf,UAAI,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,KAAK,CAAC;AACpC,UAAI,aAAa,kBAAkB;AACnC,UAAI,KAAM;AAGV,UAAI,UAAW;AACf,UAAI,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,KAAK,CAAC;AACpC,UAAI,aAAa,OAAO;AACxB,UAAI,KAAM;AACV,UAAI,KAAM;AAAA,IACV;AAGD,UAAM,aAAa,MAAM;AACxB;IACA;;;;;;;;;ACnCF,GAAG,WAAW,eAAe;"}
|
||||
{"version":3,"file":"index.js","sources":["../../HBuilderX/plugins/uniapp-cli-vite/uniPage:/cGFnZXMvaW5kZXgvaW5kZXgudnVl"],"sourcesContent":["import MiniProgramPage from 'C:/Users/hp/Desktop/app/canvas/pages/index/index.vue'\nwx.createPage(MiniProgramPage)"],"names":["MiniProgramPage"],"mappings":";;AACA,GAAG,WAAWA,MAAe,eAAA;"}
|
1
unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/index2.js.map
vendored
Normal file
1
unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/index2.js.map
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"index2.js","sources":["../../HBuilderX/plugins/uniapp-cli-vite/uniPage:/QzovVXNlcnMvaHAvRGVza3RvcC9hcHAvY2FudmFzL3BhZ2VzL2luZGV4L2luZGV4LnZ1ZQ"],"sourcesContent":["import MiniProgramPage from 'C:/Users/hp/Desktop/app/canvas/pages/index/index.vue'\nwx.createPage(MiniProgramPage)"],"names":["MiniProgramPage"],"mappings":";;AACA,GAAG,WAAWA,MAAe,eAAA;"}
|
1
unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/indexFu.js.map
vendored
Normal file
1
unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/indexFu.js.map
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"indexFu.js","sources":["pages/index/indexFu.vue","../../HBuilderX/plugins/uniapp-cli-vite/uniPage:/cGFnZXMvaW5kZXgvaW5kZXhGdS52dWU"],"sourcesContent":["<template>\r\n\t<view>\r\n\t<indexZi></indexZi>\r\n\t</view>\r\n</template>\r\n\r\n<script setup>\r\n\timport indexZi from \"./index.vue\" \r\n\timport {\r\n\t\tref\r\n\t} from 'vue'\r\n\r\n</script>\r\n\r\n<style scoped>\r\n\r\n</style>","import MiniProgramPage from 'C:/Users/hp/Desktop/app/canvas/pages/index/indexFu.vue'\nwx.createPage(MiniProgramPage)"],"names":["MiniProgramPage"],"mappings":";;;;;AAOC,MAAM,UAAU,MAAW;;;;;;;;;ACN5B,GAAG,WAAWA,SAAe;"}
|
1
unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/step2.js.map
vendored
Normal file
1
unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/step2.js.map
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"step2.js","sources":["pages/index/step2.vue","../../HBuilderX/plugins/uniapp-cli-vite/uniPage:/cGFnZXMvaW5kZXgvc3RlcDIudnVl"],"sourcesContent":["<template>\r\n\t<view>\r\n\t<indexstep2></indexstep2>\r\n\t</view>\r\n</template>\r\n\r\n<script setup>\r\n\timport indexstep2 from \"./index.vue\" \r\n\timport {\r\n\t\tref\r\n\t} from 'vue'\r\n\r\n</script>\r\n\r\n<style scoped>\r\n\r\n</style>","import MiniProgramPage from 'C:/Users/hp/Desktop/app/canvas/pages/index/step2.vue'\nwx.createPage(MiniProgramPage)"],"names":["MiniProgramPage"],"mappings":";;;;;AAOC,MAAM,aAAa,MAAW;;;;;;;;;ACN/B,GAAG,WAAWA,SAAe;"}
|
16
unpackage/dist/dev/app-plus/__uniappautomator.js
vendored
Normal file
16
unpackage/dist/dev/app-plus/__uniappautomator.js
vendored
Normal file
File diff suppressed because one or more lines are too long
32
unpackage/dist/dev/app-plus/__uniappchooselocation.js
vendored
Normal file
32
unpackage/dist/dev/app-plus/__uniappchooselocation.js
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
unpackage/dist/dev/app-plus/__uniapperror.png
vendored
Normal file
BIN
unpackage/dist/dev/app-plus/__uniapperror.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.7 KiB |
32
unpackage/dist/dev/app-plus/__uniappopenlocation.js
vendored
Normal file
32
unpackage/dist/dev/app-plus/__uniappopenlocation.js
vendored
Normal file
File diff suppressed because one or more lines are too long
33
unpackage/dist/dev/app-plus/__uniapppicker.js
vendored
Normal file
33
unpackage/dist/dev/app-plus/__uniapppicker.js
vendored
Normal file
File diff suppressed because one or more lines are too long
8
unpackage/dist/dev/app-plus/__uniappquill.js
vendored
Normal file
8
unpackage/dist/dev/app-plus/__uniappquill.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
unpackage/dist/dev/app-plus/__uniappquillimageresize.js
vendored
Normal file
1
unpackage/dist/dev/app-plus/__uniappquillimageresize.js
vendored
Normal file
File diff suppressed because one or more lines are too long
32
unpackage/dist/dev/app-plus/__uniappscan.js
vendored
Normal file
32
unpackage/dist/dev/app-plus/__uniappscan.js
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
unpackage/dist/dev/app-plus/__uniappsuccess.png
vendored
Normal file
BIN
unpackage/dist/dev/app-plus/__uniappsuccess.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
24
unpackage/dist/dev/app-plus/__uniappview.html
vendored
Normal file
24
unpackage/dist/dev/app-plus/__uniappview.html
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>View</title>
|
||||
<link rel="icon" href="data:,">
|
||||
<link rel="stylesheet" href="app.css" />
|
||||
<script>var __uniConfig = {"globalStyle":{},"darkmode":false}</script>
|
||||
<script>
|
||||
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
|
||||
CSS.supports('top: constant(a)'))
|
||||
document.write(
|
||||
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script src="uni-app-view.umd.js"></script>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
11
unpackage/dist/dev/app-plus/app-config-service.js
vendored
Normal file
11
unpackage/dist/dev/app-plus/app-config-service.js
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
;(function(){
|
||||
let u=void 0,isReady=false,onReadyCallbacks=[],isServiceReady=false,onServiceReadyCallbacks=[];
|
||||
const __uniConfig = {"pages":[],"globalStyle":{"backgroundColor":"#F8F8F8","navigationBar":{"backgroundColor":"#F8F8F8","titleText":"uni-app","type":"default","titleColor":"#000000"},"isNVue":false},"nvue":{"compiler":"uni-app","styleCompiler":"uni-app","flex-direction":"column"},"renderer":"auto","appname":"canvas","splashscreen":{"alwaysShowBeforeRender":true,"autoclose":true},"compilerVersion":"4.57","entryPagePath":"pages/index/step2","entryPageQuery":"","realEntryPagePath":"","networkTimeout":{"request":60000,"connectSocket":60000,"uploadFile":60000,"downloadFile":60000},"locales":{},"darkmode":false,"themeConfig":{}};
|
||||
const __uniRoutes = [{"path":"pages/index/step2","meta":{"isQuit":true,"isEntry":true,"navigationBar":{"titleText":"fu","type":"default"},"isNVue":false}},{"path":"pages/index/index","meta":{"navigationBar":{"titleText":"uni-app","type":"default"},"isNVue":false}}].map(uniRoute=>(uniRoute.meta.route=uniRoute.path,__uniConfig.pages.push(uniRoute.path),uniRoute.path='/'+uniRoute.path,uniRoute));
|
||||
__uniConfig.styles=[];//styles
|
||||
__uniConfig.onReady=function(callback){if(__uniConfig.ready){callback()}else{onReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"ready",{get:function(){return isReady},set:function(val){isReady=val;if(!isReady){return}const callbacks=onReadyCallbacks.slice(0);onReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
|
||||
__uniConfig.onServiceReady=function(callback){if(__uniConfig.serviceReady){callback()}else{onServiceReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"serviceReady",{get:function(){return isServiceReady},set:function(val){isServiceReady=val;if(!isServiceReady){return}const callbacks=onServiceReadyCallbacks.slice(0);onServiceReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
|
||||
service.register("uni-app-config",{create(a,b,c){if(!__uniConfig.viewport){var d=b.weex.config.env.scale,e=b.weex.config.env.deviceWidth,f=Math.ceil(e/d);Object.assign(__uniConfig,{viewport:f,defaultFontSize:16})}return{instance:{__uniConfig:__uniConfig,__uniRoutes:__uniRoutes,global:u,window:u,document:u,frames:u,self:u,location:u,navigator:u,localStorage:u,history:u,Caches:u,screen:u,alert:u,confirm:u,prompt:u,fetch:u,XMLHttpRequest:u,WebSocket:u,webkit:u,print:u}}}});
|
||||
})();
|
||||
|
1
unpackage/dist/dev/app-plus/app-config.js
vendored
Normal file
1
unpackage/dist/dev/app-plus/app-config.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
(function(){})();
|
636
unpackage/dist/dev/app-plus/app-service.js
vendored
Normal file
636
unpackage/dist/dev/app-plus/app-service.js
vendored
Normal file
@ -0,0 +1,636 @@
|
||||
if (typeof Promise !== "undefined" && !Promise.prototype.finally) {
|
||||
Promise.prototype.finally = function(callback) {
|
||||
const promise = this.constructor;
|
||||
return this.then(
|
||||
(value) => promise.resolve(callback()).then(() => value),
|
||||
(reason) => promise.resolve(callback()).then(() => {
|
||||
throw reason;
|
||||
})
|
||||
);
|
||||
};
|
||||
}
|
||||
;
|
||||
if (typeof uni !== "undefined" && uni && uni.requireGlobal) {
|
||||
const global = uni.requireGlobal();
|
||||
ArrayBuffer = global.ArrayBuffer;
|
||||
Int8Array = global.Int8Array;
|
||||
Uint8Array = global.Uint8Array;
|
||||
Uint8ClampedArray = global.Uint8ClampedArray;
|
||||
Int16Array = global.Int16Array;
|
||||
Uint16Array = global.Uint16Array;
|
||||
Int32Array = global.Int32Array;
|
||||
Uint32Array = global.Uint32Array;
|
||||
Float32Array = global.Float32Array;
|
||||
Float64Array = global.Float64Array;
|
||||
BigInt64Array = global.BigInt64Array;
|
||||
BigUint64Array = global.BigUint64Array;
|
||||
}
|
||||
;
|
||||
if (uni.restoreGlobal) {
|
||||
uni.restoreGlobal(Vue, weex, plus, setTimeout, clearTimeout, setInterval, clearInterval);
|
||||
}
|
||||
(function(vue) {
|
||||
"use strict";
|
||||
function formatAppLog(type, filename, ...args) {
|
||||
if (uni.__log__) {
|
||||
uni.__log__(type, filename, ...args);
|
||||
} else {
|
||||
console[type].apply(console, [...args, filename]);
|
||||
}
|
||||
}
|
||||
const _export_sfc = (sfc, props) => {
|
||||
const target = sfc.__vccOpts || sfc;
|
||||
for (const [key, val] of props) {
|
||||
target[key] = val;
|
||||
}
|
||||
return target;
|
||||
};
|
||||
const _sfc_main$2 = {
|
||||
data() {
|
||||
return {
|
||||
canvasWidth: 300,
|
||||
canvasHeight: 400,
|
||||
ctx: null,
|
||||
areas: [],
|
||||
// 从接口获取的区域数据
|
||||
selectedArea: null,
|
||||
colorMap: {
|
||||
"A区": "#FF5252",
|
||||
"B区": "#4CAF50",
|
||||
"C区": "#2196F3",
|
||||
"D区": "#FFC107"
|
||||
}
|
||||
};
|
||||
},
|
||||
async onLoad() {
|
||||
await this.loadAreaData();
|
||||
},
|
||||
onReady() {
|
||||
setTimeout(() => {
|
||||
this.initCanvas().catch((e) => {
|
||||
formatAppLog("error", "at pages/index/step2.vue:47", "初始化失败:", e);
|
||||
uni.showToast({
|
||||
title: "画布初始化失败",
|
||||
icon: "none"
|
||||
});
|
||||
});
|
||||
}, 300);
|
||||
},
|
||||
methods: {
|
||||
// 模拟加载区域数据
|
||||
async loadAreaData() {
|
||||
try {
|
||||
const data = [{
|
||||
"areacode": "lg0umpjukrdn",
|
||||
"areaname": "C4区",
|
||||
"description": "C4区",
|
||||
"remain": 94,
|
||||
"polygon": [131, 184, 130, 196, 146, 201, 174, 208, 174, 215, 215, 215, 258, 215, 258, 205, 257, 192, 258, 184, 215, 184, 174, 184, 131, 184]
|
||||
}, {
|
||||
"areacode": "pnk4022gt71m",
|
||||
"areaname": "A4区-一层",
|
||||
"description": "A4区-一层",
|
||||
"remain": 0,
|
||||
"polygon": [490, 464, 490, 475, 490, 488, 490, 499, 532, 499, 572, 499, 614, 499, 614, 488, 599, 480, 586, 474, 572, 464, 532, 464, 490, 464]
|
||||
}, {
|
||||
"areacode": "e0jhx1sa8194",
|
||||
"areaname": "D1区-一层",
|
||||
"description": "D1区-一层",
|
||||
"remain": 247,
|
||||
"polygon": [604, 345, 603, 385, 604, 396, 624, 439, 643, 437, 644, 417, 643, 396, 644, 367, 644, 344, 616, 345, 644, 346, 630, 344, 604, 345]
|
||||
}, {
|
||||
"areacode": "qxhs4574ffrh",
|
||||
"areaname": "D1区-二层",
|
||||
"description": "D1区-二层",
|
||||
"remain": 191,
|
||||
"polygon": [648, 349, 648, 386, 648, 425, 648, 452, 668, 452, 668, 462, 674, 462, 674, 425, 674, 386, 674, 349, 666, 349, 656, 349, 648, 349]
|
||||
}, {
|
||||
"areacode": "ar2q2e74ffrj",
|
||||
"areaname": "D2区-二层",
|
||||
"description": "D2区-二层",
|
||||
"remain": 122,
|
||||
"polygon": [647, 240, 648, 270, 648, 309, 648, 350, 657, 350, 665, 350, 673, 350, 673, 309, 673, 270, 673, 229, 667, 229, 667, 239, 647, 240]
|
||||
}, {
|
||||
"areacode": "qar2r374ffrl",
|
||||
"areaname": "D2区-一层",
|
||||
"description": "D2区-一层",
|
||||
"remain": 153,
|
||||
"polygon": [617, 266, 605, 285, 606, 303, 606, 342, 626, 341, 645, 342, 643, 341, 642, 302, 642, 278, 642, 263, 642, 249, 626, 248, 617, 266]
|
||||
}, {
|
||||
"areacode": "fpfaxmsa816f",
|
||||
"areaname": "A2区-一层",
|
||||
"description": "A2区-一层",
|
||||
"remain": 0,
|
||||
"polygon": [269, 463, 269, 476, 269, 488, 269, 501, 301, 501, 332, 501, 364, 501, 364, 488, 364, 476, 364, 463, 332, 463, 301, 463, 269, 463]
|
||||
}, {
|
||||
"areacode": "tse56pjukrdx",
|
||||
"areaname": "C3区",
|
||||
"description": "C3区",
|
||||
"remain": 215,
|
||||
"polygon": [279, 141, 279, 174, 266, 173, 265, 180, 308, 180, 339, 180, 369, 180, 369, 167, 369, 154, 369, 141, 339, 141, 308, 141, 279, 141]
|
||||
}, {
|
||||
"areacode": "lpkym7ej0kmd",
|
||||
"areaname": "B1区-一层",
|
||||
"description": "B1区-一层",
|
||||
"remain": 248,
|
||||
"polygon": [104, 250, 104, 282, 104, 313, 104, 345, 118, 345, 131, 345, 145, 345, 145, 313, 145, 288, 138, 276, 131, 263, 123, 250, 104, 250]
|
||||
}, {
|
||||
"areacode": "r6xrfc2gt71x",
|
||||
"areaname": "C3区",
|
||||
"description": "C3区",
|
||||
"remain": 143,
|
||||
"polygon": [269, 186, 269, 196, 269, 207, 269, 217, 300, 217, 333, 217, 364, 217, 364, 207, 364, 196, 364, 186, 333, 186, 300, 186, 269, 186]
|
||||
}, {
|
||||
"areacode": "h84jstej0kmf",
|
||||
"areaname": "C1区",
|
||||
"description": "C1区",
|
||||
"remain": 337,
|
||||
"polygon": [477, 133, 476, 168, 491, 168, 491, 179, 519, 178, 690, 179, 689, 170, 660, 170, 659, 140, 670, 140, 670, 134, 530, 134, 477, 133]
|
||||
}, {
|
||||
"areacode": "tqaegcej0kmg",
|
||||
"areaname": "A2区-二层",
|
||||
"description": "A2区-二层",
|
||||
"remain": 0,
|
||||
"polygon": [278, 514, 277, 526, 256, 525, 256, 542, 289, 542, 311, 542, 311, 531, 364, 533, 364, 525, 352, 525, 352, 513, 303, 513, 278, 514]
|
||||
}, {
|
||||
"areacode": "606fa9ej0kmh",
|
||||
"areaname": "A3区-一层",
|
||||
"description": "A3区-一层",
|
||||
"remain": 0,
|
||||
"polygon": [384, 466, 384, 477, 384, 489, 384, 500, 416, 500, 447, 500, 479, 500, 479, 489, 479, 477, 479, 466, 447, 466, 416, 466, 384, 466]
|
||||
}, {
|
||||
"areacode": "2x9j4bej0km8",
|
||||
"areaname": "B1区-二层",
|
||||
"description": "B1区-二层",
|
||||
"remain": 192,
|
||||
"polygon": [74, 231, 73, 270, 73, 304, 73, 340, 84, 340, 91, 340, 101, 340, 101, 304, 101, 283, 100, 239, 80, 238, 80, 230, 74, 231]
|
||||
}, {
|
||||
"areacode": "81mj022gt723",
|
||||
"areaname": "A4区-二层",
|
||||
"description": "A4区-二层",
|
||||
"remain": 0,
|
||||
"polygon": [513, 511, 513, 525, 493, 525, 493, 547, 556, 547, 624, 547, 657, 546, 657, 513, 687, 513, 688, 501, 489, 500, 490, 511, 513, 511]
|
||||
}, {
|
||||
"areacode": "f217dy2gt72f",
|
||||
"areaname": "C2区",
|
||||
"description": "C2区",
|
||||
"remain": 136,
|
||||
"polygon": [372, 144, 372, 156, 372, 168, 372, 180, 403, 180, 434, 180, 481, 180, 481, 175, 467, 175, 467, 144, 434, 144, 403, 144, 372, 144]
|
||||
}, {
|
||||
"areacode": "crxllrjukre8",
|
||||
"areaname": "A3区-二层",
|
||||
"description": "A3区-二层",
|
||||
"remain": 0,
|
||||
"polygon": [386, 515, 387, 528, 376, 527, 376, 535, 436, 533, 436, 545, 486, 545, 486, 534, 486, 526, 463, 526, 464, 515, 411, 515, 386, 515]
|
||||
}, {
|
||||
"areacode": "kb8wtgjukre9",
|
||||
"areaname": "C2区",
|
||||
"description": "C2区",
|
||||
"remain": 144,
|
||||
"polygon": [386, 186, 386, 197, 386, 206, 386, 217, 416, 217, 448, 217, 478, 217, 478, 206, 478, 197, 478, 186, 448, 186, 416, 186, 386, 186]
|
||||
}, {
|
||||
"areacode": "0wrt1djukrea",
|
||||
"areaname": "C1区",
|
||||
"description": "C1区",
|
||||
"remain": 60,
|
||||
"polygon": [496, 184, 496, 194, 496, 205, 496, 215, 571, 214, 572, 204, 587, 205, 598, 202, 614, 194, 614, 184, 574, 184, 536, 184, 496, 184]
|
||||
}, {
|
||||
"areacode": "hya95p74ffs3",
|
||||
"areaname": "B2区-二层",
|
||||
"description": "B2区-二层",
|
||||
"remain": 191,
|
||||
"polygon": [73, 337, 73, 378, 72, 415, 73, 457, 78, 457, 78, 449, 100, 449, 101, 415, 100, 394, 101, 337, 92, 337, 82, 337, 73, 337]
|
||||
}, {
|
||||
"areacode": "rrw413jukre2",
|
||||
"areaname": "A1区-一层",
|
||||
"description": "A1区-一层",
|
||||
"remain": 0,
|
||||
"polygon": [256, 465, 256, 476, 256, 489, 256, 499, 213, 499, 172, 499, 129, 499, 129, 485, 144, 479, 158, 473, 172, 465, 213, 465, 256, 465]
|
||||
}, {
|
||||
"areacode": "sagsr1sa816m",
|
||||
"areaname": "C4区",
|
||||
"description": "C4区",
|
||||
"remain": 490,
|
||||
"polygon": [88, 139, 89, 171, 61, 172, 60, 181, 224, 181, 259, 182, 259, 174, 273, 173, 272, 154, 273, 131, 77, 132, 77, 139, 88, 139]
|
||||
}, {
|
||||
"areacode": "eqk4nyjukre4",
|
||||
"areaname": "B2区一层",
|
||||
"description": "B2区一层",
|
||||
"remain": 247,
|
||||
"polygon": [104, 344, 104, 376, 104, 406, 104, 438, 123, 438, 128, 425, 134, 415, 143, 399, 144, 376, 144, 344, 130, 344, 118, 344, 104, 344]
|
||||
}, {
|
||||
"areacode": "rrtc9e2gt72d",
|
||||
"areaname": "A1区-二层",
|
||||
"description": "A1区-二层",
|
||||
"remain": 0,
|
||||
"polygon": [62, 501, 62, 509, 90, 510, 89, 549, 250, 548, 250, 527, 231, 528, 230, 510, 254, 509, 254, 501, 191, 501, 125, 501, 62, 501]
|
||||
}];
|
||||
this.areas = data.map((area) => ({
|
||||
...area,
|
||||
color: this.getAreaColor(area.areaname),
|
||||
// 转换多边形为绘制路径
|
||||
path: this.parsePolygon(area.polygon)
|
||||
}));
|
||||
} catch (error) {
|
||||
formatAppLog("error", "at pages/index/step2.vue:213", "数据加载失败:", error);
|
||||
}
|
||||
},
|
||||
// 根据区域名称获取颜色
|
||||
getAreaColor(name) {
|
||||
for (const [key, value] of Object.entries(this.colorMap)) {
|
||||
if (name.includes(key))
|
||||
return value;
|
||||
}
|
||||
return "#9E9E9E";
|
||||
},
|
||||
// 解析多边形数据
|
||||
parsePolygon(points) {
|
||||
const path = [];
|
||||
if (!points || !Array.isArray(points) || points.length % 2 !== 0) {
|
||||
formatAppLog("error", "at pages/index/step2.vue:230", "无效的多边形数据:", points);
|
||||
return path;
|
||||
}
|
||||
for (let i = 0; i < points.length; i += 2) {
|
||||
const x = Number(points[i]);
|
||||
const y = Number(points[i + 1]);
|
||||
if (!isNaN(x) && !isNaN(y)) {
|
||||
path.push({ x, y });
|
||||
} else {
|
||||
formatAppLog("warn", "at pages/index/step2.vue:241", "忽略无效坐标:", points[i], points[i + 1]);
|
||||
}
|
||||
}
|
||||
if (path.length > 0 && (path[0].x !== path[path.length - 1].x || path[0].y !== path[path.length - 1].y)) {
|
||||
path.push({ ...path[0] });
|
||||
}
|
||||
return path;
|
||||
},
|
||||
async initCanvas() {
|
||||
try {
|
||||
const canvasNode = await new Promise((resolve, reject) => {
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query.select("#selectCanvas").fields({ node: true, size: true }).exec((res) => {
|
||||
var _a;
|
||||
((_a = res[0]) == null ? void 0 : _a.node) ? resolve(res[0].node) : reject("Canvas节点获取失败");
|
||||
});
|
||||
});
|
||||
const systemInfo = uni.getSystemInfoSync();
|
||||
this.canvasWidth = systemInfo.windowWidth;
|
||||
this.canvasHeight = systemInfo.windowHeight * 0.8;
|
||||
const dpr = systemInfo.pixelRatio || 1;
|
||||
canvasNode.width = this.canvasWidth * dpr;
|
||||
canvasNode.height = this.canvasHeight * dpr;
|
||||
this.ctx = uni.createCanvasContext("selectCanvas", this);
|
||||
this.ctx.scale(dpr, dpr);
|
||||
this.drawAllAreas();
|
||||
} catch (error) {
|
||||
formatAppLog("error", "at pages/index/step2.vue:289", "初始化失败:", error);
|
||||
this.useFallbackRender();
|
||||
}
|
||||
},
|
||||
// 绘制所有区域
|
||||
drawAllAreas() {
|
||||
this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
|
||||
this.ctx.setFillStyle("#f5f5f5");
|
||||
this.ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight);
|
||||
this.areas.forEach((area) => {
|
||||
this.drawArea(area);
|
||||
});
|
||||
this.ctx.draw();
|
||||
},
|
||||
// 绘制单个区域
|
||||
drawArea(area) {
|
||||
this.ctx.beginPath();
|
||||
this.ctx.moveTo(area.path[0].x, area.path[0].y);
|
||||
for (let i = 1; i < area.path.length; i++) {
|
||||
this.ctx.lineTo(area.path[i].x, area.path[i].y);
|
||||
}
|
||||
this.ctx.closePath();
|
||||
this.ctx.setFillStyle(area.color);
|
||||
this.ctx.fill();
|
||||
if (this.selectedArea === area) {
|
||||
this.ctx.setStrokeStyle("#000000");
|
||||
this.ctx.setLineWidth(3);
|
||||
this.ctx.stroke();
|
||||
}
|
||||
},
|
||||
// 检查点击了哪个区域
|
||||
async checkAreaSelection(x, y) {
|
||||
return new Promise((resolve) => {
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query.select("#selectCanvas").boundingClientRect((rect) => {
|
||||
if (!rect)
|
||||
return resolve(null);
|
||||
const canvasX = x - rect.left;
|
||||
const canvasY = y - rect.top;
|
||||
const clickedArea = this.areas.find(
|
||||
(area) => this.isPointInPolygon(canvasX, canvasY, area.path)
|
||||
);
|
||||
resolve(clickedArea);
|
||||
}).exec();
|
||||
});
|
||||
},
|
||||
// 判断点是否在多边形内
|
||||
isPointInPolygon(x, y, polygon) {
|
||||
if (!polygon || !Array.isArray(polygon) || polygon.length < 3) {
|
||||
formatAppLog("warn", "at pages/index/step2.vue:360", "无效的多边形数据", polygon);
|
||||
return false;
|
||||
}
|
||||
let inside = false;
|
||||
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
||||
const xi = polygon[i].x, yi = polygon[i].y;
|
||||
const xj = polygon[j].x, yj = polygon[j].y;
|
||||
if (isNaN(xi) || isNaN(yi) || isNaN(xj) || isNaN(yj)) {
|
||||
formatAppLog("warn", "at pages/index/step2.vue:371", "无效的坐标点", { xi, yi, xj, yj });
|
||||
return false;
|
||||
}
|
||||
const intersect = yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi;
|
||||
if (intersect)
|
||||
inside = !inside;
|
||||
}
|
||||
return inside;
|
||||
},
|
||||
// 处理触摸开始
|
||||
async handleTouchStart(e) {
|
||||
const touch = e.touches[0];
|
||||
const clickedArea = await this.checkAreaSelection(touch.clientX, touch.clientY);
|
||||
if (clickedArea) {
|
||||
this.selectedArea = clickedArea;
|
||||
this.drawAllAreas();
|
||||
uni.showToast({
|
||||
title: `选中: ${clickedArea.areaname}`,
|
||||
icon: "none"
|
||||
});
|
||||
this.$emit("area-selected", {
|
||||
areacode: clickedArea.areacode,
|
||||
areaname: clickedArea.areaname,
|
||||
remain: clickedArea.remain
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
|
||||
return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [
|
||||
vue.createElementVNode(
|
||||
"canvas",
|
||||
{
|
||||
"canvas-id": "selectCanvas",
|
||||
id: "selectCanvas",
|
||||
type: "2d",
|
||||
"disable-scroll": "true",
|
||||
onTouchstart: _cache[0] || (_cache[0] = (...args) => $options.handleTouchStart && $options.handleTouchStart(...args)),
|
||||
style: vue.normalizeStyle({
|
||||
width: $data.canvasWidth + "px",
|
||||
height: $data.canvasHeight + "px"
|
||||
})
|
||||
},
|
||||
null,
|
||||
36
|
||||
/* STYLE, NEED_HYDRATION */
|
||||
),
|
||||
$data.selectedArea ? (vue.openBlock(), vue.createElementBlock(
|
||||
"view",
|
||||
{
|
||||
key: 0,
|
||||
class: "selection-info"
|
||||
},
|
||||
" 当前选中:" + vue.toDisplayString($data.selectedArea.areaname) + " (剩余:" + vue.toDisplayString($data.selectedArea.remain) + ") ",
|
||||
1
|
||||
/* TEXT */
|
||||
)) : vue.createCommentVNode("v-if", true)
|
||||
]);
|
||||
}
|
||||
const PagesIndexStep2 = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render$1], ["__file", "/Users/sunmeng/Desktop/wx/canvas/pages/index/step2.vue"]]);
|
||||
const _sfc_main$1 = {
|
||||
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 = uni.createSelectorQuery().in(this);
|
||||
query.select(`#${id}`).fields({ node: true, size: true }).exec((res) => {
|
||||
formatAppLog("log", "at pages/index/index.vue:94", "给我看看", res);
|
||||
formatAppLog("log", "at pages/index/index.vue:95", "给我看看", res);
|
||||
formatAppLog("log", "at pages/index/index.vue:96", "给我看看", res);
|
||||
formatAppLog("log", "at pages/index/index.vue:97", "给我看看", res);
|
||||
formatAppLog("log", "at pages/index/index.vue:98", "给我看看", res);
|
||||
formatAppLog("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 * uni.getSystemInfoSync().pixelRatio;
|
||||
canvas.height = height * uni.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 vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [
|
||||
vue.createElementVNode("view", { class: "screen" }, "银幕"),
|
||||
vue.createElementVNode(
|
||||
"canvas",
|
||||
{
|
||||
"canvas-id": "seatCanvas",
|
||||
type: "2d",
|
||||
class: "seat-canvas",
|
||||
onTouchstart: _cache[0] || (_cache[0] = (...args) => $options.handleTouchStart && $options.handleTouchStart(...args)),
|
||||
onTouchmove: _cache[1] || (_cache[1] = (...args) => $options.handleTouchMove && $options.handleTouchMove(...args)),
|
||||
onTouchend: _cache[2] || (_cache[2] = (...args) => $options.handleTouchEnd && $options.handleTouchEnd(...args))
|
||||
},
|
||||
null,
|
||||
32
|
||||
/* NEED_HYDRATION */
|
||||
),
|
||||
vue.createElementVNode("view", { class: "legend" }, [
|
||||
vue.createElementVNode("view", { class: "legend-item" }, [
|
||||
vue.createElementVNode("view", { class: "seat-icon available" }),
|
||||
vue.createElementVNode("text", null, "可选")
|
||||
]),
|
||||
vue.createElementVNode("view", { class: "legend-item" }, [
|
||||
vue.createElementVNode("view", { class: "seat-icon selected" }),
|
||||
vue.createElementVNode("text", null, "已选")
|
||||
]),
|
||||
vue.createElementVNode("view", { class: "legend-item" }, [
|
||||
vue.createElementVNode("view", { class: "seat-icon sold" }),
|
||||
vue.createElementVNode("text", null, "已售")
|
||||
])
|
||||
]),
|
||||
vue.createElementVNode("view", { class: "selected-seats" }, [
|
||||
vue.createElementVNode(
|
||||
"text",
|
||||
null,
|
||||
"已选座位:" + vue.toDisplayString($data.selectedSeats.join(", ") || "无"),
|
||||
1
|
||||
/* TEXT */
|
||||
)
|
||||
])
|
||||
]);
|
||||
}
|
||||
const PagesIndexIndex = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render], ["__file", "/Users/sunmeng/Desktop/wx/canvas/pages/index/index.vue"]]);
|
||||
__definePage("pages/index/step2", PagesIndexStep2);
|
||||
__definePage("pages/index/index", PagesIndexIndex);
|
||||
const _sfc_main = {
|
||||
onLaunch: function() {
|
||||
formatAppLog("log", "at App.vue:4", "App Launch");
|
||||
},
|
||||
onShow: function() {
|
||||
formatAppLog("log", "at App.vue:7", "App Show");
|
||||
},
|
||||
onHide: function() {
|
||||
formatAppLog("log", "at App.vue:10", "App Hide");
|
||||
}
|
||||
};
|
||||
const App = /* @__PURE__ */ _export_sfc(_sfc_main, [["__file", "/Users/sunmeng/Desktop/wx/canvas/App.vue"]]);
|
||||
function createApp() {
|
||||
const app = vue.createVueApp(App);
|
||||
return {
|
||||
app
|
||||
};
|
||||
}
|
||||
const { app: __app__, Vuex: __Vuex__, Pinia: __Pinia__ } = createApp();
|
||||
uni.Vuex = __Vuex__;
|
||||
uni.Pinia = __Pinia__;
|
||||
__app__.provide("__globalStyles", __uniConfig.styles);
|
||||
__app__._component.mpType = "app";
|
||||
__app__._component.render = () => {
|
||||
};
|
||||
__app__.mount("#app");
|
||||
})(Vue);
|
4
unpackage/dist/dev/app-plus/app.css
vendored
Normal file
4
unpackage/dist/dev/app-plus/app.css
vendored
Normal file
File diff suppressed because one or more lines are too long
113
unpackage/dist/dev/app-plus/manifest.json
vendored
Normal file
113
unpackage/dist/dev/app-plus/manifest.json
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
{
|
||||
"@platforms": [
|
||||
"android",
|
||||
"iPhone",
|
||||
"iPad"
|
||||
],
|
||||
"id": "__UNI__EBE2302",
|
||||
"name": "canvas",
|
||||
"version": {
|
||||
"name": "1.0.0",
|
||||
"code": "100"
|
||||
},
|
||||
"description": "",
|
||||
"developer": {
|
||||
"name": "",
|
||||
"email": "",
|
||||
"url": ""
|
||||
},
|
||||
"permissions": {
|
||||
"UniNView": {
|
||||
"description": "UniNView原生渲染"
|
||||
}
|
||||
},
|
||||
"plus": {
|
||||
"useragent": {
|
||||
"value": "uni-app",
|
||||
"concatenate": true
|
||||
},
|
||||
"splashscreen": {
|
||||
"target": "id:1",
|
||||
"autoclose": true,
|
||||
"waiting": true,
|
||||
"delay": 0
|
||||
},
|
||||
"popGesture": "close",
|
||||
"launchwebview": {
|
||||
"render": "always",
|
||||
"id": "1",
|
||||
"kernel": "WKWebview"
|
||||
},
|
||||
"canvas2d": true,
|
||||
"optimization": {
|
||||
"subPackages": true
|
||||
},
|
||||
"usingComponents": {
|
||||
"canvas": true
|
||||
},
|
||||
"nvueStyleCompiler": "uni-app",
|
||||
"compilerVersion": 3,
|
||||
"distribute": {
|
||||
"google": {
|
||||
"permissions": [
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||
]
|
||||
},
|
||||
"apple": {},
|
||||
"plugins": {
|
||||
"audio": {
|
||||
"mp3": {
|
||||
"description": "Android平台录音支持MP3格式文件"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"statusbar": {
|
||||
"immersed": "supportedDevice",
|
||||
"style": "dark",
|
||||
"background": "#F8F8F8"
|
||||
},
|
||||
"uniStatistics": {
|
||||
"enable": false
|
||||
},
|
||||
"allowsInlineMediaPlayback": true,
|
||||
"uni-app": {
|
||||
"control": "uni-v3",
|
||||
"vueVersion": "3",
|
||||
"compilerVersion": "4.57",
|
||||
"nvueCompiler": "uni-app",
|
||||
"renderer": "auto",
|
||||
"nvue": {
|
||||
"flex-direction": "column"
|
||||
},
|
||||
"nvueLaunchMode": "normal",
|
||||
"webView": {
|
||||
"minUserAgentVersion": "49.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"app-harmony": {
|
||||
"useragent": {
|
||||
"value": "uni-app",
|
||||
"concatenate": true
|
||||
},
|
||||
"uniStatistics": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
"launch_path": "__uniappview.html"
|
||||
}
|
61
unpackage/dist/dev/app-plus/pages/index/index.css
vendored
Normal file
61
unpackage/dist/dev/app-plus/pages/index/index.css
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 0.625rem;
|
||||
height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
.screen {
|
||||
width: 80%;
|
||||
height: 1.25rem;
|
||||
background: linear-gradient(to bottom, #ccc, #fff);
|
||||
margin-bottom: 1.25rem;
|
||||
text-align: center;
|
||||
font-size: 0.875rem;
|
||||
color: #333;
|
||||
border-radius: 0.25rem;
|
||||
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.seat-canvas {
|
||||
width: 100%;
|
||||
height: 15.625rem;
|
||||
background-color: #fff;
|
||||
margin-bottom: 0.625rem;
|
||||
border-radius: 0.25rem;
|
||||
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.legend {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-bottom: 0.625rem;
|
||||
}
|
||||
.legend-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0 0.625rem;
|
||||
}
|
||||
.seat-icon {
|
||||
width: 0.9375rem;
|
||||
height: 0.9375rem;
|
||||
margin-right: 0.3125rem;
|
||||
border-radius: 0.125rem;
|
||||
}
|
||||
.available {
|
||||
background-color: #4CAF50;
|
||||
}
|
||||
.selected {
|
||||
background-color: #2196F3;
|
||||
}
|
||||
.sold {
|
||||
background-color: #9E9E9E;
|
||||
}
|
||||
.selected-seats {
|
||||
padding: 0.625rem;
|
||||
background-color: #fff;
|
||||
border-radius: 0.25rem;
|
||||
width: 90%;
|
||||
text-align: center;
|
||||
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.1);
|
||||
}
|
19
unpackage/dist/dev/app-plus/pages/index/step2.css
vendored
Normal file
19
unpackage/dist/dev/app-plus/pages/index/step2.css
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
}
|
||||
uni-canvas {
|
||||
width: 100%;
|
||||
height: 80%;
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
.selection-info {
|
||||
padding: 15px;
|
||||
background-color: #fff;
|
||||
border-top: 1px solid #eee;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
BIN
unpackage/dist/dev/app-plus/static/logo.png
vendored
Normal file
BIN
unpackage/dist/dev/app-plus/static/logo.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
7
unpackage/dist/dev/app-plus/uni-app-view.umd.js
vendored
Normal file
7
unpackage/dist/dev/app-plus/uni-app-view.umd.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
unpackage/dist/dev/cache/.app-plus/tsc/app-android/.tsbuildInfo
vendored
Normal file
1
unpackage/dist/dev/cache/.app-plus/tsc/app-android/.tsbuildInfo
vendored
Normal file
File diff suppressed because one or more lines are too long
1
unpackage/dist/dev/mp-weixin/app.js
vendored
1
unpackage/dist/dev/mp-weixin/app.js
vendored
@ -2,6 +2,7 @@
|
||||
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
||||
const common_vendor = require("./common/vendor.js");
|
||||
if (!Math) {
|
||||
"./pages/index/step2.js";
|
||||
"./pages/index/index.js";
|
||||
}
|
||||
const _sfc_main = {
|
||||
|
1
unpackage/dist/dev/mp-weixin/app.json
vendored
1
unpackage/dist/dev/mp-weixin/app.json
vendored
@ -1,5 +1,6 @@
|
||||
{
|
||||
"pages": [
|
||||
"pages/index/step2",
|
||||
"pages/index/index"
|
||||
],
|
||||
"window": {
|
||||
|
@ -7787,6 +7787,9 @@ const createSubpackageApp = initCreateSubpackageApp();
|
||||
}
|
||||
exports._export_sfc = _export_sfc;
|
||||
exports.createSSRApp = createSSRApp;
|
||||
exports.getCurrentInstance = getCurrentInstance;
|
||||
exports.index = index;
|
||||
exports.o = o;
|
||||
exports.onMounted = onMounted;
|
||||
exports.ref = ref;
|
||||
//# sourceMappingURL=../../.sourcemap/mp-weixin/common/vendor.js.map
|
||||
|
40
unpackage/dist/dev/mp-weixin/index.js
vendored
Normal file
40
unpackage/dist/dev/mp-weixin/index.js
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
"use strict";
|
||||
const common_vendor = require("./common/vendor.js");
|
||||
const _sfc_main = {
|
||||
__name: "index",
|
||||
setup(__props) {
|
||||
const canvasWidth = common_vendor.ref(200);
|
||||
const canvasHeight = common_vendor.ref(200);
|
||||
const instance = common_vendor.getCurrentInstance();
|
||||
function draw() {
|
||||
const ctx = common_vendor.index.createCanvasContext("canvas", instance);
|
||||
common_vendor.index.__f__("log", "at pages/index/index.vue:20", ctx, "12");
|
||||
ctx.beginPath();
|
||||
ctx.arc(100, 100, 80, 0, Math.PI * 2);
|
||||
ctx.setFillStyle("rgba(0, 0, 0, 1)");
|
||||
ctx.fill();
|
||||
ctx.beginPath();
|
||||
ctx.arc(100, 100, 75, 0, Math.PI * 2);
|
||||
ctx.setFillStyle("white");
|
||||
ctx.fill();
|
||||
ctx.draw();
|
||||
}
|
||||
const handleDraw = () => {
|
||||
common_vendor.index.__f__("log", "at pages/index/index.vue:37", "111111");
|
||||
draw();
|
||||
common_vendor.index.__f__("log", "at pages/index/index.vue:39", "222222222");
|
||||
};
|
||||
common_vendor.onMounted(() => {
|
||||
});
|
||||
return (_ctx, _cache) => {
|
||||
return {
|
||||
a: canvasWidth.value,
|
||||
b: canvasHeight.value,
|
||||
c: common_vendor.o(handleDraw)
|
||||
};
|
||||
};
|
||||
}
|
||||
};
|
||||
const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["__scopeId", "data-v-1cf27b2a"]]);
|
||||
exports.MiniProgramPage = MiniProgramPage;
|
||||
//# sourceMappingURL=../.sourcemap/mp-weixin/index.js.map
|
@ -1,30 +1,4 @@
|
||||
"use strict";
|
||||
const common_vendor = require("../../common/vendor.js");
|
||||
const _sfc_main = {
|
||||
__name: "index",
|
||||
setup(__props) {
|
||||
function draw() {
|
||||
const ctx = common_vendor.index.createCanvasContext("canvas");
|
||||
ctx.beginPath();
|
||||
ctx.arc(100, 100, 80, 0, Math.PI * 2);
|
||||
ctx.setFillStyle("rgba(0, 0, 0, 1)");
|
||||
ctx.fill();
|
||||
ctx.beginPath();
|
||||
ctx.arc(100, 100, 75, 0, Math.PI * 2);
|
||||
ctx.setFillStyle("white");
|
||||
ctx.fill();
|
||||
ctx.draw();
|
||||
}
|
||||
const handleDraw = () => {
|
||||
draw();
|
||||
};
|
||||
return (_ctx, _cache) => {
|
||||
return {
|
||||
a: common_vendor.o(($event) => handleDraw())
|
||||
};
|
||||
};
|
||||
}
|
||||
};
|
||||
const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["__scopeId", "data-v-1cf27b2a"]]);
|
||||
wx.createPage(MiniProgramPage);
|
||||
const index = require("../../index.js");
|
||||
wx.createPage(index.MiniProgramPage);
|
||||
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/index/index.js.map
|
||||
|
@ -1 +1 @@
|
||||
<view class="data-v-1cf27b2a"><canvas class="data-v-1cf27b2a" canvas-id="canvas" id="canvas" style="width:200px;height:200px"></canvas><button class="data-v-1cf27b2a" bindtap="{{a}}">点击绘制圆形</button></view>
|
||||
<view class="data-v-1cf27b2a"><canvas class="data-v-1cf27b2a" canvas-id="canvas" id="canvas" style="width:200px;height:200px;border:1px solid red" width="{{a}}" height="{{b}}"></canvas><button class="data-v-1cf27b2a" bindtap="{{c}}">点击绘制圆形</button></view>
|
@ -1,6 +1,4 @@
|
||||
|
||||
/* 样式部分 */
|
||||
button.data-v-1cf27b2a {
|
||||
margin-top: 10px;
|
||||
/* 给按钮设置一些上边距以避免过于紧凑 */
|
||||
}
|
||||
|
4
unpackage/dist/dev/mp-weixin/pages/index/index2.js
vendored
Normal file
4
unpackage/dist/dev/mp-weixin/pages/index/index2.js
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
"use strict";
|
||||
const index = require("../../index.js");
|
||||
wx.createPage(index.MiniProgramPage);
|
||||
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/index/index2.js.map
|
16
unpackage/dist/dev/mp-weixin/pages/index/indexFu.js
vendored
Normal file
16
unpackage/dist/dev/mp-weixin/pages/index/indexFu.js
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
"use strict";
|
||||
require("../../common/vendor.js");
|
||||
if (!Math) {
|
||||
indexZi();
|
||||
}
|
||||
const indexZi = () => "./index2.js";
|
||||
const _sfc_main = {
|
||||
__name: "indexFu",
|
||||
setup(__props) {
|
||||
return (_ctx, _cache) => {
|
||||
return {};
|
||||
};
|
||||
}
|
||||
};
|
||||
wx.createPage(_sfc_main);
|
||||
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/index/indexFu.js.map
|
6
unpackage/dist/dev/mp-weixin/pages/index/indexFu.json
vendored
Normal file
6
unpackage/dist/dev/mp-weixin/pages/index/indexFu.json
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"navigationBarTitleText": "fu",
|
||||
"usingComponents": {
|
||||
"index-zi": "./index"
|
||||
}
|
||||
}
|
1
unpackage/dist/dev/mp-weixin/pages/index/indexFu.wxml
vendored
Normal file
1
unpackage/dist/dev/mp-weixin/pages/index/indexFu.wxml
vendored
Normal file
@ -0,0 +1 @@
|
||||
<view><index-zi u-i="51b35b8e-0" bind:__l="__l"></index-zi></view>
|
0
unpackage/dist/dev/mp-weixin/pages/index/indexFu.wxss
vendored
Normal file
0
unpackage/dist/dev/mp-weixin/pages/index/indexFu.wxss
vendored
Normal file
16
unpackage/dist/dev/mp-weixin/pages/index/step2.js
vendored
Normal file
16
unpackage/dist/dev/mp-weixin/pages/index/step2.js
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
"use strict";
|
||||
require("../../common/vendor.js");
|
||||
if (!Math) {
|
||||
indexstep2();
|
||||
}
|
||||
const indexstep2 = () => "./index2.js";
|
||||
const _sfc_main = {
|
||||
__name: "step2",
|
||||
setup(__props) {
|
||||
return (_ctx, _cache) => {
|
||||
return {};
|
||||
};
|
||||
}
|
||||
};
|
||||
wx.createPage(_sfc_main);
|
||||
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/index/step2.js.map
|
6
unpackage/dist/dev/mp-weixin/pages/index/step2.json
vendored
Normal file
6
unpackage/dist/dev/mp-weixin/pages/index/step2.json
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"navigationBarTitleText": "fu",
|
||||
"usingComponents": {
|
||||
"indexstep2": "./index"
|
||||
}
|
||||
}
|
1
unpackage/dist/dev/mp-weixin/pages/index/step2.wxml
vendored
Normal file
1
unpackage/dist/dev/mp-weixin/pages/index/step2.wxml
vendored
Normal file
@ -0,0 +1 @@
|
||||
<view><indexstep2 u-i="41bebd5e-0" bind:__l="__l"></indexstep2></view>
|
0
unpackage/dist/dev/mp-weixin/pages/index/step2.wxss
vendored
Normal file
0
unpackage/dist/dev/mp-weixin/pages/index/step2.wxss
vendored
Normal file
Loading…
x
Reference in New Issue
Block a user