目錄
3.wxs回應事件" >3.wxs回應事件
首頁 web前端 uni-app uniapp怎麼實現小程式頁面的自由拖曳功能

uniapp怎麼實現小程式頁面的自由拖曳功能

Sep 07, 2021 pm 07:28 PM
uniapp 小程式

uniapp怎麼實作小程式頁面的自由拖曳功能?以下這篇文章跟大家介紹一下uniapp實作小程式頁面自由拖曳組件的方法,希望對大家有幫助!

uniapp怎麼實現小程式頁面的自由拖曳功能

先看實現效果:

uniapp怎麼實現小程式頁面的自由拖曳功能

【相關推薦:《uniapp教學》】

實作過程

根據查閱文檔,要實現拖曳功能,大概有三種方式:

1.給需要實現拖曳的元素監聽#catchtouchmove事件,動態修改樣式座標

#這種方式最容易想到,透過js監聽觸控位置動態修改元素座標。但是拖曳是即時性要求非常高的操作,你不能說在這個操作裡面去設定節流函數減少setData操作,並且本身每次setData操作也是比較耗性能的,很容易造成拖曳卡頓,這個方案可以先排除。

2.movable-area movable-view

#movable-area元件的作用是定義一個區域,在這個區域內的movable- view的元件可以被使用者自由的移動,同時movable-view也可以輕鬆設定放大縮小效果。根據元件定義,可以想到它的使用場景大概是在頁面局部區域內對一些元素拖曳縮放,這個與我們想要的在整個頁面進行自由拖曳的需求不符。

3.wxs回應事件

wxs是專門用來解決有頻繁互動的場景,它直接在視圖層運行,免去了視圖層跟邏輯層通訊帶來的效能損耗,實現流暢的動畫效果。詳見:wxs回應事件 。根據wxs的使用場景,基本能確定我們要的功能實作應該使用wxs方案。

程式碼實作

我們使用的是uniapp框架,查閱uniapp文檔,官方直接提供了一個自由拖曳的程式碼案例,鏈接點擊這裡

直接拿官方的程式碼範例改造一番,如下:

<template>
    <view catchtouchmove="return">
        <view @click="play" @touchstart="hudun.touchstart" @touchmove="hudun.touchmove" @touchend="hudun.touchend">
            <canvas id="lottie-canvas" type="2d" style="width: 88px; height: 102px;"></canvas>
        </view>
    </view>
</template>

