uniapp小程序实现圆环效果

news2025/4/13 12:52:45

文章目录

  • 调用
  • 组件

uniapp小程序利用 canvas2d实现根据指定时间动态画圆环效果
在这里插入图片描述

调用

<view class="dubbing-control" :style="{'width':recordWidth,'height':recordWidth}">
	<dubbing-button v-if="show" :width.sync="recordWidth" :size='71' ref="record" @startRecord="onClickHandle" @stopRecord="onClickHandle" :duration="recordConfig.duration"></dubbing-button>
	<image v-else :style="{'width':'142rpx','height':'142rpx','opacity':'0.4'}" src="../static/xgn/record_img.png"></image>
</view>
<script>
export default {
	data() {
		return {
		show:true,//是否展示录制组件
		recordWidth:'88px',//录制按钮+圆环的宽度  动态设置包裹层大小
		recording:'start',//控制是否录制 start:开始 proceed:进行中 end:结束
		}
	}methods:{
	onClickHandle(recording){
		this.recording = recording;
		if (Object.is(this.recording, 'proceed')) {
			//开始渲染圆环
				this.$refs.record.startRecord();
				this.recording = 'proceed';
			} else {
			//停止渲染圆环并重置
				this.recording = 'end';
			}
		}
	}
}
</script>

组件

<template>
	<view class="dubbing-button">
		<view :style="{width: (2*radius+16)+'px', height:(2*radius+16)+'px'}" :class="['record-button',shadowShow ? 'record-button-shadow' : '']  " @touchstart="onClickHandle">
			<canvas class="progress_bg" v-if="Object.is(recording, 'proceed')" type="2d" id="cpbar" canvas-id="cpbar"
				:style="{width: (2*radius+16)+'px', height:(2*radius+16)+'px'}" ></canvas>
			<image v-if="recording=='proceed'" src="../static/xgn/recording_img.gif" :style="{width: 2*radius+'px', height:2*radius+'px'}">
			<image v-else src="../static/xgn/record_img.png" :style="{width: 2*radius+'px', height:2*radius+'px'}">
			</image>
		</view>
		
	</view>

</template>

