uniapp 支付宝小程序使用canvas 绘制图案
1. canvas 片段, 支付宝用的id 是 id, 不是 canvas-id
<canvas class="canvas-process" id="canvas" :width="width" :height="height" ></canvas>
2. 在onload里面进行一些预定义设置
const systemInfo = uni.getSystemInfoSync(); this.pixelRatio = systemInfo.pixelRatio; // canvas 的宽度不等于 容器的宽度 this.width = uni.upx2px(750) * this.pixelRatio; this.height = uni.upx2px(448) * this.pixelRatio;
3. 因为绘制图形必须等容器加载完成. 所以在nextTick中调用绘制
this.$nextTick(() => { this.drawProcess(process); });
4. 绘制准备, 和微信小程序的区别是 这里不需要使用 scale(x, y) 进行缩放
const context = uni.createCanvasContext("canvas"); const size = (x) => uni.upx2px(x) * this.pixelRatio; // 下面所有的储存都需要调用这个 函数 const w = uni.upx2px(750) * this.pixelRatio; // canvas 的宽度, 不需要调用 size 函数 const h = uni.upx2px(448) * this.pixelRatio; // canvs 的高度, 不需要调用 size 函数
for example
// 绘制进度条 drawProcess(process) { console.log("渲染canvas"); const context = uni.createCanvasContext("canvas"); const size = (x) => uni.upx2px(x) * this.pixelRatio; const w = uni.upx2px(750) * this.pixelRatio; const h = uni.upx2px(448) * this.pixelRatio; const pai = Math.PI; const percentage = process / 100; const endAngle = pai * percentage * 2; // 请除之前的样式 context.setFillStyle("#fff"); context.fillRect(0, 0, w, h); context.setShadow(0, 0, 0, "rgba(255,255,255,0)"); // 绘制最大的圆环 context.moveTo(w / 2, h / 2); context.beginPath(); context.arc(w / 2, h / 2, size(180), 0, 2 * pai, true); const grd = context.createCircularGradient(w / 2, h / 2, size(180)); grd.addColorStop(0, "#a9caff"); grd.addColorStop(1, "#e0ebff"); context.setFillStyle(grd); context.fill(); // 绘制内部的白色圆环 context.moveTo(w / 2, h / 2); context.beginPath(); context.arc(w / 2, h / 2, size(125), 0, 2 * pai, true); context.setFillStyle("#ffffff"); context.fill(); // 绘制进度 context.moveTo(w / 2, h / 2); context.beginPath(); context.arc(w / 2, h / 2, size(137), pai, endAngle + pai); context.setStrokeStyle("#0967ff"); context.setLineCap("round"); context.setLineWidth(size(24)); context.stroke(); // 求终点坐标 /** * cosA = x / r sinA = y / r * x = r * cosA y = r * sinA */ const endPointX = size(137) * Math.cos(endAngle + pai); const endPointY = size(137) * Math.sin(endAngle + pai); // 绘制终点 大白色圆 ----> 移动圆心到中心点位置 context.moveTo(endPointX, endPointY); context.beginPath(); context.arc(w / 2 + endPointX, h / 2 + endPointY, size(28), 0, 2 * pai); context.setShadow(0, size(12), size(16), "rgba(9,103,255, 0.3)"); context.setFillStyle("#fff"); context.fill(); // 绘制小蓝圆 context.beginPath(); context.arc(w / 2 + endPointX, h / 2 + endPointY, size(20), 0, 2 * pai); context.setFillStyle("#0967ff"); context.fill(); // 绘制进度文字 context.beginPath(); context.setTextAlign("center"); context.setTextBaseline("middle"); context.setFontSize(size(48)); context.setFillStyle("#0967ff"); context.fillText(`${process}%`, w / 2, h / 2); context.draw(); },
本想把生活活成一首诗, 时而优雅 , 时而豪放 , 结果活成了一首歌 , 时而不靠谱 , 时而不着调