ホームページ  >  記事  >  ウェブフロントエンド  >  uniapp はミニ プログラム ページに無料のドラッグ アンド ドロップ機能をどのように実装していますか?

uniapp はミニ プログラム ページに無料のドラッグ アンド ドロップ機能をどのように実装していますか?

青灯夜游
青灯夜游転載
2021-09-07 19:28:048585ブラウズ

uniapp はミニ プログラム ページに無料のドラッグ アンド ドロップ機能をどのように実装していますか?次の記事では、uniapp がミニプログラム ページに自由なドラッグ アンド ドロップ コンポーネントを実装する方法を紹介します。

uniapp はミニ プログラム ページに無料のドラッグ アンド ドロップ機能をどのように実装していますか?

まず導入効果を見てみましょう:

uniapp はミニ プログラム ページに無料のドラッグ アンド ドロップ機能をどのように実装していますか?

[関連する推奨事項: "uniapp チュートリアル"]

実装プロセス

ドキュメントによると、約 3 つあります。ドラッグ アンド ドロップ機能を実現する手順。一方の方法:

1. 必要な要素の catchtouchmove イベントを監視します。ドラッグしてスタイル座標を動的に変更する

この方法は、js を使用してタッチ位置を監視し、要素の座標を動的に変更するのが最も簡単に考えられます。ただし、ドラッグ アンド ドロップは非常に高いリアルタイム パフォーマンスが必要な操作です。この操作にスロットル関数を設定して setData 操作を減らすことはできません。また、各 setData 操作自体は比較的パフォーマンスを重視しており、問題が発生しやすいです。ドラッグ アンド ドロップのラグ。このオプションは最初に削除できます。

2.可動領域可動ビュー

可動領域コンポーネントの役割は、可動領域を配置する領域を定義することです。ビューのコンポーネントはユーザーが自由に移動でき、可動ビューではズーム効果を簡単に設定できます。コンポーネント定義によると、その使用シナリオは、ページのローカル領域でいくつかの要素をドラッグして拡大縮小することと考えることができますが、これはページ全体で自由にドラッグ アンド ドロップする必要性と矛盾します。

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>

上記のコードは、オープニング レンダリングに実装された完全なコードであり、別のコンポーネントにカプセル化されています。ドラッグしたいのは、クリックするとアニメーションを再生する Lottie アニメーション ライブラリを使用する Canvas 要素です。ページ上に単純なボタンのドラッグを実装する場合、コードの量ははるかに少なくなります。実装したい機能がこれに似ている場合は、上記のコードの次の点を説明する必要があります:

1. 要件は複数のページに表示されることです。関連情報を参照した後、コンポーネントを 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. 上記でカプセル化されたコンポーネントの中に、どのページからのアニメーション インスタンスを識別するために使用されるタグ属性があることがわかります。これが存在するのは、通常の状況では、コンポーネント内でアニメーション インスタンスを保存するプロパティをデータに直接定義できるためですが、問題を掘り下げた結果、

this.ins = lottie.loadAnimation({})

を直接記述すると、コンソールがLottie.loadAnimation({}) によって返されたオブジェクトは、データに配置されるときに JSON.stringfy プロセスを通過するため、エラーを報告します。このプロセス中に、不明な理由でエラーが報告されます。このエラーを解決するには、代わりにコンポーネント内で insList をグローバルに定義してアニメーション インスタンス コレクションを保存し、受信タグを通じて対応するページ インスタンスを取得し、対応するインスタンスの play メソッドを呼び出します。

ページの侵入とクリックの問題1. ページをドラッグすると、ページがスクロールします。解決するのは非常に簡単です。この問題は、エリアビューに

catchtouchmove="return"

を追加するだけです

2. エリアページボタンをクリック&ドラッグできない問題。まず、ドラッグ領域はページ全体であり、固定位置を使用してページ全体をカバーしますが、これによりマスク レイヤーの下のページがクリック イベントに応答できなくなります。そのため、クラス名expandを動的に設定する必要があり、要素がドラッグ状態にあるとき、マスクされた領域をページ全体にカバーし、初期領域をドラッグされた要素と一致させることができます。コードの実装については、上記の完全なコードを参照してください。

エクスペリエンス効果の表示WeChat 検索アプレット: ロビイスト英語 - あなたの個人外国人教師

プログラミング関連の知識について詳しくは、プログラミング入門をご覧ください。 !

以上がuniapp はミニ プログラム ページに無料のドラッグ アンド ドロップ機能をどのように実装していますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。