uniapp 小程序 五星评分精确到0.1
uniapp 小程序 五星评分精确到0.1
-
上图
-
上组件
<template>
<view class="container">
<view class="canvas-wrap">
<canvas
type="2d"
id="canvas"
class="canvas"
disable-scroll="true"
></canvas>
</view>
</view>
</template>
<script>
// star style
const ratingColor = '#CBB195';
const starColor = '#fff';
const borderColor = '#CBB195';
const borderWidth = uni.upx2px(2);
const height = uni.upx2px(24);
const width = uni.upx2px(144);
// star config
const disabled = false;
const starNum = 5;
const step = 0.1;
const toFixed = 1;
const starGap = uni.upx2px(6);
const oneStarPercent = 20;
const oneStepPercent = 2;
const starWidth = Math.floor((width - starNum * starGap) / starNum);
const degree = 72
export default {
props:{
score: {
type: Number,
default (){
return 0
}
},
// 总分为5时 type传1
// 总分为100时 type传2
// 也可自定义总分
type: {
type: Number,
default (){
return 1
}
},
ratingColor: {
type: String,
default (){
return '#CBB195'
}
},
starColor: {
type: String,
default (){
return '#fff'
}
},
borderColor: {
type: String,
default (){
return '#CBB195'
}
},
},
data() {
this.canvasDraw = null // 绘图对象
this.canvasEle = null // canvas元素对象
this.canvasNode = null
this.percent = 0
return {
isDrawing: false, // 是否正在绘图
}
},
created() {},
beforeDestroy() {
/** 销毁对象 */
if (this.canvasDraw) {
this.canvasDraw = null // 绘图对象
this.canvasEle = null // canvas元素对象
this.canvasNode = null
}
},
mounted() {
/** 初始化 */
let that = this
setTimeout(()=>{
that.$nextTick(()=>{
that.initCanvas()
})
},300)
},
methods: {
/** 初始化canvas */
initCanvas() {
const query = wx.createSelectorQuery().in(this)
query
.select('#canvas')
.fields({ node: true, size: true, rect: true })
.exec((res) => {
const ele = res[0]
const pixelRatio = wx.getSystemInfoSync().pixelRatio
this.canvasEle = ele
this.canvasNode = ele.node // wx的canvas节点
this.canvasNode.width = ele.width * pixelRatio // 设置canvas节点宽度
this.canvasNode.height = ele.height * pixelRatio // 设置canvas节点高度
this.canvasDraw = this.canvasNode.getContext('2d')
this.canvasDraw.scale(pixelRatio, pixelRatio)
if(this.score){
console.log(this.score)
this.drawRate(this.score)
}
})
},
drawRate(value) {
// 此处可根据自身的总分 计算五星比例
if(this.type == 2){
value = (value/20).toFixed(1)
}
this.percent = value * oneStarPercent;
for (let i = 0; i < starNum; i++) {
this.drawStar({
x: starWidth / 2 + i * (starWidth + starGap) + starGap / 2,
y: height / 2,
r: starWidth / 4,
R: starWidth / 2,
rot: 0,
index: i
})
}
},
drawStar({x, y, r, R, rot, index}){
const gradient = this.canvasDraw.createLinearGradient(x - R, 0 , x + R, 0)
const stop = Math.min(Math.max((index + 1) * oneStarPercent - this.percent, 0), oneStarPercent)
const rate = (oneStarPercent - stop) / oneStarPercent
gradient.addColorStop(rate, this.ratingColor)
gradient.addColorStop(Math.min(1, rate + 0.01), this.starColor)
this.canvasDraw.beginPath();
for (let i = 0; i < 360 / degree; i ++) {
this.canvasDraw.lineTo( Math.cos( (18 + i*degree - rot)/180 * Math.PI) * R + x,
-Math.sin( (18 + i*degree - rot)/180 * Math.PI) * R + y)
this.canvasDraw.lineTo( Math.cos( (54 + i*degree - rot)/180 * Math.PI) * r + x,
-Math.sin( (54 + i*degree - rot)/180 * Math.PI) * r + y)
}
this.canvasDraw.closePath();
this.canvasDraw.lineWidth = borderWidth;
this.canvasDraw.fillStyle = gradient;
this.canvasDraw.strokeStyle = this.borderColor;
this.canvasDraw.lineJoin = "round";
this.canvasDraw.fill();
this.canvasDraw.stroke();
}
},
}
</script>
<style>
.container {
width: 144rpx;
height: 24rpx;
}
.canvas-wrap {
display: flex;
height: 100%;
/* background: #FFFFFF; */
}
.canvas {
flex: 1;
width: 100%;
height: 100%;
/* background: #FFFFFF; */
}
</style>
- 使用
<template>
<view class="star-box">
<starRate v-if="score" :score="score" type="2"></starRate>
</view>
</template>
<script>
import starRate from './starRate.vue'
export default {
components:{ starRate },
data(){
return {
score:100
}
}
};
</script>
- 搞定!