<script>
	export default {
		name: 'record-button',
		data() {
			return {
				radius: 0, // 半径
				eAngle: 0, // 结束角度
				interval: null,
				deviceWidth: 0,
				recording: 'start',
				canvasContext: null,
				shadowShow: false,
			};
		},
		props: {
			// 进度条转一圈的时间
			duration: {
				type: Number,
				default () {
					return 20000;
				}
			},
			size: { //图片大小
				type: Number,
				default () {
					return 44;
				}
			},
			width:{ //父元素动态设置包裹层的宽高
				type:String,
				default:''
			},
		},
		created() {
			const res = uni.getSystemInfoSync();
			this.deviceWidth = res.windowWidth;
			this.radius = this.getPointValue(this.size);
			this.width =(2*this.radius+16)+'px'; //给父元素设置宽高
			this.$emit('update:width',this.width)
		},
		mounted() {
			// this.canvasContext = uni.createCanvasContext('cpbar', this);
		},
		methods: {
			// 点击录音处理
			async onClickHandle() {
				console.log('button this.recording',this.recording);
				if (!Object.is(this.recording, 'proceed')) {
					this.shadowShow = true;
				} 
				if (Object.is(this.recording, 'proceed')) {
					//如果是录制中 点击则停止
					this.shadowShow = false;
					this.stopRecord();
				} else {
					//否则开始录制 触发父元素录制功能
					if(this.shadowShow){
					this.$emit('startRecord', 'proceed');
					}
				}
			},
			// 开始录音状态
			startRecord() {
				console.log('开始了')
				this.recording = 'proceed';
				let that = this;
				this.shadowShow = false;
				this.drawCircle();
			},
			// 停止录音状态
			stopRecord(status) {
				status ? this.recording = 'start' : this.recording = 'end';
				let that = this;
				this.$emit('stopRecord', 'end');
				clearTimeout(that.interval);
				this.interval = null;
				this.canvasContext && this.clearCicle();
				this.eAngle = 0;
			},
			// 动态绘制圆环
			drawCircle: function() {
				this.$nextTick(()=>{
					const query = uni.createSelectorQuery().in(this);
					query.select('#cpbar').fields({
						node: true,
						size: true
					}).exec(res => {
						console.log('res',res);
						if(res){
							const canvas = res[0].node;
							const ctx = canvas.getContext("2d");
							const dpr = wx.getSystemInfoSync().pixelRatio;
							canvas.width = res[0].width * dpr;
							canvas.height = res[0].height * dpr;
							ctx.scale(dpr, dpr);
							this.canvasContext = ctx;
							this.drawCircleAction();
						}
					})
				})
			},
			drawCircleAction(){
				this.eAngle += 2 * Math.PI / (this.duration / 100);
				this.canvasContext.lineWidth = 4;
				this.canvasContext.strokeStyle = '#FE9B2F';
				this.canvasContext.lineCap = 'butt';
				this.canvasContext.beginPath();
				// arc(x,y,半径,起始弧度,结束弧度,顺逆时针)
				this.canvasContext.arc(this.radius + 8, this.radius + 8, this.radius + 4, 0, this.eAngle , false);
				this.canvasContext.stroke();
				this.canvasContext.closePath();
				if (this.eAngle >= 2 * Math.PI) {
					this.stopRecord();
				} else {
					let that = this;
					clearTimeout(that.interval);
					this.interval = setTimeout(that.drawCircleAction, 100);
				}
			},
			// 清空圆环
			clearCicle() {
				this.canvasContext.clearRect(0, 0, 2 * this.radius + 16, 2 * this.radius + 16);
			},
			// canvas适配不同机型 算出当前屏幕中实际px大小
			getPointValue(val) {
				return Math.floor(val * this.deviceWidth / 750);
			},
		},
		destroyed() {
			this.stopRecord();
		}
	}
</script>

<style lang="scss" scoped>
	.record-button {
		position: relative;
		image {
			position: absolute;
			left: 50%;
			top: 50%;
			transform: translate(-50%,-50%);
		}

		.progress_bg {
			position: absolute;
			top: 0;
			left: 0;
			z-index: 1;
			transform: rotate(-90deg);
		}
	}
	.record-button-shadow{
		image {
			opacity: 0.4;
		}
	}
	.popup_wrap {
		width: 594rpx;
		border-radius: 20rpx;
		background: #fff;
		box-sizing: border-box;
		padding-top: 48rpx;
		display: flex;
		flex-direction: column;
		box-sizing: border-box;
		box-shadow: 0rpx 6rpx 20rpx 0rpx rgba(255, 214, 170, 0.9);

		.popup_title {
			font-size: 34rpx;
			font-weight: 500;
			color: #283445;
			text-align: center;
			margin-bottom: 48rpx;
			padding: 0 20rpx;
			box-sizing: border-box;
		}

		.popup_footer {
			height: 88rpx;
			width: 100%;
			display: flex;
			align-items: center;
			justify-content: center;
			padding: 0 20rpx;
			box-sizing: border-box;

			view {
				flex: 1;
				border-top: 2rpx solid #dcdcdc;
				text-align: center;
				font-size: 32rpx;
				padding: 22rpx 0;
				box-sizing: border-box;

				text {
					display: block;
					height: 50rpx;
				}
			}

			view.popup_footer_confirm {
				color: #283445;

				text {
					border-left: 2rpx solid #dcdcdc;
				}
			}

			view.popup_footer_cancel {
				color: #7e94b1;
			}
		}
	}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/29054.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

e智团队实验室项目-第四周-YOLOv论文的对比实验中遇到的问题

贾小云*&#xff0c;赵雅玲 *, 张钊* , 李锦玉*&#xff0c;迟梦瑶*&#xff0c;赵尉*&#xff0c;潘玉*&#xff0c;刘立赛&#xff0c;祝大双&#xff0c;李月&#xff0c;曹海艳&#xff0c; (淮北师范大学计算机科学与技术学院&#xff0c;淮北师范大学经济与管理学院&…

