當前位置:首頁 > IT技術 > 移動平臺 > 正文

uni-app技術分享| 用uni-app實現(xiàn)拖動的訣竅
2021-10-12 14:16:45

還在為實現(xiàn)類似于QQ視頻通話 那樣的視頻窗口隨意拖動而苦惱嗎?福音來了,今天就為大家解決這樣的煩惱。

前提:

使用 anyrtc 基本實現(xiàn)音視頻(nvue頁面)

需求:

兩人通話時可隨意拖動小視頻

實現(xiàn)原理:

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

效果展示:

在這里插入圖片描述
在這里插入圖片描述

項目地址:

Call_uniapp

具體實現(xiàn):

1. 在實現(xiàn)音視頻功能插件提供的視頻容器外邊包裹一層。

如:(使用 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. 實現(xiàn)拖拽具體方法:

1. 相關數(shù)據(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. 為可拖動元素綁定手指觸發(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) { 
                              //移動時間特別短暫 視為點擊事件
                            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. 運行項目,即可流暢拖動

本文摘自 :https://blog.51cto.com/u

開通會員,享受整站包年服務立即開通 >