当前位置: 首页 > article >正文

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

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

  1. 上图
    在这里插入图片描述

  2. 上组件

<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. 使用
<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的特性 开发工具显示有问题,真机不影响


http://www.kler.cn/a/504444.html

相关文章:

  • 如何解决Webview和H5缓存问题,确保每次加载最新版本的资源
  • ArkTS 组件事件、状态管理与资源管理
  • 【update 更新数据语法合集】.NET开源ORM框架 SqlSugar 系列
  • 项目概述、开发环境搭建(day01)
  • OpenAI Whisper:语音识别技术的革新者—深入架构与参数
  • 【9.1】Golang后端开发系列--Gin快速入门指南
  • Lua语言的软件开发工具
  • 设计模式-工厂模式/抽象工厂模式
  • 免 root 开启 Pixel 手机 VoLTE 功能
  • 使用Python实现疫情监测系统
  • STM32 FreeRTOS 介绍
  • 【机器学习:十四、TensorFlow与PyTorch的对比分析】
  • 微服务主流框架和基础设施介绍
  • 关于编写测试用例的细枝末节
  • STM32 FreeRTOS 的任务挂起与恢复以及查看任务状态
  • 【算法学习】——整数划分问题详解(动态规划)
  • Nginx是什么?怎么用?
  • 【大数据】机器学习------决策树
  • react Hooks 父组件调用子组件函数、获取子组件属性
  • react与nodejs实现流式传输,并可以进行中断(fetch聊天版)
  • RTX 5090 加持,科研服务器如何颠覆 AI 深度学习构架?
  • 自动驾驶ADAS算法--测试工程环境搭建
  • RDP、VNC、SSH 三种登陆方式的差异解析
  • 工程水印相机结合图纸,真实现场时间地点,如何使用水印相机,超简单方法只教一次!
  • 【免费开源】积木JimuBI大屏集成eladmin
  • arcgis中生成格网矢量带高度