|
@@ -1,72 +1,62 @@
|
|
|
<template>
|
|
<template>
|
|
|
- <view class="record-layer">
|
|
|
|
|
- <view class="record-box">
|
|
|
|
|
- <view class="record-btn-layer" v-if="tempFilePath == ''">
|
|
|
|
|
- <button class="record-btn" :class="longPress == '1' ? 'record-btn-1' : 'record-btn-2'" @longpress="longpressBtn()" @touchend="touchendBtn()">
|
|
|
|
|
- <image src="../../static/image/logo.png" />
|
|
|
|
|
- <text>{{ longPress == '1' ? '按住说话' : '说话中...' }}</text>
|
|
|
|
|
- </button>
|
|
|
|
|
- </view>
|
|
|
|
|
- <view class="record-btn-layer" v-else>
|
|
|
|
|
- <button class="record-btn" @longpress="delShow = true" @click="playBtn()" :class="playStatus == '1' ? 'record-btn-2' : 'record-btn-1'">
|
|
|
|
|
- <image src="../../static/image/logo.png" />
|
|
|
|
|
- <text>{{ playStatus == '1' ? count + 's' : '点击播放' }}</text>
|
|
|
|
|
- </button>
|
|
|
|
|
- </view>
|
|
|
|
|
- <!-- 语音音阶动画 -->
|
|
|
|
|
- <view class="prompt-layer prompt-layer-1" v-if="longPress == '2'">
|
|
|
|
|
- <view class="prompt-loader">
|
|
|
|
|
- <view class="em" v-for="(item, index) in 15" :key="index"></view>
|
|
|
|
|
- </view>
|
|
|
|
|
- <text class="p">{{ '剩余:' + count + 's' }}</text>
|
|
|
|
|
- <text class="span">松手结束录音</text>
|
|
|
|
|
- </view>
|
|
|
|
|
- <!-- 删除 -->
|
|
|
|
|
- <view class="prompt-layer prompt-layer-2" v-if="delShow" @click.stop="delBtn()">
|
|
|
|
|
- <text>删除</text>
|
|
|
|
|
|
|
+ <view class="container">
|
|
|
|
|
+ <view class="record-btn-layer">
|
|
|
|
|
+ <button
|
|
|
|
|
+ :class="[longPress === '1' ? 'record-btn-1' : 'record-btn-2', VoiceTitle === '松开手指,取消录音' ? 'record-btn-3' : '']"
|
|
|
|
|
+ @longpress="longpressBtn"
|
|
|
|
|
+ @touchend="touchendBtn"
|
|
|
|
|
+ @touchmove="handleTouchMove"
|
|
|
|
|
+ >
|
|
|
|
|
+ <text>{{ VoiceText }}</text>
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <!-- 语音音阶动画 -->
|
|
|
|
|
+ <view :class="VoiceTitle != '松开手指,取消录音' ? 'prompt-layer prompt-layer-1' : 'prompt-layer1 prompt-layer-1'" v-if="longPress == '2'">
|
|
|
|
|
+ <view class="prompt-loader">
|
|
|
|
|
+ <view class="em" v-for="(item, index) in 15" :key="index"></view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
+ <text class="span">{{ VoiceTitle }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
</template>
|
|
</template>
|
|
|
-
|
|
|
|
|
<script>
|
|
<script>
|
|
|
-const recorderManager = uni.getRecorderManager()
|
|
|
|
|
-const innerAudioContext = uni.createInnerAudioContext()
|
|
|
|
|
-var init // 录制时长计时器
|
|
|
|
|
-var timer // 播放 录制倒计时
|
|
|
|
|
export default {
|
|
export default {
|
|
|
data() {
|
|
data() {
|
|
|
return {
|
|
return {
|
|
|
- count: null, // 录制倒计时
|
|
|
|
|
- longPress: '1', // 1显示 按住说话 2显示 说话中
|
|
|
|
|
- delShow: false, // 删除提示框显示隐藏
|
|
|
|
|
- time: 0, //录音时长
|
|
|
|
|
- duration: 60000, //录音最大值ms 60000/1分钟
|
|
|
|
|
- tempFilePath: '', //音频路径
|
|
|
|
|
- playStatus: 0 //录音播放状态 0:未播放 1:正在播放
|
|
|
|
|
|
|
+ // 1显示 按住说话 2显示 说话中
|
|
|
|
|
+ longPress: '1',
|
|
|
|
|
+ //录音时长
|
|
|
|
|
+ recordingTime: 0,
|
|
|
|
|
+ // 定时器标识
|
|
|
|
|
+ recordingTimer: null,
|
|
|
|
|
+ //录音最大值ms 60000/1分钟
|
|
|
|
|
+ duration: 60000,
|
|
|
|
|
+ //音频路径
|
|
|
|
|
+ tempFilePath: '',
|
|
|
|
|
+ //记录长按录音开始点信息,用于后面计算滑动距离。
|
|
|
|
|
+ startPoint: {},
|
|
|
|
|
+ //发送锁,当为true时上锁,false时解锁发送
|
|
|
|
|
+ sendLock: true,
|
|
|
|
|
+ VoiceTitle: '松手结束录音',
|
|
|
|
|
+ VoiceText: '按住说话',
|
|
|
|
|
+ recorderManager: uni.getRecorderManager()
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
methods: {
|
|
methods: {
|
|
|
- // 倒计时
|
|
|
|
|
- countdown(val) {
|
|
|
|
|
- this.count = Number(val)
|
|
|
|
|
- timer = setInterval(() => {
|
|
|
|
|
- if (this.count > 0) {
|
|
|
|
|
- this.count--
|
|
|
|
|
- } else {
|
|
|
|
|
- this.longPress = '1'
|
|
|
|
|
- clearInterval(timer)
|
|
|
|
|
- }
|
|
|
|
|
- }, 1000)
|
|
|
|
|
- },
|
|
|
|
|
// 长按录音事件
|
|
// 长按录音事件
|
|
|
- longpressBtn() {
|
|
|
|
|
|
|
+ longpressBtn(e) {
|
|
|
|
|
+ //记录长按时开始点信息,后面用于计算上划取消时手指滑动的距离
|
|
|
|
|
+ this.startPoint = e.touches[0]
|
|
|
this.longPress = '2'
|
|
this.longPress = '2'
|
|
|
- this.countdown(60) // 倒计时
|
|
|
|
|
- clearInterval(init) // 清除定时器
|
|
|
|
|
- recorderManager.onStop((res) => {
|
|
|
|
|
|
|
+ this.VoiceText = '说话中...'
|
|
|
|
|
+
|
|
|
|
|
+ this.recordingTime = 0
|
|
|
|
|
+ this.recordingTimer = setInterval(() => {
|
|
|
|
|
+ this.recordingTime++
|
|
|
|
|
+ }, 1000)
|
|
|
|
|
+ this.recorderManager.onStop((res) => {
|
|
|
|
|
+ // console.log(res);
|
|
|
this.tempFilePath = res.tempFilePath
|
|
this.tempFilePath = res.tempFilePath
|
|
|
- this.recordingTimer(this.time)
|
|
|
|
|
})
|
|
})
|
|
|
const options = {
|
|
const options = {
|
|
|
duration: this.duration, // 指定录音的时长,单位 ms
|
|
duration: this.duration, // 指定录音的时长,单位 ms
|
|
@@ -76,138 +66,175 @@ export default {
|
|
|
format: 'mp3', // 音频格式,有效值 aac/mp3
|
|
format: 'mp3', // 音频格式,有效值 aac/mp3
|
|
|
frameSize: 10 // 指定帧大小,单位 KB
|
|
frameSize: 10 // 指定帧大小,单位 KB
|
|
|
}
|
|
}
|
|
|
- this.recordingTimer()
|
|
|
|
|
- recorderManager.start(options)
|
|
|
|
|
|
|
+ this.recorderManager.start(options)
|
|
|
// 监听音频开始事件
|
|
// 监听音频开始事件
|
|
|
- recorderManager.onStart((res) => {
|
|
|
|
|
- console.log(res)
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ this.sendLock = false //长按时是不上锁的。
|
|
|
|
|
+ this.recorderManager.onStart((res) => {})
|
|
|
},
|
|
},
|
|
|
// 长按松开录音事件
|
|
// 长按松开录音事件
|
|
|
touchendBtn() {
|
|
touchendBtn() {
|
|
|
this.longPress = '1'
|
|
this.longPress = '1'
|
|
|
- recorderManager.onStop((res) => {
|
|
|
|
|
- this.tempFilePath = res.tempFilePath
|
|
|
|
|
|
|
+ this.VoiceText = '按住说话'
|
|
|
|
|
+ this.VoiceTitle = '松手结束录音'
|
|
|
|
|
+ this.recorderManager.onStop((res) => {
|
|
|
|
|
+ // console.log(this.sendLock)
|
|
|
|
|
+ clearInterval(this.recordingTimer)
|
|
|
|
|
+ if (this.sendLock) {
|
|
|
|
|
+ //上锁不发送
|
|
|
|
|
+ } else {
|
|
|
|
|
+ //解锁发送,发送网络请求
|
|
|
|
|
+ if (res.duration < 1000)
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '录音时间太短',
|
|
|
|
|
+ icon: 'none',
|
|
|
|
|
+ duration: 1000
|
|
|
|
|
+ })
|
|
|
|
|
+ else {
|
|
|
|
|
+ this.tempFilePath = res.tempFilePath
|
|
|
|
|
+ this.$emit('getTempFilePath', this.tempFilePath, this.recordingTime)
|
|
|
|
|
+ // uploadFile({
|
|
|
|
|
+ // url: '/voice/VoiceControl',
|
|
|
|
|
+ // src: res.tempFilePath,
|
|
|
|
|
+ // }).then(res => {
|
|
|
|
|
+ // console.log(JSON.parse(res.data));
|
|
|
|
|
+ // })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
})
|
|
})
|
|
|
- this.recordingTimer(this.time)
|
|
|
|
|
- recorderManager.stop()
|
|
|
|
|
- },
|
|
|
|
|
- recordingTimer(time) {
|
|
|
|
|
- if (time == undefined) {
|
|
|
|
|
- // 将计时器赋值给init
|
|
|
|
|
- init = setInterval(() => {
|
|
|
|
|
- this.time++
|
|
|
|
|
- }, 1000)
|
|
|
|
|
- } else {
|
|
|
|
|
- clearInterval(init)
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ this.recorderManager.stop() //结束录音
|
|
|
},
|
|
},
|
|
|
- // 删除录音
|
|
|
|
|
- delBtn() {
|
|
|
|
|
- this.delShow = false
|
|
|
|
|
- this.time = 0
|
|
|
|
|
- this.tempFilePath = ''
|
|
|
|
|
- this.playStatus = 0
|
|
|
|
|
- innerAudioContext.stop()
|
|
|
|
|
- },
|
|
|
|
|
- // 播放
|
|
|
|
|
- playBtn() {
|
|
|
|
|
- innerAudioContext.src = this.tempFilePath
|
|
|
|
|
- //在ios下静音时播放没有声音,默认为true,改为false就好了。
|
|
|
|
|
- // innerAudioContext.obeyMuteSwitch = false
|
|
|
|
|
- //点击播放
|
|
|
|
|
- if (this.playStatus == 0) {
|
|
|
|
|
- this.playStatus = 1
|
|
|
|
|
- innerAudioContext.play()
|
|
|
|
|
- this.countdown(this.time) // 倒计时
|
|
|
|
|
|
|
+ // 取消录音
|
|
|
|
|
+ handleTouchMove(e) {
|
|
|
|
|
+ //touchmove时触发
|
|
|
|
|
+ var moveLenght = e.touches[e.touches.length - 1].clientY - this.startPoint.clientY //移动距离
|
|
|
|
|
+ if (Math.abs(moveLenght) > 70) {
|
|
|
|
|
+ this.VoiceTitle = '松开手指,取消录音'
|
|
|
|
|
+ this.VoiceText = '松开手指,取消录音'
|
|
|
|
|
+ //触发了上滑取消录音,上锁
|
|
|
|
|
+ this.sendLock = true
|
|
|
} else {
|
|
} else {
|
|
|
- this.playStatus = 0
|
|
|
|
|
- innerAudioContext.pause()
|
|
|
|
|
|
|
+ this.VoiceTitle = '松手结束录音'
|
|
|
|
|
+ this.VoiceText = '松手结束录音'
|
|
|
|
|
+ //上划距离不足,依然可以发送,不上锁
|
|
|
|
|
+ this.sendLock = false
|
|
|
}
|
|
}
|
|
|
- // //播放结束
|
|
|
|
|
- innerAudioContext.onEnded(() => {
|
|
|
|
|
- this.playStatus = 0
|
|
|
|
|
- innerAudioContext.stop()
|
|
|
|
|
- })
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
</script>
|
|
</script>
|
|
|
-
|
|
|
|
|
-<style scoped>
|
|
|
|
|
-/* 语音录制开始--------------------------------------------------------------------- */
|
|
|
|
|
-.record-layer {
|
|
|
|
|
- margin: auto;
|
|
|
|
|
- width: 50%;
|
|
|
|
|
- padding: 300px 0;
|
|
|
|
|
- box-sizing: border-box;
|
|
|
|
|
-}
|
|
|
|
|
-.record-box {
|
|
|
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
|
+.container {
|
|
|
width: 100%;
|
|
width: 100%;
|
|
|
- position: relative;
|
|
|
|
|
-}
|
|
|
|
|
-.record-btn-layer {
|
|
|
|
|
- width: 100%;
|
|
|
|
|
-}
|
|
|
|
|
-.record-btn-layer button::after {
|
|
|
|
|
- border: none;
|
|
|
|
|
-}
|
|
|
|
|
-.record-btn-layer button {
|
|
|
|
|
- font-size: 14px;
|
|
|
|
|
- line-height: 38px;
|
|
|
|
|
- width: 100%;
|
|
|
|
|
- height: 38px;
|
|
|
|
|
- border-radius: 8px;
|
|
|
|
|
- text-align: center;
|
|
|
|
|
- background: #ffd300;
|
|
|
|
|
-}
|
|
|
|
|
-.record-btn-layer button image {
|
|
|
|
|
- width: 16px;
|
|
|
|
|
- height: 16px;
|
|
|
|
|
- margin-right: 4px;
|
|
|
|
|
- vertical-align: middle;
|
|
|
|
|
-}
|
|
|
|
|
-.record-btn-layer .record-btn-2 {
|
|
|
|
|
- background: rgba(255, 211, 0, 0.2);
|
|
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+
|
|
|
|
|
+ .record-btn-layer {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+
|
|
|
|
|
+ button {
|
|
|
|
|
+ width: 50%;
|
|
|
|
|
+ height: 50px;
|
|
|
|
|
+ line-height: 50px;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ transition: all 0.1s;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ button::after {
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ transition: all 0.1s;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .record-btn-1 {
|
|
|
|
|
+ background-color: #6fb6b8;
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .record-btn-2 {
|
|
|
|
|
+ color: #0061ff;
|
|
|
|
|
+ transition: all 0.3s;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .record-btn-3 {
|
|
|
|
|
+ background-color: #fb5353;
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
/* 提示小弹窗 */
|
|
/* 提示小弹窗 */
|
|
|
.prompt-layer {
|
|
.prompt-layer {
|
|
|
- border-radius: 8px;
|
|
|
|
|
- background: #ffd300;
|
|
|
|
|
|
|
+ border-radius: 15px;
|
|
|
|
|
+ background: #95eb6c;
|
|
|
padding: 8px 16px;
|
|
padding: 8px 16px;
|
|
|
box-sizing: border-box;
|
|
box-sizing: border-box;
|
|
|
position: absolute;
|
|
position: absolute;
|
|
|
left: 50%;
|
|
left: 50%;
|
|
|
|
|
+ height: 11vh;
|
|
|
transform: translateX(-50%);
|
|
transform: translateX(-50%);
|
|
|
|
|
+ transition: all 0.3s;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.prompt-layer::after {
|
|
.prompt-layer::after {
|
|
|
content: '';
|
|
content: '';
|
|
|
display: block;
|
|
display: block;
|
|
|
- border: 6px solid rgba(0, 0, 0, 0);
|
|
|
|
|
- border-top-color: rgba(255, 211, 0, 1);
|
|
|
|
|
|
|
+ border: 12px solid rgba(0, 0, 0, 0);
|
|
|
|
|
+ border-radius: 10rpx;
|
|
|
|
|
+ border-top-color: #95eb6c;
|
|
|
position: absolute;
|
|
position: absolute;
|
|
|
- bottom: -10px;
|
|
|
|
|
|
|
+ bottom: -46rpx;
|
|
|
left: 50%;
|
|
left: 50%;
|
|
|
transform: translateX(-50%);
|
|
transform: translateX(-50%);
|
|
|
|
|
+ transition: all 0.3s;
|
|
|
|
|
+}
|
|
|
|
|
+//取消动画
|
|
|
|
|
+.prompt-layer1 {
|
|
|
|
|
+ border-radius: 15px;
|
|
|
|
|
+ background: #fb5353;
|
|
|
|
|
+ padding: 8px 16px;
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ left: 50%;
|
|
|
|
|
+ height: 11vh;
|
|
|
|
|
+ transform: translateX(-50%);
|
|
|
|
|
+ transition: all 0.3s;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.prompt-layer1::after {
|
|
|
|
|
+ content: '';
|
|
|
|
|
+ display: block;
|
|
|
|
|
+ border: 12px solid rgba(0, 0, 0, 0);
|
|
|
|
|
+ border-radius: 10rpx;
|
|
|
|
|
+ border-top-color: #fb5353;
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ bottom: -46rpx;
|
|
|
|
|
+ left: 50%;
|
|
|
|
|
+ transform: translateX(-50%);
|
|
|
|
|
+ transition: all 0.3s;
|
|
|
}
|
|
}
|
|
|
.prompt-layer-1 {
|
|
.prompt-layer-1 {
|
|
|
font-size: 12px;
|
|
font-size: 12px;
|
|
|
- width: 128px;
|
|
|
|
|
|
|
+ width: 150px;
|
|
|
text-align: center;
|
|
text-align: center;
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
justify-content: center;
|
|
|
- top: -80px;
|
|
|
|
|
-}
|
|
|
|
|
-.prompt-layer-1 .p {
|
|
|
|
|
- color: #000000;
|
|
|
|
|
-}
|
|
|
|
|
-.prompt-layer-1 .span {
|
|
|
|
|
- color: rgba(0, 0, 0, 0.6);
|
|
|
|
|
-}
|
|
|
|
|
-.prompt-loader .em {
|
|
|
|
|
|
|
+ top: -400rpx;
|
|
|
|
|
+
|
|
|
|
|
+ .p {
|
|
|
|
|
+ color: #000000;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .span {
|
|
|
|
|
+ color: rgba(0, 0, 0, 0.6);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
/* 语音音阶------------- */
|
|
/* 语音音阶------------- */
|
|
|
.prompt-loader {
|
|
.prompt-loader {
|
|
|
width: 96px;
|
|
width: 96px;
|
|
@@ -217,6 +244,7 @@ export default {
|
|
|
justify-content: space-between;
|
|
justify-content: space-between;
|
|
|
margin-bottom: 6px;
|
|
margin-bottom: 6px;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.prompt-loader .em {
|
|
.prompt-loader .em {
|
|
|
display: block;
|
|
display: block;
|
|
|
background: #333333;
|
|
background: #333333;
|
|
@@ -225,72 +253,92 @@ export default {
|
|
|
margin-right: 2.5px;
|
|
margin-right: 2.5px;
|
|
|
float: left;
|
|
float: left;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.prompt-loader .em:last-child {
|
|
.prompt-loader .em:last-child {
|
|
|
margin-right: 0px;
|
|
margin-right: 0px;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.prompt-loader .em:nth-child(1) {
|
|
.prompt-loader .em:nth-child(1) {
|
|
|
animation: load 2.5s 1.4s infinite linear;
|
|
animation: load 2.5s 1.4s infinite linear;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.prompt-loader .em:nth-child(2) {
|
|
.prompt-loader .em:nth-child(2) {
|
|
|
animation: load 2.5s 1.2s infinite linear;
|
|
animation: load 2.5s 1.2s infinite linear;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.prompt-loader .em:nth-child(3) {
|
|
.prompt-loader .em:nth-child(3) {
|
|
|
animation: load 2.5s 1s infinite linear;
|
|
animation: load 2.5s 1s infinite linear;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.prompt-loader .em:nth-child(4) {
|
|
.prompt-loader .em:nth-child(4) {
|
|
|
animation: load 2.5s 0.8s infinite linear;
|
|
animation: load 2.5s 0.8s infinite linear;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.prompt-loader .em:nth-child(5) {
|
|
.prompt-loader .em:nth-child(5) {
|
|
|
animation: load 2.5s 0.6s infinite linear;
|
|
animation: load 2.5s 0.6s infinite linear;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.prompt-loader .em:nth-child(6) {
|
|
.prompt-loader .em:nth-child(6) {
|
|
|
animation: load 2.5s 0.4s infinite linear;
|
|
animation: load 2.5s 0.4s infinite linear;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.prompt-loader .em:nth-child(7) {
|
|
.prompt-loader .em:nth-child(7) {
|
|
|
animation: load 2.5s 0.2s infinite linear;
|
|
animation: load 2.5s 0.2s infinite linear;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.prompt-loader .em:nth-child(8) {
|
|
.prompt-loader .em:nth-child(8) {
|
|
|
animation: load 2.5s 0s infinite linear;
|
|
animation: load 2.5s 0s infinite linear;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.prompt-loader .em:nth-child(9) {
|
|
.prompt-loader .em:nth-child(9) {
|
|
|
animation: load 2.5s 0.2s infinite linear;
|
|
animation: load 2.5s 0.2s infinite linear;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.prompt-loader .em:nth-child(10) {
|
|
.prompt-loader .em:nth-child(10) {
|
|
|
animation: load 2.5s 0.4s infinite linear;
|
|
animation: load 2.5s 0.4s infinite linear;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.prompt-loader .em:nth-child(11) {
|
|
.prompt-loader .em:nth-child(11) {
|
|
|
animation: load 2.5s 0.6s infinite linear;
|
|
animation: load 2.5s 0.6s infinite linear;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.prompt-loader .em:nth-child(12) {
|
|
.prompt-loader .em:nth-child(12) {
|
|
|
animation: load 2.5s 0.8s infinite linear;
|
|
animation: load 2.5s 0.8s infinite linear;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.prompt-loader .em:nth-child(13) {
|
|
.prompt-loader .em:nth-child(13) {
|
|
|
animation: load 2.5s 1s infinite linear;
|
|
animation: load 2.5s 1s infinite linear;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.prompt-loader .em:nth-child(14) {
|
|
.prompt-loader .em:nth-child(14) {
|
|
|
animation: load 2.5s 1.2s infinite linear;
|
|
animation: load 2.5s 1.2s infinite linear;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.prompt-loader .em:nth-child(15) {
|
|
.prompt-loader .em:nth-child(15) {
|
|
|
animation: load 2.5s 1.4s infinite linear;
|
|
animation: load 2.5s 1.4s infinite linear;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
@keyframes load {
|
|
@keyframes load {
|
|
|
0% {
|
|
0% {
|
|
|
height: 10%;
|
|
height: 10%;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
50% {
|
|
50% {
|
|
|
height: 100%;
|
|
height: 100%;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
100% {
|
|
100% {
|
|
|
height: 10%;
|
|
height: 10%;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
/* 语音音阶-------------------- */
|
|
/* 语音音阶-------------------- */
|
|
|
.prompt-layer-2 {
|
|
.prompt-layer-2 {
|
|
|
top: -40px;
|
|
top: -40px;
|
|
|
|
|
+
|
|
|
|
|
+ .text {
|
|
|
|
|
+ color: rgba(0, 0, 0, 1);
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
-.prompt-layer-2 .text {
|
|
|
|
|
- color: rgba(0, 0, 0, 1);
|
|
|
|
|
- font-size: 12px;
|
|
|
|
|
-}
|
|
|
|
|
-/* 语音录制结束---------------------------------------------------------------- */
|
|
|
|
|
</style>
|
|
</style>
|