123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- <template>
- <view class="speak-container">
- <view
- ref="talkRef"
- class="talk"
- :class="{
- normal: normalModel,
- start: startModel,
- startMouseover: startOverModel,
- }"
- @touchstart="handleTouchStart"
- @touchend="handleTouchEnd"
- >{{ talkText }}
- <LottieRecording class="lottie" v-if="isShowLottieR" />
- <text class="lottie-text" v-if="isShowLottieR">{{ lottieText }}</text>
- <yimo-AudioTrans
- ref="yimoAudioTransRef"
- :options="options"
- @countDown="countDown"
- @result="resultMsg"
- @onStop="onStop"
- @onOpen="onOpen"
- @change="change"
- ></yimo-AudioTrans>
- </view>
- </view>
- </template>
- <script setup>
- import { onMounted, ref } from "vue";
- import LottieRecording from "../../components/lottie/lottie-recording.vue";
- import noticeBar from "../../uni_modules/uview-plus/components/u-notice-bar/noticeBar";
- const emits = defineEmits(["recordResult"]);
- // 动画相关
- const isShowLottieR = ref(false);
- const showLottieR = () => {
- isShowLottieR.value = true;
- };
- // 按住说话===================
- const talkRef = ref(null);
- //文字
- const normalText = "按住 说话";
- const startText = "松手 发送";
- const mouseOverText = "松手 取消";
- const talkText = ref("");
- let lottieTextNormal = "松手发送,上移取消";
- let lottieTextCancel = "滑动到按钮区域回复录音";
- const lottieText = ref("");
- // 样式控制
- const normalModel = ref(false);
- const startModel = ref(false);
- const startOverModel = ref(false);
- // 相关方法
- const handleTouchStart = () => {
- normalModel.value = false;
- startModel.value = true;
- talkText.value = startText;
- // 开始录音
- yimoAudioTransRef.value && yimoAudioTransRef.value.start();
- };
- const handleTouchEnd = () => {
- // 结束录音
- yimoAudioTransRef.value && yimoAudioTransRef.value.end();
- initTalkModel();
- };
- const handleTouchMove = (event) => {
- if (!startModel.value) return;
- const touch = event.touches[0];
- const currentX = touch.clientX;
- const currentY = touch.clientY;
- console.log("handleTouchMove", talkRef.value);
- const rect = talkRef.value.getBoundingClientRect();
- const isInsideX = currentX >= rect.left && currentX <= rect.right;
- const isInsideY = currentY >= rect.top && currentY <= rect.bottom;
- if (!isInsideX || !isInsideY) {
- // 超出范围
- startModel.value = false;
- startOverModel.value = true;
- talkText.value = mouseOverText;
- } else {
- // 移动中
- startModel.value = true;
- startOverModel.value = false;
- talkText.value = startText;
- }
- };
- const mouseOver = () => {
- startModel.value = false;
- startOverModel.value = true;
- talkText.value = mouseOverText;
- };
- const mouseIn = () => {
- startModel.value = true;
- startOverModel.value = false;
- talkText.value = startText;
- };
- const initTalkModel = () => {
- normalModel.value = true;
- startModel.value = false;
- startOverModel.value = false;
- talkText.value = normalText;
- isShowLottieR.value = false;
- lottieText.value = lottieTextNormal;
- };
- // ==================== 语音相关 =
- const yimoAudioTransRef = ref(null);
- const options = ref({
- receordingDuration: 20,
- APPID: "d6d15e17",
- API_SECRET: "NmIyZWFjYzMxNTEwMmRjZTE0YjcxNzIw",
- API_KEY: "172b9f1528efa9442956f2f26f34ead0",
- });
- const countDown = (duration) => {
- console.log("countDown", duration);
- };
- const resultMsg = (msg) => {
- console.log("resultMsg", msg);
- emits("recordResult", msg);
- };
- const onStop = () => {
- console.log("onStop");
- };
- const onOpen = () => {
- console.log("onOpen");
- showLottieR();
- };
- const change = (msg) => {
- console.log("change", msg);
- };
- onMounted(() => {
- initTalkModel();
- });
- </script>
- <style lang="scss" scoped>
- .speak-container {
- width: 100%;
- height: 30rpx;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- min-height: 300px;
- background-color: lightgrey;
- .talk {
- margin-top: 100px;
- width: 80%;
- height: 40px;
- line-height: 40px;
- border-radius: 20px;
- font-size: 20px;
- text-align: center;
- font-weight: bold;
- position: relative;
- .lottie {
- position: absolute;
- top: -85px;
- left: 0;
- }
- .lottie-text {
- width: 100%;
- font-size: 14px;
- color: #1f1f1f;
- text-align: center;
- position: absolute;
- top: -35px;
- left: 0;
- }
- }
- .normal {
- color: black;
- background-color: white;
- }
- .start {
- color: white;
- background-color: blue;
- }
- .startMouseover {
- color: black;
- background-color: red;
- }
- }
- </style>
|