小程序按住说话

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

使用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>
相关推荐
A5rZ1 小时前
缓存投毒进阶 -- justctf 2025 Busy Traffic
前端·javascript·缓存
WSSWWWSSW1 小时前
Numpy科学计算与数据分析:Numpy文件操作入门之数组数据的读取和保存
开发语言·python·数据挖掘·数据分析·numpy
芥子须弥Office2 小时前
从C++0基础到C++入门 (第二十五节:指针【所占内存空间】)
c语言·开发语言·c++·笔记
未来之窗软件服务2 小时前
浏览器CEFSharp133+X86+win7 之多页面展示(三)
前端·javascript·浏览器开发·东方仙盟
胡斌附体2 小时前
elementui cascader 远程加载请求使用 选择单项等
前端·javascript·elementui·cascader·可独立选中单节点
Q741_1473 小时前
如何判断一个数是 2 的幂 / 3 的幂 / 4 的幂 / n 的幂 位运算 总结和思考 每日一题 C++的题解与思路
开发语言·c++·算法·leetcode·位运算·总结思考
半瓶啤酒一醉方休3 小时前
C# 查询电脑已安装所有软件并打印txt保存到桌面
开发语言·c#
甘露寺3 小时前
深入理解 Axios 请求与响应对象结构:从配置到数据处理的全面指南
javascript·ajax
钢铁男儿3 小时前
深入解析C#并行编程:从并行循环到异步编程模式
开发语言·c#
招风的黑耳4 小时前
Axure 高阶设计:打造“以假乱真”的多图片上传组件
javascript·图片上传·axure