Page({ data: { gridWidth: 5, width: 800, height: 300, }, onReady() { // 使用 wx.createCanvasContext 创建绘图上下文 const backgroundCtx = wx.createCanvasContext('background'); console.log(backgroundCtx) this.drawGrid(backgroundCtx); backgroundCtx.draw(); // 必须调用 draw 方法将绘制提交到 canvas 上 // 启动波形绘制 const lineCtx = wx.createCanvasContext('line'); this.initializeWaves(lineCtx); }, drawGrid(ctx) { const { width, height, gridWidth } = this.data; const hLineNum = parseInt(height / gridWidth); const vLineNum = parseInt(width / gridWidth); ctx.setLineWidth(1); ctx.setStrokeStyle("#ffbebe"); // 横线 for (let i = 0; i < hLineNum; i++) { if (i === 0 || i % 5 !== 0) { ctx.beginPath(); ctx.moveTo(0, i * gridWidth); ctx.lineTo(width, i * gridWidth); ctx.stroke(); } } // 竖线 for (let i = 0; i < vLineNum; i++) { if (i === 0 || i % 5 !== 0) { ctx.beginPath(); ctx.moveTo(i * gridWidth, 0); ctx.lineTo(i * gridWidth, height); ctx.stroke(); } } // 粗线 ctx.setStrokeStyle("#FF7F50"); for (let i = 5; i <= vLineNum; i += 5) { ctx.beginPath(); ctx.moveTo(i * gridWidth, 0); ctx.lineTo(i * gridWidth, height); ctx.stroke(); } for (let i = 5; i <= hLineNum; i += 5) { ctx.beginPath(); ctx.moveTo(0, i * gridWidth); ctx.lineTo(width, i * gridWidth); ctx.stroke(); } }, initializeWaves(ctx) { // 配置波形参数 const waveViews = [ { frameSize: 250, yMax: 250, y_offset: 0, step: 10, speedRatio: 1, strokeStyle: '#00ff00', }, { frameSize: 125, yMax: 250, y_offset: 100, step: 10, speedRatio: 0.5, strokeStyle: '#00ff00', }, { frameSize: 60, yMax: 250, y_offset: 200, step: 4, speedRatio: 1, strokeStyle: '#00F5FF', }, ]; // 初始化波形实例并启动动画 waveViews.forEach((config) => { const wave = new this.WaveView(ctx, config); wave.loop(); }); }, WaveView(ctx, { frameSize, yMax, y_offset, step, speedRatio, strokeStyle }) { this.ctx = ctx; this.currentX = 0; this.currentY = 0; this.lastX = 0; this.lastY = 0; this.step = step; this.yMax = yMax; this.y_offset = y_offset; this.queue = []; this.strokeStyle = strokeStyle; this.speedRatio = speedRatio; this.itemHeight = 100; this.clearGap = 20; this.drawInterval = Math.floor((1 / frameSize) * 1000 * step); this.draw = () => { ctx.beginPath(); ctx.setStrokeStyle(this.strokeStyle); // 清除部分画布,避免图像重叠 if (this.lastX === 0) { ctx.clearRect(this.currentX - 2, this.y_offset, this.clearGap, this.itemHeight); } else { ctx.clearRect(this.currentX + this.lastX, this.y_offset, this.clearGap, this.itemHeight); } // 绘制波形 for (let i = 0; i < this.step; i++) { if (this.queue.length === 0) { this.currentY = this.itemHeight / 2; } else { this.currentY = (-1.0 * this.queue.shift()) / this.yMax * this.itemHeight + this.itemHeight; } ctx.moveTo(this.currentX + this.lastX, this.y_offset + this.lastY); ctx.lineTo(this.currentX, this.y_offset + this.currentY); this.lastX = this.currentX; this.lastY = this.currentY; this.currentX += (this.step * 25 * this.speedRatio) / frameSize; if (this.currentX >= 800 - 25) { this.currentX = 0; this.lastX = 0; } } ctx.stroke(); ctx.draw(); // 必须提交绘制 }; this.loop = () => { this.draw(); setTimeout(this.loop, this.drawInterval); // 循环调用 }; this.addData = (arr) => { this.queue.push(...arr); // 添加数据到队列 }; }, });