小程序按住说话

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

使用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>
相关推荐
麻瓜老宋6 分钟前
AI开发C语言应用按步走,表达式计算器calc的第二十三步,多行输入、进制输出、错误恢复、常量折叠、配置加载等
c语言·开发语言·atomcode
用户9385156350724 分钟前
从零构建《天龙八部》知识库:EPUB 加载→文本分割→向量嵌入→Milvus 存储→RAG 问答,一条链路打通
javascript·人工智能·全栈
q5673152335 分钟前
企业级 HTTP 代理采购选型:技术评估清单 15 项
开发语言·网络·爬虫·网络协议·http·隧道ip·代理ip
天天进步20151 小时前
Python全栈项目--智能办公自动化系统
开发语言·python
cm04Z9c912 小时前
C#摸鱼实录——IoC与DI案例详解
开发语言·c#
柚yuzumi2 小时前
变量明明定义了,为什么访问不到?深入理解 JavaScript 作用域
javascript
long3162 小时前
Java 新手入门与实战开发指南
java·开发语言
何时梦醒2 小时前
React + TypeScript + Vite 实战:从零构建 Color Picker 应用
前端·javascript·架构
摩西蒙2 小时前
计算机网络
开发语言·计算机网络·php
Highcharts.js2 小时前
基于Highcharts开发的OHLC 股票K线图完全指南
javascript·信息可视化·echarts·数据可视化·highcharts·ohlc