手把手教你实现振动记录器
yuyutoo 2025-05-28 21:29 6 浏览 0 评论
概述
本文只涉及实现及代码讲解,不涉及具体技术的讲解,并尽量每一行代码都有详尽的注释,先实现,后积累。
前端 - 入门级教程 - 简易振动记录器
本文教大家实现一个简易的振动记录器。包括 短振动、长振动、振动录制开始/停止功能、播放功能,分享功能等
技术栈使用 uniapp-vue3 版本,工具使用 HbuilderX,真机App调试,微信小程序调试;
效果如下图:
分享效果如下图:
1. 安装HbuilderX 最新版最新版
https://www.dcloud.io/hbuilderx.html
2. 安装 微信开发者工具
https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html
3. 打开HbuilderX 文件 - 新建 - 项目,新增一个uniapp项目,选择vue3版本
代码编写
直接修改新建项目中的 /pages/index/index.vue 文件即可
整体结构
<template>
</template>
<script setup>
</script>
<style lang="scss" scoped>
</style>
<template>部分
<template>
<view class="content">
<!-- 一个在抖动的图片 class 里面的shake类是一个左右振动的动画 -->
<image class="logo shake" src="/static//vibrate.jpg"></image>
<!-- 提示信息 -->
<uni-title type="h1" title="点击下方按钮让手机振动"></uni-title>
<!-- 短振动按钮,点击调用一次短震动,如果正在录制,那么往记录信息里面加一条数据 -->
<button @click="onShortVibrate" type="primary">短振动</button>
<!-- 长振动按钮,点击调用一次长振动,如果正在录制,那么往记录信息里面加一条数据 -->
<button @click="onLongVibrate" type="primary">长振动</button>
<!-- 提示信息 -->
<uni-title type="h1" title="点击开始/停止录制"></uni-title>
<uni-title type="h1" title="上方两个按钮的震动记录"></uni-title>
<!-- 开始/停止录制振动按钮,点击之后开始或者停止振动 -->
<button @click="onStartRecord" type="warn">{{vibrate.recordStatus ? '停止' : '开始'}}录制振动</button>
<!-- 播放已经录制的振动 -->
<button @click="onPlayRecord" :type="vibrate.isShowing ? 'default' : 'primary'">{{vibrate.isShowing ? '播放中...' : '播放振动'}}</button>
<!-- 分享按钮 小程序中必须要有 open-type="share" -->
<button open-type="share">分享</button>
</view>
</template>
<script setup>部分
import {
reactive
} from "vue";
// 来自官方文档的用法,引入分享的监听
import {
onShareAppMessage
} from '@dcloudio/uni-app'
// 震动状态
const vibrate = reactive({
// 用来延时控制动画,暂时不使用,会导致振动接口调用延迟
status : "stop",
// 如果要做多个录制的记录,这里放要展示的录制信息
records: [],
// 当前录制的数据
// [{time:0,type:'short/long/stop'}] : time:相对时间
nowRecords:[],
// 是否正在录制中
recordStatus : false,
// 开始录制的时间戳
startTime:0,
// 是否在演示模式
isShowing:false,
// 一分钟录制限制
limitTimer:null
})
// 点击短震动
const onShortVibrate = () => {
// 不在演示模式,并且正在录制中,演示模式时不加记录
if(! vibrate.isShowing && vibrate.recordStatus){
// 向当前录制的振动信息里面放一条新的数据
vibrate.nowRecords.push({
time: new Date().getTime() - vibrate.startTime,
type : 'short'
})
}
// 调用短震动
uni.vibrateShort();
}
const onLongVibrate = () => {
// 不在演示模式,并且正在录制中,演示模式时加记录
if(! vibrate.isShowing && vibrate.recordStatus){
// 向当前录制的振动信息里面放一条新的数据
vibrate.nowRecords.push({
time: new Date().getTime() - vibrate.startTime,
type : 'long'
})
}
// 调用长振动
uni.vibrateLong();
}
// 开始/停止录制振动
const onStartRecord = () => {
// 如果正在录制中,那么停止录制
if(vibrate.recordStatus){
// 结束时间是点击按钮的时候,并不是点击确认停止的时候,所以放在这里
let stopTime = new Date().getTime();
// 调起一个交互框,询问是否需要停止录制
uni.showModal({
title:"提示",
content:"确认停止录制吗?",
success: (res) => {
// 如果点击的是确认按钮
if(res.confirm === true){
// 此时停止记录,并把停止时间放进去
if(vibrate.nowRecords.length === 0){
uni.showToast({
icon:"error",
title:"至少振动一次"
})
return;
}
// 把正在录制标识改为false
vibrate.recordStatus = false;
// 加入一条停止播放的记录
vibrate.nowRecords.push({
time : stopTime - vibrate.startTime,
type : 'stop'
})
// 清空一分钟限制的setTimeout
clearTimeout(vibrate.limitTimer)
// 提示信息
uni.showToast({
icon:"success",
title:"录制成功!"
})
}
}
})
}else{
// 询问是否开始录制
uni.showModal({
title:"提示",
content:"确认开始录制吗?",
success: (res) => {
// 如果点击的是确定
if(res.confirm === true){
// 提示开始记录
uni.showToast({
icon:"success",
title:"开始录制振动"
})
// 开始录制
vibrate.recordStatus = true;
// 清空原本的录制信息
// todo:如果有多个录制,那么先把原始录制放到录制列表里面去,并给个名称
vibrate.nowRecords = [];
// 记录开始录制的时间,后面所有的事件都要减去这个时间,记录相对值
vibrate.startTime = new Date().getTime();
// 一分钟限制的延时器,即在一分钟后直接执行停止录制操作
vibrate.limitTimer = setTimeout(()=>{
let stopTime = new Date().getTime();
// 此时停止记录
vibrate.recordStatus = false;
// 并把停止时间放进去
vibrate.nowRecords.push({
time : stopTime - vibrate.startTime,
type : 'stop'
});
// 提示一下
uni.showToast({
icon:"success",
title:"最长录制一分钟"
})
console.log("达到一分钟限制")
},60*1000)
}
}
})
}
}
// 播放震动
const onPlayRecord = () => {
// 如果已经在播放中了,就直接返回了,不执行任何操作
if(vibrate.isShowing) return ;
// 如果记录数组的长度是0,说明还没开始录制,给个提示并退出函数
if(vibrate.nowRecords.length == 0 ) {
uni.showToast({
icon:"error",
title:"尚未进行录制"
})
return ;
}
// 如果当前正在录制中,同样退出函数
if(vibrate.recordStatus){
uni.showToast({
icon:"error",
title:"正在录制中"
})
return ;
}
// 开始播放
vibrate.isShowing = true;
// 循环每一条已经记录好的振动记录
for(let i = 0; i < vibrate.nowRecords.length; i ++ ){
// 当前处理的这一条记录
const item = vibrate.nowRecords[i];
// 根据记录的相对时间进行延迟操作,这样所有的记录就会按照原来录制的顺序一条一条进行操作了
// setTimeout(() => {要执行的操作}, 延迟的时间);
setTimeout(() => {
if(item.type == 'short'){
// 如果记录的是短振动,执行短振动
onShortVibrate();
}
if(item.type == 'long'){
// 如果记录的是长振动,执行长振动
onLongVibrate();
}
// 如果遇到停止标识,或者已经执行到最后一条记录
if(item.type == 'stop' || i == vibrate.nowRecords.length - 1){
// 提示一下,已经播放完毕
uni.showToast({
icon:"success",
title:"播放完毕!"
})
// 并恢复正在播放标识
vibrate.isShowing = false;
}
},item.time)
}
}
// 这里是微信小程序的监听分享的方法,分享的效果在上图
onShareAppMessage((res) => {
return {
title: "振动录制器", // 分享的名称
path: "/pages/index/index" // 分享出去的地址
}
})
<style lang="scss" scoped>部分
.content {
/** 上下左右内边距都为 15rpx */
padding:15rpx;
/* 使用flex布局 */
display: flex;
/* 布局方向为列方向,即竖着排列 */
flex-direction: column;
/* 水平布局为flex的开始位置对齐,即在纵向上从顶部开始布局 */
justify-content: flex-start;
/* 在垂直方向上为居中布置,里面的所有元素都会横向(垂直于列,所以是横向)居中 */
align-items: center;
/* 定义里面的按钮button元素 */
button{
/* 宽度顶满 */
width:100%;
/* 上边距20rpx */
margin-bottom: 20rpx;
/* 上边距20rpx */
margin-top: 20rpx;
}
}
/* 上面的那个图片 */
.logo {
/* 宽高 200rpx */
height: 200rpx;
width: 200rpx;
/* 上外边距 100 */
margin-top: 100rpx;
}
/* 图片的动画 */
.shake {
/* 动画名称 shake,持续时间 200ms,动画循环无限次 */
animation: shake 200ms infinite;
}
/* 关键帧 shake 定义,即动画定义 */
@keyframes shake {
/* 10%和90%的时长时 变形往左 4rpx */
10%,
90% {
transform: translateX(-4rpx);
}
/* 20%和80%时长时 变形往右 4rpx */
20%,
80% {
transform: translateX(+4rpx);
}
/* 变形往左 4rpx */
30%,
70% {
transform: translateX(-4rpx);
}
/* 变形往右 4rpx */
40%,
60% {
transform: translateX(+4rpx);
}
/* 变形往左 4rpx */
50% {
transform: translateX(-4rpx);
}
}
调试
调试时可能会提示安装各种插件,顺序安装即可
- 运行 - 运行到内置浏览器,内置H5浏览器无法体验振动以及分享功能
- 运行 - 运行到手机或模拟器
- 运行 - 运行到小程序模拟器,看到振动及分享功能
即可体验本次编写的小功能
总结
使用到的技术,可以到对应的官方文档中去看看具体用法
uniapp:onShareAppMessage 分享事件监听、uni.vibrateShort() 短振动、uni.vibrateLong() 长振动
vue3 : setup 组合式API入口 <script setup> 是一个语法糖、reactive 返回对象的响应式副本、
css:flex布局、基本盒子模型、@keyframes关键帧定义,scss预编译器
如果在自己操作过程中有任何的疑问和问题,欢迎交流!
相关推荐
- Python+selenium自动化之selenium常用API
-
前面的几十篇文章介绍了selenium的常用的API的用法,但是这些仅仅是API的一小部分,大家可以去selenium官网获取查看https://python-selenium-zh.readthed...
- 如何用英文写电子邮件?英文的邮件格式怎么写?
-
电子邮件可以说是现代社会中人们交流沟通的重要工具之一,我们在社交、求学、工作中都需要用到邮件。如何写一封合适的英文电子邮件就是我们今天的主题。首先,请看下面这封邮件:这是不是就是很多小伙伴的邮件的样子...
- 如何删除Linux文件夹中除某些扩展名之外的所有文件?
-
假设你有一个名为data的文件夹,里面包含各种类型的文件,例如:...
- 手把手教你实现振动记录器
-
概述本文只涉及实现及代码讲解,不涉及具体技术的讲解,并尽量每一行代码都有详尽的注释,先实现,后积累。前端-入门级教程-简易振动记录器本文教大家实现一个简易的振动记录器。包括短振动、长振动、振...
- UG NX 出图技巧
-
UGNX出图技巧A、出工程图时,如何屏蔽掉多余的轮廓线?方法一:选中要修改的视图---按右键---选择“型式”--出现“查看形式”对话框---选择“光滑边”栏---把“光滑边”的...
- 利用forms表单组件进行表单校验
-
###利用forms表单组件进行表单校验,完成用户名,密码,确认密码,邮箱功能的校验该作业包含了下面的知识点:error_messages,label,required,invalid,局部钩子函数...
- 关于"must"的这些用法,你“必须”知道!
-
1mustbe\mustdo用于现在时Hekeepslookingatyou,hemustlikeyou.他一直在看你,他一定是喜欢你吧Shelookssobeautif...
- vue confirm弹窗提示确认,修改提示的字体颜色
-
1.日常写法this.$confirm(context,"提示",{confirmButtonText...
- 战旗TV悬赏令:守望先锋重金求天梯英雄
-
终于等到你!国服守望先锋持续一周的压力测试即将到来,蓄势待发的你是否已经热血沸腾?战旗TV发布天梯英雄悬赏令,直播冲击国服天梯段位就可获得大量奖励,赶快加入直播间的守望者行列!活动专区:http://...
- dart系列之:HTML的专属领域,除了javascript之外,dart也可以
-
简介虽然dart可以同时用作客户端和服务器端,但是基本上dart还是用做flutter开发的基本语言而使用的。除了andorid和ios之外,web就是最常见和通用的平台了,dart也提供了对HTML...
- 直播!去东新路寻找“夜杭州”的烟火气,人气餐厅美食福利放送中
-
APP中打开,直接点击图片进入直播;微信中打开稿件,保存直播海报,打开淘宝APP可以收看直播淘宝直播地址:h5.m.taobao.com/taolive/video.html?userId=41258...
- 深入浅出序列化(1)——JDK序列化和Hessian序列化
-
我之前在《聊一聊RPC》中曾提过什么是序列化和反序列化,当时有说过之后要单独抽出一期来详细聊聊序列化,没想到这一拖竟然拖了一年多,现在来把这个坑补上。由于篇幅较长,本文先主要介绍两种常见的序列化方式...
- Web前端开发,HTML超链接标签,不懂的可以学习一下
-
一、什么是HTML的超链接大家平时浏览的网页中都可以找到链接。点击链接就可以从一个页面跳转到另一个页面。HTML超链接可以是一个字,一个词,或者一组词,也可以是一幅图像。可以点击这些内容来跳转到新的文...
- TypeScript 终极初学者指南
-
在过去的几年里TypeScript变得越来越流行,现在许多工作都要求开发人员了解TypeScript...
- QStyle
-
一、描述QStyle类是一个抽象基类,它封装了GUI的外观。样式也可以作为插件使用。Qt的内置小部件使用QStyle来执行几乎所有的绘图,确保它们看起来与等效的原生小部件完全一样。下图显示...
你 发表评论:
欢迎- 一周热门
-
-
前端面试:iframe 的优缺点? iframe有那些缺点
-
带斜线的表头制作好了,如何填充内容?这几种方法你更喜欢哪个?
-
漫学笔记之PHP.ini常用的配置信息
-
推荐7个模板代码和其他游戏源码下载的网址
-
其实模版网站在开发工作中很重要,推荐几个参考站给大家
-
[干货] JAVA - JVM - 2 内存两分 [干货]+java+-+jvm+-+2+内存两分吗
-
正在学习使用python搭建自动化测试框架?这个系统包你可能会用到
-
织梦(Dedecms)建站教程 织梦建站详细步骤
-
【开源分享】2024PHP在线客服系统源码(搭建教程+终身使用)
-
2024PHP在线客服系统源码+完全开源 带详细搭建教程
-
- 最近发表
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)