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. 運行項目,即可流暢拖動


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM