uni-app技术分享| 用uni-app实现拖动的诀窍

还在为实现类似于QQ视频通话 那样的视频窗口随意拖动而苦恼吗?福音来了,今天就为大家解决这样的烦恼。

前提:

使用 anyrtc 基本实现音视频(nvue页面)

需求:

两人通话时可随意拖动小视频

实现原理:

uniapp的nvue内置原生插件 BindingX。具体可查看 uniapp 原生插件引入BindingX

效果展示:

![在这里插入图片描述]( https://img-blog.csdnimg.cn/d5992a41f2914514ac96f030f7713866.jpg?x-oss-process=image/watermark ,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAYW55UlRD,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
![在这里插入图片描述]( https://img-blog.csdnimg.cn/fbc8b6d3eb1d411787a806bb8fa06895.jpg?x-oss-process=image/watermark ,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAYW55UlRD,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)

项目地址:

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. 运行项目,即可流畅拖动
posted @ 2021-10-12 12:15  anyRTC  阅读(2124)  评论(0)    收藏  举报