uniapp 小程序 五星评分精确到0.1

uniapp 小程序 五星评分精确到0.1

  1. 上图

  2. 上组件

javascript 复制代码
<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>
  1. 使用
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>
  1. 搞定!

注意 由于原生canvas的特性 开发工具显示有问题,真机不影响

相关推荐
ZC跨境爬虫7 小时前
跟着 MDN 学JavaScript day_7:数学运算与逻辑判断实战测试
开发语言·前端·javascript·学习·ecmascript
凌云拓界8 小时前
文件管理:让AI安全操作你的电脑 ——CogitoAgent开发实战(三)
javascript·人工智能·架构·开源·node.js
凌云拓界8 小时前
联网能力:让AI看见更广阔的世界 ——CogitoAgent开发实战(四)
javascript·人工智能·架构·node.js·创业创新
HYCS9 小时前
用pixi.js实现fabric.js(六):从线性代数的角度理解编辑器交互
前端·javascript·canvas
you458010 小时前
学成在线--day02 CMS前端开发(含Vue基础知识得回顾)
前端·javascript·vue.js
想吃火锅100510 小时前
【leetcode】1.两数之和js版
javascript·算法·leetcode
xiaofeichaichai10 小时前
虚拟 DOM
前端·javascript·vue.js
CRMEB系统商城10 小时前
CRMEB多商户系统(Java)v2.3公测版发布
java·开发语言·人工智能·小程序·开源·php
初一初十10 小时前
vue3实现的纯前端护肤品商城网站
前端·javascript·vue.js·前端框架
ANnianStriver11 小时前
PetLumina 07 — 宠物管理升级与 JavaScript 大数精度修复
开发语言·javascript·ai编程·宠物