您的位置:首页 > 移动开发 > 微信开发

微信小程序canvas 实现信用图表

2018-02-03 16:13 429 查看
前言:APP当时模仿着阿里支付宝画了一个图标,当初是以java去实现的。现在在开发公司的微信小程序,又根据当时写的代码通过微信小程序canvas的相关接口。从头又画了一次,对微信小程序的canvas理解更加深刻了。在这里直接贴一下代码,记录一下。也给需要的小伙伴一些参考。

效果图:



wxml:

<!--pages/mine/report/report.wxml-->
<view class='container'>
<canvas canvas-id="credit-canvas" class='credit-canvas'></canvas>

</view>
js:

// pages/mine/report/report.js
Page({

/**
* 页面的初始数据
*/
data: {
canvasWidth: 0,
canvasHeight: 0,
currentNum: 500,
timeText:"2017-12"
},

/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
//获取画布大小
const that = this;
wx.createSelectorQuery().select(".credit-canvas").boundingClientRect(function (rect) {
that.setData({
canvasWidth: rect.width,
canvasHeight: rect.height
})
}).exec()
},

/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
this.drawCredit();
},

/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
this.timeout = setTimeout(this.drawCredit, 100);
},

/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {

},

/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {

},

/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {

},

/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {

},

/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {

},
drawCredit: function () {
const that = this;
const ctx = wx.createCanvasContext('credit-canvas');
// 圆弧半径
const radius = this.data.canvasWidth * 3 / 10;
// 内圆宽度
const sweepInWidth = 10;
// 外圆宽度
const sweepOutWidth = 3;
// 圆弧初始的弧度
const startAngle = 0.9 * Math.PI;
// 圆弧结束的弧度
const endAngle = 2.1 * Math.PI;
// 圆弧扫过的弧度
const sweepAngle = 1.2 * Math.PI;
// 信用分值
let currentNum = that.data.currentNum
// 信用评级
const leverText = ["C", "CC", "CCC", "B", "BB", "BBB", "A", "AA", "AAA"];
// 信用等级
const creditLeverText = ["差", "欠佳", "一般", "较好", "良好", "优良"];
ctx.translate(this.data.canvasWidth / 2, this.data.canvasHeight * 3 / 4);
// 画内外圆弧
function drawRound() {
// 内圆
// 保存画布
ctx.save();
// 每次设置画笔时要调用这个beginPath,非则以最后一次为准。
ctx.beginPath();
// 设置画笔宽度
ctx.setLineWidth(sweepInWidth);
// 设置画笔颜色
ctx.setStrokeStyle('rgba(255, 255, 255, 0.2)')
// 画内圆弧形,角度为162度~378度,起始位置由于调用过ctx.translate(this.data.canvasWidth/2,this.data.canvasHeight*3/4);,所以在中心位置
ctx.arc(0, 0, radius, startAngle, endAngle);
// 描绘路径边框
ctx.stroke();
// 画外圆
ctx.beginPath()
ctx.setLineWidth(sweepOutWidth);
ctx.setStrokeStyle('rgba(255, 255, 255, 0.2)')
ctx.arc(0, 0, radius + 10, startAngle, endAngle);
ctx.stroke();
// 还原画布
ctx.restore();
}

function drawScale() {
// 画刻度
const startNum = 300;
// 画布旋转弧度
const angle = 6 * Math.PI / 180;
ctx.save();
ctx.rotate((-1.5 * Math.PI) + startAngle)
for (let i = 0; i <= 36; i++) {
if (i % 6 === 0) {
//画粗刻度并写数值
ctx.beginPath()
ctx.setLineWidth(2)
ctx.setStrokeStyle('rgba(255, 255, 255, 0.7)')
ctx.moveTo(0, -radius - sweepInWidth / 2);
ctx.lineTo(0, -radius + sweepInWidth / 2 + 1);
ctx.stroke()

// 设置文字画笔
ctx.setFontSize(9)
ctx.setTextAlign('center')
ctx.setFillStyle('rgba(255, 255, 255, 0.4)')
if (i === 36) {
ctx.fillText(">1000", 0, -radius + 15)
} else if (i === 0) {
ctx.fillText("0-300", 0, -radius + 15)
} else {
ctx.fillText(startNum + (i / 6 * 100) + "", 0, -radius + 15)
}
} else {
ctx.beginPath()
ctx.setLineWidth(1)
ctx.setStrokeStyle('rgba(255, 255, 255, 0.4)')
ctx.moveTo(0, -radius - sweepInWidth / 2);
ctx.lineTo(0, -radius + sweepInWidth / 2 + 1);
ctx.stroke()
}
if (i === 3 || i === 9 || i === 15 || i === 21 || i === 27 || i === 33) {
ctx.fillText(leverText[((i - 3) / 6) + 3], 0, -radius + 15)
}
ctx.rotate(angle)
}
// 还原画布
ctx.restore(
b583
);
}

function drawIndicator() {
ctx.save();
let sweep = 0;
if (currentNum <= 300) {
sweep = 0;
} else if (currentNum <= 800 && currentNum > 300) {
sweep = (currentNum - 300) * sweepAngle / 600;
} else if (currentNum > 800 && currentNum <= 1000) {
sweep = (5 * sweepAngle / 6) + ((currentNum - 800) * sweepAngle / 1200);
} else {
sweep = sweepAngle;
}

// 画指示点圆弧
const grd = ctx.createLinearGradient(0, 0, 200, 0)
grd.addColorStop(0, 'rgba(255, 255, 255, 0.4)')
grd.addColorStop(1, 'rgba(255, 255, 255, 0.7)')
ctx.beginPath()
ctx.setStrokeStyle(grd)
ctx.setLineWidth(sweepOutWidth);
ctx.arc(0, 0, radius + 10, startAngle, startAngle+sweep);
ctx.stroke()
// 画指示点
let x = (radius + 10) * Math.cos(startAngle + sweep)
let y = (radius + 10) * Math.sin(startAngle + sweep)
ctx.beginPath()
ctx.setStrokeStyle('white')
ctx.fill()
ctx.arc(x,y,3,0,2*Math.PI)
ctx.stroke()
// 还原画布
ctx.restore();
}

function drawCenterText(){
ctx.save();
//设置文字画笔
ctx.beginPath();
ctx.setFontSize(radius/6)
ctx.setTextAlign('center')
ctx.setFillStyle('white')
let lever="信用等级:"
if (currentNum < 100) {
lever += leverText[0];
} else if (currentNum >= 100 && currentNum < 200) {
lever += leverText[1];
} else if (currentNum >= 200 && currentNum < 300) {
lever += leverText[2];
} else if (currentNum >= 300 && currentNum < 400) {
lever += leverText[3];
} else if (currentNum >= 400 && currentNum < 500) {
lever += leverText[4];
} else if (currentNum >= 500 && currentNum < 600) {
lever += leverText[5];
} else if (currentNum >= 600 && currentNum < 700) {
lever += leverText[6];
} else if (currentNum >= 700 && currentNum < 800) {
lever += leverText[7];
} else if (currentNum >= 800) {
lever += leverText[8];
}
ctx.fillText(lever, 0, -radius / 2)

// 绘制信用分值
ctx.setFontSize(radius / 4)
ctx.fillText(currentNum, 0, -radius / 6)

// 绘制信用评估
let content = "信用";
let maxNum=1000;
if (currentNum < maxNum * 4 / 10) {
content += creditLeverText[0];
} else if (currentNum >= maxNum * 4 / 10 && currentNum < maxNum * 5 / 10) {
content += creditLeverText[1];
} else if (currentNum >= maxNum * 5 / 10 && currentNum < maxNum * 6 / 10) {
content += creditLeverText[2];
} else if (currentNum >= maxNum * 6 / 10 && currentNum < maxNum * 7 / 10) {
content += creditLeverText[3];
} else if (currentNum >= maxNum * 7 / 10 && currentNum < maxNum * 8 / 10) {
content += creditLeverText[4];
} else if (currentNum >= maxNum * 8 / 10) {
content += creditLeverText[5];
}
ctx.setFontSize(radius / 4)
ctx.fillText(content, 0, radius / 8)

// 评估时间
ctx.setFontSize(15)
ctx.setFillStyle('rgba(255,255,255,0.4)')
ctx.fillText("评估时间:" + that.data.timeText, 0, radius / 3)

// 还原画布
ctx.restore();

console.log("正在画画.....")
}

drawRound();
drawScale();
drawIndicator();
drawCenterText();
ctx.draw()
},

})


wxss:

/* pages/mine/report/report.wxss */
page{
height: 100%;
}

.credit-canvas{
width: 100%;
height: 35%;
background-image: url("http://www.datacubr.com/img/bg_report.png");
background-size: 100% 100%;
background-repeat: no-repeat;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: