小程序按住说话

小程序按住说话、上滑取消的实现。

使用view作为容器总有奇怪的问题,比如touchend事件有时候不触发。

需要使用事件修饰符来阻止冒泡,不如有时候touchend、touchmove也不会触发。

下面是效果及源码。


html 复制代码
<template>
  <view class="w-full bg-white">
    <button
      class="record-btn w-full"
      style="padding: 0; line-height: 22px; background-color: transparent"
      @touchend.stop="handleTouchEnd"
      @touchmove.stop="handleTouchmove"
      @longpress.stop="handleLongPress"
    >
      <view v-if="isRecording">
        <view class="text-center text-secondary text-xs py-3">
          <text v-if="isUp">松开取消</text>
          <text v-else>松手发送,上滑取消</text>
        </view>
        <Wave :bgColor="`var(--wot-color-${isUp ? 'danger' : 'theme'})`" />
      </view>

      <view v-else class="leading-22px py-3">
        <view>
          <text class="font-bold">按住说话</text>
        </view>
      </view>
    </button>
  </view>
</template>

<script lang="ts" setup>
import Wave from './Wave.vue'

const isRecording = ref(false) // 状态,当前是否在录音
const isUp = ref(false) // 是否上滑
const startY = ref(0)
const handleLongPress = (event) => {
  startY.value = event.touches[0].clientY
  isRecording.value = true
  console.log(`output->按压的坐标`, startY.value)
}
const handleTouchEnd = () => {
  isRecording.value = false
  startY.value = 0
  isUp.value = false
  console.log(`output->离开后的坐标`, startY.value)
}
const handleTouchmove = (event) => {
  if (!isRecording.value) return

  const currentY = event.touches[0].clientY
  const diffY = startY.value - currentY

  // 设定阈值,防止误判
  isUp.value = diffY > 10
}
</script>

wave.vue

html 复制代码
<template>
  <view
    class="wave-container"
    :style="{
      'background-color': bgColor,
    }"
  >
    <view :class="`wave-bar wave-bar-delay-${n}`" v-for="n in generateSequence(20)" :key="n"></view>
  </view>
</template>
<script lang="ts" setup>
type PropsType = { bgColor: string }

const props = defineProps<PropsType>()

function generateSequence(n) {
  const result = []

  // 递增部分:1 到 n
  for (let i = 1; i <= n; i++) {
    result.push(i)
  }

  // 递减部分:n-1 到 1
  for (let i = n - 1; i >= 1; i--) {
    result.push(i)
  }

  return result
}
</script>

<style lang="scss" scoped>
$number: 20;

.wave-container {
  display: flex;
  gap: 5px;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 22px;
  padding: 12px 0;
  border-radius: 10px;
}
.wave-bar {
  width: 3px;
  height: 10px;
  background-color: #fff;
  border-radius: 2px;
  animation: wave 1s infinite ease-in-out;
}

@for $i from 1 through $number {
  .wave-bar-delay-#{$i} {
    animation-delay: $i * -0.8 + s;
  }
}

@keyframes wave {
  0%,
  100% {
    transform: scaleY(0.8);
  }
  50% {
    transform: scaleY(1);
  }
}
</style>
相关推荐
Tairitsu_H2 分钟前
[C++] C++11 Lambda与包装器深度解析
开发语言·c++·c++11·lambda·包装器
傲世仙尊10 分钟前
从磁盘硬件到Ext文件系统-Linux磁盘级文件系统学习笔记
linux·运维·服务器·开发语言·c++
小羊没烦恼!28 分钟前
Memory 记忆设计讨论:为什么 Agent Memory 不能只靠向量数据库?
java·开发语言·windows·算法·c#
黑马程序员毕设44 分钟前
基于微信小程序的节目活动报名与管理系统设计与实现
java·开发语言·spring boot·后端·电脑
天若有情6731 小时前
开源轻量双语工具|一键批量查询 NPM 包历史下载量,支持按作者批量统计
javascript·npm·github pages·开源工具·netlify·前端开源·npm克隆量
sunshine22 girl1 小时前
Java学习 java原理
java·开发语言·学习
troy1282 小时前
Python 基础语法(六):函数与模块、文件操作、异常处理
开发语言·python
lv__pf2 小时前
09-深入理解AQS之独占锁ReentrantLock源码分析【TL 并发 09】
java·开发语言
福兮说2 小时前
纯前端把图片压缩到指定体积:canvas.toBlob 配合二分查找
前端·javascript·canvas·图片处理
志尊宝3 小时前
Vue3 零基础每日笔记(018):按键与鼠标修饰符——回车搜索、Ctrl+S 保存这样写
javascript·vue.js·笔记