uni-app技术分享| 用uni-app实现拖动的诀窍
还在为实现类似于QQ视频通话
那样的视频窗口随意拖动而苦恼吗?福音来了,今天就为大家解决这样的烦恼。
前提:
使用 anyrtc 基本实现音视频(nvue页面)
需求:
两人通话时可随意拖动小视频
实现原理:
uniapp的nvue内置原生插件 BindingX。具体可查看 uniapp 原生插件引入、 BindingX
效果展示:
项目地址:
Call_uniapp
具体实现:
1. 在实现音视频功能插件提供的视频容器外边包裹一层。
如:(使用 anyRTC 音视频插件)
<view ref="move" @touchstart="drag_start"> <AR-CanvasView ref="location" style="flex: 1;" /> </view> 复制代码
2. 使用nvue内置插件 BindingX(uniapp已默认集成) 。
nvue内置插件,具体可查看 uniapp 原生插件引入 BindingX 效果以及相关方法可参考 BindingX
const BindingX = uni.requireNativePlugin('bindingx'); 复制代码
3. 实现拖拽具体方法:
1. 相关数据(nvue)
```javascript data() { return { // 页面高宽 windowWidth: 200, windowHeight: 400, // 记录当前位置 position: { x: 0, y: 0 }, // 判断是点击事件还是拖动事件 timer: false, } } ``` 复制代码
2. 封装 BindingX 获取拖动的元素(添加到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. 为可拖动元素绑定手指触发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) { //移动时间特别短暂 视为点击事件 clearTimeout(this.timer); // 点击事件处理 } 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; } // 结束拖动 this.endAmaier(); } else { // 判断点击事件还是拖动事件 this.timer = setTimeout(() => { this.timer = null; }, 50) } }); } // 结束拖动 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. 运行项目,即可流畅拖动
作者:anyRTC
链接:https://juejin.cn/post/7018023917562363934