2022年度国家级科技企业孵化器开始申报

科技部火炬中心关于开展2022年度国家级科技企业孵化器申报工作的通知各省、自治区、直辖市及计划单列市科技厅&#xff08;委、局&#xff09;&#xff0c;新疆生产建设兵团科技局&#xff1a; 为贯彻落实党的二十大精神&#xff0c;加快实施创新驱动发展战略&#xff0c;加快实…

MySQL操作

目录 1.对库操作 1.1 创建数据库 1.1.1 查看有哪些数据库 1.1.2 指定数据库的字符集 1.1.3 查重创建数据库 1.1.4 查看警告信息 1.1.5 小知识:SQL语句中的分号 1.1.6 小知识:设置默认字符集 1.1.7 小知识:语句中的大小写 1.2 使用/选中数据库 1.3 删除数据库(慎重操作…

PHP视频网站用wamp、phpstudy运行定制开发mysql数据库BS模式

一、源码特点 PHP视频网站是一套完善的web设计系统&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库系统主要采用B/S模式开发,开发环境为PHP APACHE&#xff0c;数据库为mysql5.0&#xff0c;使 用php语言开发 PHP视频网站用wamp、phpstu…

21. [Python GUI] PyQt5中的模型与视图框架-抽象模型基类QAbstractItemModel与自定义模型

PyQt5中的抽象模型基类QAbstractItemModel与自定义模型 一、关于QAbstractItemModel类 QAbstractItemModel类继承自QObject&#xff0c; 该类是Qt所有模型类的基类&#xff0c;用于管理模型/视图结构中的数据。Qt的所有模型都需要子类化该类。注意&#xff0c;该类是抽象类&am…

数字孪生应用方向展示

昨晚&#xff0c;2022年卡塔尔世界杯正式打响&#xff01;伴随开幕式的进行&#xff0c;由中国铁建城建的卡塔尔世界杯主场馆卢赛尔体育场惊艳全球。事实上&#xff0c;在数字孪生技术的加持下&#xff0c;体育场馆建设也是重点技术应用方向之一&#xff0c;今天就为大家重点展…

java读取文件

先看项目截图 public class FileTest {public static void main(String[]args) throws IOException {String path Objects.requireNonNull(FileTest.class.getClassLoader().getResource("")).getPath();System.out.println(path);System.out.println("****…

微信“史诗级”更新,小而美终于回来啦~

最近微信安卓版又有了更新&#xff0c;版本号也来到了8.0.30。 此次更新又被业界称之为“史诗级”更新&#xff0c;主要原因是新版本微信安装包体积缩小了10M。 没错&#xff0c;你没有看错微信的安装包真的缩小了&#xff0c;而且整整缩小了10M&#xff01; 天呐&#xff0…

MyBatis从入门到精通真没那么难!跟着我带你深入实践Mybatis技术原理与实战!

什么是Mybatis mybatis 是一个优秀的基于java的持久层框架&#xff0c;它内部封装了jdbc&#xff0c;使开发者只需要关注sql语句本身&#xff0c;而不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。 mybatis通过xml或注解的方式将要执行的各种 statemen…

跨平台应用开发进阶(四十五)uni-app集成企微客服实战

文章目录一、前言二、功能实现2.1 环境准备2.2 代码层面2.3 拓展工具三、拓展阅读一、前言 应用运营过程中&#xff0c;考虑接入企业微信客服功能&#xff0c;大致看了下官方接入文档&#xff0c;并不困难&#xff0c;引入代码量也不大。按照手册来操作即可。 二、功能实现 …

Go Module的基本使用

go module是类似于java中的maven,是包的管理工具&#xff0c;在没有这个go module之前&#xff0c;都是配置本地的GOPATH&#xff0c;创建的每个项目也都必须创建在这个GOPATH的src目录下&#xff0c;且项目的go文件不能重名 go module是在go1.1.1版本推出的 开启go module 在…

装配式施工在建筑装修中的应用研究

目 录 摘 要 I Abstract II 1引言 1 2装配式施工在建筑装修中的发展背景及现状 2 2.1装配式施工在建筑装修中的发展背景 2 2.2建筑装饰行业现状 2 3装配式施工在建筑装修中体系的主要特点 3 4装配式施工在建筑装修中体系的构成 4 4.1八大系统 4 4.1.1集成卫浴系统 4 4.1.2集成厨…

【App自动化测试】(二)Appium环境部署

目录1. Appium生态工具2. Appium环境安装部署2.1 Appium 环境依赖说明2.2 第一步&#xff1a;安装JDK2.3 第二步&#xff1a;安装SDK2.4 第三步&#xff1a;安装Appium2.5 第四步&#xff1a;安装appium python client2.6 第五步&#xff1a;安装appium-doctor检测appium的安装…

Metabase学习教程:视图-1

你应该用哪个图表&#xff1f; 您应该使用哪种类型的图表和图表来最好地传达来自数据的见解&#xff1f;这将有助于你选择正确的工作。 选择正确的图表可以归结为两个问题&#xff1a;数据是什么样子的&#xff0c;以及您试图传达什么&#xff1f; 让Metabase为您选择图表 …

Day01-网页结构分析

网页结构分析 一 前言 姓名&#xff1a;陈云 TEL&#xff1a;18571593511 企业用人的两个标准 1.能干活,见到需求能反应出粗线条实施计划,起手实施后能自主预判和解决坑点,直至完成. 2.对某些敏感点理解较准确,有一定潜质做个性化封装和技术选型工作,应对突发状况,避免生…

SpringBoot--通过JSON传递请求参数--方法/实例

原文网址&#xff1a;SpringBoot--通过JSON传递请求参数--方法/实例_IT利刃出鞘的博客-CSDN博客 简介 本文用示例介绍SpringMVC如何通过JSON格式传递入参。 JSON格式使用post方式来请求&#xff0c;即&#xff1a;对应的注解为&#xff1a;PostMapping。 PostMapping注解的方法…

Vue学习笔记

课程来源&#xff1a;https://www.bilibili.com/video/BV1Zy4y1K7SH?p4&vd_source6f37192b213c98639a87ec77b26d105d 学习计划&#xff1a;一天学10节&#xff0c;从第四节开始做笔记&#xff0c;预计16天完成&#xff08;完成日期2022年12月7日&#xff09; 目录&#…

【1】Anaconda基本命令以及相关工具:jupyter、numpy、Matplotilb

目录 一、Anaconda ◼ anaconda命令行操作 二、jupyter notebook 1 jupyter的基础使用 ◼ jupyter的启动 ◼ ipynb文件的新建、重命名、删除 ◼ 菜单说明 ◼ 运行cell单元块 ◼ 编写文档笔记 2 jupyter的高级使用&#xff1a;常用魔法命令 ◼ writefile pycat run …

【Golang】来用GoLand开发第一个Go程序

​ &#x1f4d3;推荐网站(不断完善中)&#xff1a;个人博客 ​ &#x1f4cc;个人主页&#xff1a;个人主页 ​ &#x1f449;相关专栏&#xff1a;CSDN专栏、个人专栏 ​ &#x1f3dd;立志赚钱&#xff0c;干活想躺&#xff0c;瞎分享的摸鱼工程师一枚 文章目录&#x1f34a…

【JAVA程序设计】基于JAVA的坦克大战小游戏--入门级小游戏

基于JAVA的坦克大战小游戏--入门级小游戏零、项目获取一、项目简介二、开发环境三、游戏玩法四、运行截图零、项目获取 获取方式&#xff08;点击下载&#xff09;&#xff1a;是云猿实战 项目经过多人测试运行&#xff0c;可以确保100%成功运行。 一、项目简介 本项目是基于…