uniapp 小程序 五星评分精确到0.1
-
上图
-
上组件
javascript"><template><view class="container"><view class="canvas-wrap"><canvastype="2d"id="canvas"class="canvas"disable-scroll="true"></canvas></view></view>
</template>
<script>// star styleconst ratingColor = '#CBB195';const starColor = '#fff';const borderColor = '#CBB195';const borderWidth = uni.upx2px(2);const height = uni.upx2px(24);const width = uni.upx2px(144);// star configconst 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 = 72export 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 = nullthis.percent = 0return {isDrawing: false, // 是否正在绘图}},created() {},beforeDestroy() {/** 销毁对象 */if (this.canvasDraw) {this.canvasDraw = null // 绘图对象this.canvasEle = null // canvas元素对象this.canvasNode = null }},mounted() {/** 初始化 */let that = thissetTimeout(()=>{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().pixelRatiothis.canvasEle = elethis.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) / oneStarPercentgradient.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>
- 使用
javascript"><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>
- 搞定!