<template>
	<view style="width: 100%;height: 100%;position: relative;">
		<zero-loading v-show="loading && !noloading" position="absolute" v-if="loading && !noloading"></zero-loading>
		<canvas :id="cId" type="2d" :style="{width:width,height:height}" :canvas-id="cId"></canvas>
	</view>

</template>

<script>
	export default {
		data() {
			return {
				windowWidth: 0,
				type: 'app',
				ctx: null,
				textArr: [],
				imgArr: [],
				lineArr: [],
				circleArr: [],
				rectArr: [],
				loading: true,
				canvasWidth: null,
				canvasHeight: null
			}
		},
		props: {
			cId: {
				type: [String, Number],
				default: 'canvas'
			},
			width: {
				type: [String, Number],
				default: '100%'
			},
			height: {
				type: [String, Number],
				default: '100%'
			},
			canvasData: {
				type: Array,
				default: () => {
					return []
				}
			},
			noloading: {
				type: Boolean,
				default: false
			}
		},
		watch: {
			canvasData: {
				handler(val) {
					// 等待 windowWidth 初始化完成后再绘制
					if (this.windowWidth) {
					  this.draw(null); // 直接绘制
					} else {
					  // 若 windowWidth 未获取，先获取再绘制
					  this.getSystemInfo().then(() => {
						this.draw(null);
					  });
					}
				},
				deep: true,
				immediate: false
			}
		},
		mounted() {
			// this.getSystemInfo()
		},
		methods: {
			getSystemInfo() {
				const self = this
				uni.getSystemInfo({
					success: function(res) {
						// 获取屏幕尺寸
						self.windowWidth = res.windowWidth
						// const platform = res.hostName.toLowerCase()
						if (res.uniPlatform || res.uniPlatform === 'app') {
							self.type = 'app'
							//获取app的canvas的dom
							self.getAppDom()
						} else {
							self.type = 'wx'
							//获取小程序的canvas的dom
							self.getWXDom()
						}

					}
				})
			},
			clear() {
				// if (this.type === 'wx') {
				// 	this.ctx.globalCompositeOperation = 'destination-out';
				// 	this.ctx.beginPath();
				// 	this.ctx.fillStyle = 'red';
				// 	this.ctx.fillRect(0, 0, 8000, 80000);
				// 	this.ctx.fill();
				// 	this.ctx.globalCompositeOperation = 'source-over';
				// 	// this.ctx.draw();
				// } else {
				// 	// this.ctx.clearRect(2000, 2000, 2000, 2000);
				// 	// this.ctx.fillStyle = '#ffffff'
				// 	// this.ctx.draw(true);
				// }
				if (this.type === 'wx') {
					this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
				} else {
					// App 平台
					this.ctx.clearRect(0, 0, 8000, 8000);
				}
			},
			//获取app的canvas DOM
			getAppDom() {
				var context = uni.createCanvasContext(`${this.cId}`)
				this.ctx = context
				this.draw(null)
			},
			//获取微信的canvas DOM
			getWXDom() {
				// const instance = getCurrentInstance()
				let query = wx.createSelectorQuery().in(this)
				query
					.select(`#${this.cId}`)
					.fields({
						node: true,
						size: true
					}, () => {})
					.exec(this.initCanvas.bind(this))
			},
			initCanvas(res) {

				const width = res[0].width
				const height = res[0].height
				const canvas = res[0].node
				this.ctx = canvas.getContext('2d')

				const dpr = wx.getSystemInfoSync().pixelRatio
				canvas.width = width * dpr
				canvas.height = height * dpr
				this.canvasWidth = canvas.width
				this.canvasHeight = canvas.height
				this.ctx.scale(dpr, dpr)
				this.draw(canvas)
			},
			draw(canvas) {
				this.textArr = []
				this.circleArr = []
				this.rectArr = []
				this.imgArr = []
				this.lineArr = []
				this.canvasData.forEach((item) => {
					if (item.type === 'text') {
						this.textArr.push(item)
					}
					if (item.type === 'image') {
						this.imgArr.push(item)
					}
					if (item.type === 'line') {
						this.lineArr.push(item)
					}
					if (item.type === 'circle') {
						this.circleArr.push(item)
					}
					if (item.type === 'rect') {
						this.rectArr.push(item)
					}
				})
				if (this.imgArr.length) {
					this.drawImages(this.imgArr, canvas ? canvas : null)
				}
				if (this.lineArr.length) {
					this.drawLine(this.lineArr)
				}
				if (this.circleArr.length) {
					this.drawCircle(this.circleArr)
				}
				if (this.rectArr.length) {
					this.drawRect(this.rectArr)
				}
				if (this.textArr.length) {
					this.drawText(this.textArr)
				}

				// this.drawLine(this.lineArr)
				// this.drawCircle(this.circleArr)
				// this.drawRect(this.rectArr)
				// this.drawText(this.textArr)
				if (this.type === 'app') {
					this.ctx.draw()
				}
				this.loading = false


			},
			drawRect(draw) {
				draw.forEach((item, index) => {
					let x = this.fitSize(item.coord[0][0])
					let y = this.fitSize(item.coord[0][1])
					let w = this.fitSize(item.coord[1][0])
					let h = this.fitSize(item.coord[1][1])
					this.ctx.beginPath();
					if (this.type === 'app') {
						if (item.rectType === 'stroke') {
							this.ctx.setStrokeStyle(item.borderColor); // 设置边框颜色
							this.ctx.setLineWidth(item.width); // 设置边框宽度
							this.ctx.strokeRect(x, y, w, h); // 绘制无填充矩形
						} else {
							this.ctx.setFillStyle(item.background || 'transparent');
							this.ctx.fillRect(x, y, w, h);
						}

					} else {
						if (item.rectType === 'stroke') {
							this.ctx.strokeStyle = item.borderColor
							this.ctx.lineWidth = item.width
							this.ctx.strokeRect(x, y, w, h);
						} else {
							this.ctx.fillStyle = item.background || 'transparent'
							this.ctx.fillRect(x, y, w, h);
						}
					}
				})

			},
			// countChineseAndEnglishCharacters(str, x) {
			// 	var chineseCount = str.match(/[\u4e00-\u9fa5]/g) ?
			// 		str.match(/[\u4e00-\u9fa5]/g).length :
			// 		0;
			// 	var englishCount = str.match(/[a-zA-Z]/g) ?
			// 		str.match(/[a-zA-Z]/g).length :
			// 		0;
			// 	var otherCount = str.length - chineseCount - englishCount;
			// 	const obj = {
			// 		otherCount: otherCount,
			// 		chineseCount: chineseCount,
			// 		englishCount: englishCount,
			// 	};
			// 	return (
			// 		obj.englishCount * 6 + obj.chineseCount * 12 + obj.otherCount * 7.5 + x
			// 	);
			// },

			drawText(draw) {
			  draw.forEach((item, index) => {
			    if (item.font.length) {
			      // 记录前一个文本的结束位置（用于后续文本偏移）
			      let prevTextEndX = this.fitSize(item.coord[0][0]);
			      
			      item.font.forEach((item2, index2) => {
			        // 设置字体大小和颜色
			        if (this.type === 'app') {
			          this.ctx.setFontSize(item2.size);
			        } else {
			          this.ctx.font = `${item2.size}px sans-serif`; // 小程序端补全font属性
			        }
			        this.ctx.fillStyle = item2.color;
			
			        // 计算当前文本的绘制X坐标
			        let currentX = prevTextEndX;
			        // 非第一个文本，加上配置的偏移量（默认8px）
			        if (index2 > 0) {
			          const offsetX = item2.offsetX || 6;
			          currentX += this.fitSize(offsetX); // 适配设备尺寸的偏移量
			        }
			
			        // 绘制文本
			        this.ctx.fillText(
			          item2.text,
			          currentX,
			          this.fitSize(item.coord[0][1])
			        );
			
			        // 更新前一个文本的结束位置（当前文本的X + 文本宽度）
			        const textWidth = this.getTextWidth(item2.text, item2.size);
			        prevTextEndX = currentX + textWidth;
			
			        this.ctx.closePath();
			      });
			    }
			  });
			},
			// 新增：计算文本的实际绘制宽度（适配app/小程序）
			getTextWidth(text, fontSize) {
			  if (this.type === 'app') {
			    // App端通过measureText计算
			    return this.ctx.measureText(text).width;
			  } else {
			    // 小程序端手动计算（更稳定）
			    this.ctx.font = `${fontSize}px sans-serif`;
			    return this.ctx.measureText(text).width;
			  }
			},
			drawImages(draw, canvas) {
				let x,
					y,
					w,
					h = 0

				draw.forEach((item) => {
					if (item.coord.length >= 2) x = item.coord[0][0]
					y = item.coord[0][1]
					w = item.coord[1][0]
					h = item.coord[1][1]
					if (this.type === 'wx') {
						let img = canvas.createImage()
						img.src = item.url
						img.onload = () => {
							this.ctx.drawImage(
								img,
								this.fitSize(item.coord[0][0]),
								this.fitSize(item.coord[0][1]),
								this.fitSize(item.coord[1][0]),
								this.fitSize(item.coord[1][1])
							)

							this.drawLine(this.lineArr)
							this.drawCircle(this.circleArr)
							this.drawRect(this.rectArr)
							this.drawText(this.textArr)
							if (this.type === 'app') {
								this.ctx.draw()
							}
							this.loading = false
						}
					} else {
						this.ctx.drawImage(item.url, this.fitSize(x), this.fitSize(y), this.fitSize(w),
							this
							.fitSize(h))

					}
				})
			},
			drawLine(draw) {
				draw.forEach((item) => {
					let x1 = this.fitSize(item.coord[0][0])
					let y1 = this.fitSize(item.coord[0][1])
					let x2 = this.fitSize(item.coord[1][0])
					let y2 = this.fitSize(item.coord[1][1])
					this.ctx.beginPath()
					this.ctx.moveTo(x1, y1)
					this.ctx.lineTo(x2, y2)
					if (this.type === 'app') {
						this.ctx.setStrokeStyle(item.color)
						this.ctx.setLineWidth(item.width)
					} else {
						this.ctx.strokeStyle = item.color
						this.ctx.lineWidth = item.width
					}

					if (item.dash && item.dash.length > 0) {
						//虚线
						this.ctx.setLineDash(item.dash)
					}

					this.ctx.stroke()
					this.ctx.closePath()
				})


			},
			drawCircle(draw) {
				draw.forEach((item) => {
					let x = this.fitSize(item.coord[0][0])
					let y = this.fitSize(item.coord[0][1])
					let r = this.fitSize(item.r)
					this.ctx.beginPath()
					this.ctx.arc(x, y, r, 0, Math.PI * 2, false)
					this.ctx.fillStyle = item.color
					this.ctx.fill()
					this.ctx.closePath()
				})
			},
			fitSize(coordinate) {
			  let newWindowWidth = this.windowWidth;
			  const designWidth = 375; // 设计稿宽度
			  // 修正比例计算：设备宽度 / 设计稿宽度 = 缩放比例
			  const scale = newWindowWidth / designWidth;
			  // 设计稿的坐标 * 缩放比例 = 设备实际坐标
			  return coordinate * scale;
			}

		},

	}
</script>

<style>
</style>