<template> <view class="page"> <canvas type="2d" id="myCanvas" /> </view> </template> <script> export default { data() { return { ctx: null, }; }, methods: { draw() { if (!this.ctx) return; const ctx = this.ctx; const size = (s) => uni.upx2px(s); const pai = Math.PI; // 绘制基础的圆 ctx.beginPath(); ctx.moveTo(size(375), size(375)); ctx.arc(size(375), size(375), size(183), 0, Math.PI * 2); ctx.fillStyle = "#fff"; ctx.fill(); // ctx.clip(); // ctx.save(); let count = 0; setInterval(() => { count++; count = count > 360 ? 0 : count; drawCount(count); }, 120); // 绘制波浪线的部分 function drawCount(count) { ctx.clearRect(0, 0, size(750), size(750)); // 获取二次贝塞尔曲线的点 const points = []; for (let i = 0; i <= 2 * pai; i += pai / 2) { const y = Math.sin(i - (count * pai) / 12); points.push([i, Number(y.toFixed(2))]); } ctx.beginPath(); const bili = size(375) / pai; ctx.lineTo(points[0][0] * bili, points[0][1] + size(375)); ctx.bezierCurveTo( points[1][0] * bili, points[1][1] * size(40) + size(375), points[3][0] * bili, points[3][1] * size(40) + size(375), points[4][0] * bili, points[4][1] * size(40) + size(375) ); ctx.lineTo(size(750), size(750)); ctx.lineTo(size(0), size(750)); ctx.fillStyle = "#fea448"; ctx.fill(); // ctx.restore(); } }, }, onReady() { const _this = this; const query = wx.createSelectorQuery(); query .select("#myCanvas") .fields({ node: true, size: true }) .exec((res) => { const canvas = res[0].node; const ctx = canvas.getContext("2d"); const dpr = wx.getSystemInfoSync().pixelRatio; canvas.width = res[0].width * dpr; canvas.height = res[0].height * dpr; ctx.scale(dpr, dpr); _this.ctx = ctx; _this.draw(); }); }, }; </script> <style> page { background: #f6f5f8; } </style> <style lang='scss' scoped> #myCanvas { width: 750rpx; height: 750rpx; background-color: #c7edcc; } </style>
需要注意的是canvas 在微信小程序里面的层级相当的高, 任何定位元素都无法覆盖到 canvas 组件的上面