微信小程序 模拟打电话 实践
2019-05-27 本文已影响0人
夏海峰
模拟电话
模拟打电话功能,拨下指定的号码如10086,等待1.5秒后开始播放本地音频文件并计时。使用小程序官方API createInnerAudioContext()创建 InnerAudioContext对象。
小程序官方推荐使用更为强大的音频上下文对象InnerAudioContext,官方已经停止了对<audio>组件的维护。上述这个demo效果的具体实现,如下代码:
<template>
<view class="task">
<view class="call">
<!-- 顶部区域 -->
<view class="top" wx:if="{{phone.length > 0}}">
<view class="phone">{{phone}}</view>
<view class="tip" wx:if="{{calling}}">
<view wx:if="{{tipShow}}">正在呼叫...</view>
<view wx:else>{{formatMmSs}}</view>
</view>
</view>
<!-- 中间区域 -->
<view class="middle">
<view class="nums" wx:if="{{showNums}}" @tap="numClick">
<view class="row">
<view class="num" data-num='1'>1</view>
<view class="num" data-num='2'>2</view>
<view class="num" data-num='3'>3</view>
</view>
<view class="row">
<view class="num" data-num='4'>4</view>
<view class="num" data-num='5'>5</view>
<view class="num" data-num='6'>6</view>
</view>
<view class="row">
<view class="num" data-num='7'>7</view>
<view class="num" data-num='8'>8</view>
<view class="num" data-num='9'>9</view>
</view>
<view class="row">
<view class="num" data-num='*'>*</view>
<view class="num" data-num='0'>0</view>
<view class="num" data-num='#'>#</view>
</view>
</view>
<view class="icons" wx:else>
<view class="icon">
<image src="{{img.ringIcon1}}"></image>
<view>静音</view>
</view>
<view class="icon">
<image src="{{img.ringIcon2}}" @tap="handle('back')"></image>
<view>拔号</view>
</view>
<view class="icon">
<image src="{{img.ringIcon3}}"></image>
<view>免提</view>
</view>
</view>
</view>
<!-- 底部区域 -->
<view class="bottom">
<image wx:if="{{!calling}}" class="btn" src="{{img.call}}" @tap="handle('call')"></image>
<image wx:else class="btn" src="{{img.cancel}}" @tap="handle('cancel')"></image>
<image wx:if="{{!calling && phone.length>0}}" class="del" src="{{img.delete}}" @tap="handle('delete')"></image>
</view>
</view>
</view>
</template>
<script>
import wepy from 'wepy'
import img from '@/assets'
export default class Test extends wepy.page {
config = {
navigationBarTitleText: '模拟电话'
}
data = {
img: img,
phone: '', // 10086
tipShow: false, // 显示呼叫中
calling: false, // 是否拔通电话
showNums: true, // 显示数字面板
seconds: 0 // 计时
}
computed = {
// 通话计时 格式化
formatMmSs() {
return this.mmss(this.seconds)
}
}
// 格式化时间
mmss(count) {
count = count % 3600 // 不考虑 HH
let mm = Math.floor(count / 60)
let ss = count % 60
if (mm < 10) mm = '0' + mm
if (ss < 10) ss = '0' + ss
return mm + ':' + ss
}
onLoad() {
// 音频上下文
wepy.setInnerAudioOption({
mixWithOther: false, // 终止其他应用或微信内的音乐
obeyMuteSwitch: false // 在静音模式下,也能播放声音
})
let ctx = wepy.createInnerAudioContext()
ctx.src = '/assets/media/10086.mp3'
ctx.loop = true
ctx.onPlay(() => {
console.log('开始播放')
})
ctx.onError((res) => {
console.log(res.errMsg)
})
this.ctx = ctx
}
methods = {
// 点击数字
numClick(e) {
console.log(e)
console.log(e.target.dataset.num)
const num = e.target.dataset.num
this.phone = this.phone + num
},
handle(type) {
switch (type) {
case 'call':
// 拔打电话
if (this.phone !== '10086') {
wepy.showToast({ title: '请拔打10086', icon: 'none' })
} else {
this.calling = true
this.tipShow = true
// 延迟1.5秒后开始计时,并播放音频文件
setTimeout(() => {
this.ctx.play()
this.showNums = false
this.timer = setInterval(() => {
this.tipShow = false
this.seconds = this.seconds + 1
this.$apply()
}, 1000)
}, 1500)
}
break
case 'cancel':
// 挂掉电话
clearInterval(this.timer)
this.ctx.seek(0)
this.ctx.stop()
this.phone = ''
this.calling = false
this.showNums = true
this.seconds = 0
break
case 'delete':
// 删除电话号码的最后一位
let phone = this.phone
let arr = phone.split('')
arr.pop()
this.phone = arr.join('')
break
case 'back':
// 返回至数字键盘
this.showNums = true
break
default:
break
}
}
}
}
</script>
<style lang='less'>
.task {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
overflow: hidden;
background: rgba(0, 0, 0, 1);
// 打电话区域
.call {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 2;
.top {
position: absolute;
top: 48rpx;
left: 0;
right: 0;
color: #FDFDFD;
text-align: center;
.phone {
font-size: 72rpx;
line-height: 100rpx;
}
.tip {
font-size: 36rpx;
line-height: 54rpx;
}
}
.middle {
position: absolute;
top: 232rpx;
left: 0;
right: 0;
// 数字面板
.nums {
.row {
width: 540rpx;
margin: 0 auto;
height: 158rpx;
overflow: hidden;
.num {
float: left;
margin: 0 30rpx;
width: 120rpx;
height: 120rpx;
border-radius: 50%;
background:rgba(229,229,229,1);
text-align: center;
line-height: 120rpx;
font-size: 60rpx;
color: black;
}
.num:active {
background:rgba(229,229,229,0.5);
}
}
}
// 免提等
.icons {
margin: 0 auto;
width: 540rpx;
height: 250rpx;
overflow: hidden;
padding-top: 196rpx;
.icon {
float: left;
width: 120rpx;
margin: 0 30rpx;
&>image {
display: block;
width: 120rpx;
height: 120rpx;
border-radius: 50%;
}
&>image:active {
opacity: 0.7;
}
&>view {
font-size: 32rpx;
color: #FDFDFD;
text-align: center;
line-height: 68rpx;
}
}
}
}
.bottom {
position: absolute;
top: 940rpx;
left: 0;
right: 0;
text-align: center;
.btn {
display: inline-block;
width: 120rpx;
height: 120rpx;
border-radius: 50%;
}
.del {
display: inline-block;
width: 75rpx;
height: 56rpx;
position: absolute;
top: 46rpx;
right: 138rpx;
}
.btn:active {
opacity: 0.7;
}
.del:active {
opacity: 0.7;
}
}
}
}
</style>
END 2019-05-27