還在為實(shí)現(xiàn)類似于QQ視頻通話
那樣的視頻窗口隨意拖動(dòng)而苦惱嗎?福音來了,今天就為大家解決這樣的煩惱。
前提:
使用 anyrtc 基本實(shí)現(xiàn)音視頻(nvue頁(yè)面)
需求:
兩人通話時(shí)可隨意拖動(dòng)小視頻
實(shí)現(xiàn)原理:
uniapp的nvue內(nèi)置原生插件 BindingX。具體可查看 uniapp 原生插件引入、 BindingX
效果展示:
項(xiàng)目地址:
具體實(shí)現(xiàn):
1. 在實(shí)現(xiàn)音視頻功能插件提供的視頻容器外邊包裹一層。
如:(使用 anyRTC 音視頻插件)
<view ref="move" @touchstart="drag_start">
<AR-CanvasView ref="location" style="flex: 1;" />
</view>
2. 使用nvue內(nèi)置插件 BindingX(uniapp已默認(rèn)集成) 。
nvue內(nèi)置插件,具體可查看 uniapp 原生插件引入
BindingX 效果以及相關(guān)方法可參考 BindingX
const BindingX = uni.requireNativePlugin('bindingx');
3. 實(shí)現(xiàn)拖拽具體方法:
1. 相關(guān)數(shù)據(jù)(nvue)
```javascript
data() {
return {
// 頁(yè)面高寬
windowWidth: 200,
windowHeight: 400,
// 記錄當(dāng)前位置
position: {
x: 0,
y: 0
},
// 判斷是點(diǎn)擊事件還是拖動(dòng)事件
timer: false,
}
}
```
?
2. 封裝 BindingX 獲取拖動(dòng)的元素(添加到nvue的methods)
```javascript
// 獲取元素
getEl(el) {
if (typeof el === 'string' || typeof el === 'number') return el;
if (WXEnvironment) {
return el.ref;
} else {
return el instanceof HTMLElement ? el : el.$el;
}
},
```
3. 為可拖動(dòng)元素綁定手指觸發(fā)touchstart
事件(添加到nvue的methods)
```javascript
drag_start(e) {
const move = this.getEl(this.$refs.move);
let oBindingX = BindingX.bind({
anchor: move,
eventType: 'pan',
props: [{
element: move,
property: 'transform.translateX',
expression: `x+${this.position.x}`,
},
{
element: move,
property: 'transform.translateY',
expression: `y+${this.position.y}`,
}
]
}, (e) => {
if (e.state === 'end') {
if (this.timer) {
//移動(dòng)時(shí)間特別短暫 視為點(diǎn)擊事件
clearTimeout(this.timer);
// 點(diǎn)擊事件處理
}
BindingX.unbind({
token: oBindingX.token,
eventType: 'pan'
})
//記錄位置
this.position.x += e.deltaX;
this.position.y += e.deltaY;
// x軸邊界
if (-this.position.x >= (this.windowWidth - 193)) {
this.position.x = 193 - this.windowWidth;
}
if (this.position.x > 0) {
this.position.x = 0;
}
// y 軸邊界
if (this.position.y < 0) {
this.position.y = 0;
}
if (this.position.y >= (this.windowHeight - 244)) {
this.position.y = this.windowHeight - 244;
}
// 結(jié)束拖動(dòng)
this.endAmaier();
} else {
// 判斷點(diǎn)擊事件還是拖動(dòng)事件
this.timer = setTimeout(() => {
this.timer = null;
}, 50)
}
});
}
// 結(jié)束拖動(dòng)
endAmaier(e) {
const my = this.getEl(this.$refs.move);
let result = BindingX.bind({
eventType: 'timing',
exitExpression: 't>200',
props: [{
element: my,
property: 'transform.translateX',
expression: "easeOutElastic(t," + this.position.x + "," + 0 +
",200)",
},
{
element: my,
property: 'transform.translateY',
expression: "easeOutElastic(t," + this.position.y + "," + 0 +
",200)",
}
]
}, (e) => {
if (e.state === 'end' || e.state === 'exit') {
BindingX.unbind({
token: result.token,
eventType: 'timing'
})
}
});
}
```
?
4. 運(yùn)行項(xiàng)目,即可流暢拖動(dòng)
本文摘自 :https://blog.51cto.com/u