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

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

    還在為實現類似于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. 運行項目,即可流暢拖動

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

    開通會員,享受整站包年服務
    国产呦精品一区二区三区网站|久久www免费人咸|精品无码人妻一区二区|久99久热只有精品国产15|中文字幕亚洲无线码