<script module="hudun">
    var startX = 0
    var startY = 0
    var lastLeft = 20
    var lastTop = 20

    function touchstart(event, ins) {
        ins.addClass(&#39;expand&#39;)
        var touch = event.touches[0] || event.changedTouches[0]
        startX = touch.pageX
        startY = touch.pageY
    }
    
    function touchmove(event, ins) {
        var touch = event.touches[0] || event.changedTouches[0]
        var pageX = touch.pageX
        var pageY = touch.pageY
        var left = pageX - startX + lastLeft
        var top = pageY - startY + lastTop
        startX = pageX
        startY = pageY
        lastLeft = left
        lastTop = top
        ins.selectComponent(&#39;.movable&#39;).setStyle({
            right: -left + &#39;px&#39;,
            bottom: -top + &#39;px&#39;
        })
    }
    
    function touchend(event, ins) {
        ins.removeClass(&#39;expand&#39;)
    }
    
    module.exports = {
        touchstart: touchstart,
        touchmove: touchmove,
        touchend: touchend
    }
</script>

<script>
    import lottie from &#39;lottie-miniprogram&#39;
    let insList = {} // 存放动画实例集合
    export default {
        props: {
            tag: String
        },
        data() {
            return {
                isPlay: true,
            }
        },
        methods: {
            init() {
                const query = uni.createSelectorQuery().in(this)
                query.select(&#39;#lottie-canvas&#39;).fields({ node: true, size: true }).exec((res) => {
                    const canvas = res[0].node
                    const context = canvas.getContext(&#39;2d&#39;)
                    const dpr = uni.getSystemInfoSync().pixelRatio
                    canvas.width = res[0].width * dpr
                    canvas.height = res[0].height * dpr
                    context.scale(dpr, dpr)
                    lottie.setup(canvas)
                    const ins = lottie.loadAnimation({
                        loop: true,
                        autoplay: true,
                        path: &#39;https://usongshu.oss-cn-beijing.aliyuncs.com/data/other/f8780255686b0bb35d25464b2eeea294.json&#39;,
                        rendererSettings: {
                            context,
                        },
                    })
                    insList[this.tag] = ins
                    setTimeout(() => {
                        this.isPlay = false
                        ins.stop()
                    }, 3000)
                })
            },
            play() {
                const ins = insList[this.tag]
                if (!this.isPlay) {
                    this.isPlay = true
                    ins.play()
                    setTimeout(() => {
                        this.isPlay = false
                        ins.stop()
                    }, 3000)
                }
            }
        },
        beforeDestroy() {
            delete insList[this.tag]
        }
    }
</script>

<style>
    .area
        position fixed
        right 20px
        bottom 20px
        width 88px
        height 102px
        z-index 99999

    .expand
        width 100vw
        height 100vh

    .movable
        position absolute
</style>
登入後複製

上面程式碼是開篇效果圖實作的完整程式碼,已經封裝一個單獨的元件。我們要拖曳的是一個canvas元素,用到了lottie動畫庫,點擊時會播放動畫。如果你要實現頁面拖曳的只是一個簡單的按鈕,那程式碼量會少很多。如果你要實現的功能跟這個類似,那麼針對上面程式碼有以下幾點需要值得解釋:

1.我們的需求是在多個頁面需要展示,經過查閱相關資料,是沒法實現在只在一個地方放置元件,然後每個頁面展示,必須每個頁面引入該元件。幸運的是,uniapp支援定義全域小程式元件,可以幫助我們減少引入的程式碼量。做法如下: 在main.js中定義元件

// 动画组件
import { HudunAnimation } from &#39;@/components/hudun-animation/index&#39;
Vue.component(&#39;HudunAnimation&#39;, HudunAnimation)
登入後複製

頁面中使用: wxml:

<HudunAnimation tag="index" ref="hudunRef"></HudunAnimation>
登入後複製
// 进入页面时初始化动画
mounted() {
    this.$refs.hudunRef.init()
}
登入後複製

2.可以注意到,上面封裝的元件當中,有一個tag屬性,它是用來識別來自哪個頁面的動畫實例。它的存在是由於在元件當中,正常情況下我們可以直接在data中定義一個屬性存放動畫實例,但是經過踩坑發現如果直接這麼寫

this.ins = lottie.loadAnimation({})
登入後複製

控制台會報一個錯誤,是因為lottie.loadAnimation({})回傳的物件放置在data中會經過一個JSON.stringfy的過程,在這個過程中不知道什麼原因報錯了。為了解決此報錯,改為在元件全域定義一個insList存放動畫實例集合,透過傳入的tag拿到對應的頁面實例,然後呼叫對應的實例play方法。

頁面穿透及點擊問題

1、拖曳頁面的時候,會帶動頁面的滾動,解決這個問題很簡單,在area view中新增

catchtouchmove="return"
登入後複製

即可

2、無法點選拖曳區域頁面按鈕問題。首先我們的拖曳區域是整個頁面,用的是fixed定位覆蓋整個頁面,但是這麼一來就會導致蒙層下面的頁面無法回應點擊事件。所以我們需要透過動態設定類別名稱expand,當元素處於拖曳狀態時,我們才將蒙層的區域覆蓋整個頁面,而初始時區域跟拖曳元素保持一致即可。程式碼實作見上面完整程式碼

檢視體驗效果

#微信搜尋小程式:說客英語--你的私人外教

更多程式相關知識,請造訪:程式設計入門! !

以上是uniapp怎麼實現小程式頁面的自由拖曳功能的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

webstorm開發uniapp專案如何啟動預覽 webstorm開發uniapp專案如何啟動預覽 Apr 08, 2024 pm 06:42 PM

在 WebStorm 中啟動 UniApp 專案預覽的步驟:安裝 UniApp 開發工具外掛程式連接到裝置設定 WebSocket啟動預覽

uniapp和mui哪個好 uniapp和mui哪個好 Apr 06, 2024 am 05:18 AM

整體而言,需複雜原生功能時,uni-app 較好;需簡單或高度自訂介面時,MUI 較好。此外,uni-app 具備:1. Vue.js/JavaScript 支援;2. 豐富原生組件/API;3. 良好生態系。缺點是:1. 效能問題;2. 客製化介面困難。 MUI 具備:1. Material Design 支援;2. 高度彈性;3. 廣泛元件/主題庫。缺點是:1. CSS 依賴;2. 不提供原生元件;3. 生態系較小。

uniapp有什麼缺點 uniapp有什麼缺點 Apr 06, 2024 am 04:06 AM

UniApp 作為跨平台開發框架擁有許多便利,但缺點也較為明顯:效能受限於混合開發模式,導致開啟速度、頁面渲染和互動回應較差。生態系統不完善,特定領域組件和庫較少,限制創意發揮和複雜功能實現。不同平台的相容性問題,易出現樣式差異和 API 支援不一致的情況。 WebView 的安全機制不同於原生應用,可能降低應用程式安全性。同時支援多個平台的應用程式發布更新需要多次編譯打包,增加開發和維護成本。

uniapp用什麼開發工具 uniapp用什麼開發工具 Apr 06, 2024 am 04:27 AM

UniApp使用HBuilder X作為官方開發工具,該IDE整合了程式碼編輯器、偵錯器、模擬器和豐富的插件,為跨平台行動應用程式開發提供全面的支援。

學uniapp需要哪些基礎 學uniapp需要哪些基礎 Apr 06, 2024 am 04:45 AM

uniapp開發需要以下基礎:前端技術(HTML、CSS、JavaScript)行動開發知識(iOS和Android平台)Node.js其他基礎(版本控制工具、IDE、行動開發模擬器或真機除錯經驗)

uniapp和flutter有什麼差別 uniapp和flutter有什麼差別 Apr 06, 2024 am 04:30 AM

UniApp 基於 Vue.js,Flutter 基於 Dart,兩者都支援跨平台開發。 UniApp 提供豐富的元件和簡易開發,但效能受限於 WebView;Flutter 使用原生渲染引擎,效能優異,但開發難度較高。 UniApp 擁有活躍的中文社區,Flutter 擁有龐大且全球化的社區。 UniApp 適合快速開發、效能要求不高的場景;Flutter 適合客製化程度高、高效能的複雜應用。

uniapp和原生開發哪個好 uniapp和原生開發哪個好 Apr 06, 2024 am 05:06 AM

在 UniApp 和原生開發之間選擇時,應考慮開發成本、效能、使用者體驗和靈活性。 UniApp 優點在於跨平台開發、快速迭代、易於學習和內建插件,而原生開發則在效能、穩定性、原生體驗和可擴展性方面更勝一籌。根據特定專案需求權衡利弊,初學者適合 UniApp,追求高效能和無縫體驗的複雜應用程式適合原生開發。

解決UniApp報錯:無法找到'xxx'動畫效果的問題 解決UniApp報錯:無法找到'xxx'動畫效果的問題 Nov 25, 2023 am 11:43 AM

解決UniApp報錯:無法找到'xxx'動畫效果的問題UniApp是一種基於Vue.js框架的跨平台應用程式開發框架,可用於開發微信小程式、H5、App等多個平台的應用程式。在開發過程中,我們常會使用到動畫效果來提升使用者體驗。然而,有時候會遇到一個報錯:無法找到'xxx'動畫效果。這個報錯會導致動畫無法正常運作,造成開發不便。本文將介紹幾種解決這個問題的方法。

See all articles