uniapp 拖拽小球編寫

編寫floatButton組件,主要代碼如下

<template>
    <view>
        <view class="float-button"
        :style="{
            left: safeLeft,
            top: safeTop,
            width: width + 'px',
            height: height + 'px',
            'transition': isMove ? 'none' : 'all .2s',
            'display': isShow ? 'block' : 'none'
        }"
        @touchstart.prevent.stop="dragStart" 
        @touchmove.prevent.stop="dragMove"
        @touchend.prevent.stop="dragStop"
        :animation="animation">
            <slot></slot>
        </view>
    </view>
</template>

<script>
    export default {
        props: {
            //  距離左邊的百分比
            x: {
                type: Number,
                default: 0
            },
            //  距離右邊的百分比
            y: {
                type: Number,
                default: 0
            },
            //  寬度
            width: {
                type: Number,
                default: 50
            },
            //  高度
            height: {
                type: Number,
                default: 50
            },
            //  離頁面邊上的距離
            padding: {
                type: Number,
                default: 10
            }
        },
        data () {
            return {
                isShow: false,
                isMove: false,
                start: [0, 0],
                moveY: null,
                moveX: null,
                windowWidth: null,
                windowHeight: null,
                animation: {},
                timeout: null
            }
        },
        computed: {
            safeLeft () {
                let maxX = this.windowWidth - this.width - this.padding
                let minX = this.padding
                if (this.moveX == null) {
                    let safeX = (this.x / 100) * this.windowWidth
                    return safeX > maxX ? maxX + 'px' : (safeX < minX) ? minX + 'px' : safeX + 'px'
                }
                return this.moveX > maxX ? maxX + 'px' : (this.moveX < minX) ? minX + 'px' : this.moveX + 'px'
            },
            safeTop () {
                let maxY = this.windowHeight - this.height - this.padding
                let minY = this.padding
                if (this.moveY == null) {
                    let safeY = (this.y / 100) * this.windowHeight
                    return safeY > maxY ? maxY + 'px' : (safeY < minY) ? minY + 'px' : safeY + 'px'
                }
                return this.moveY > maxY ? maxY + 'px' : (this.moveY < minY) ? minY + 'px' : this.moveY + 'px'
            }
        },
        mounted () {
            const {
                windowWidth,
                windowHeight
            } = uni.getSystemInfoSync()
            this.windowWidth = windowWidth
            this.windowHeight = windowHeight
            this.$nextTick(() => {
                this.isShow = true
            })
        },
        methods: {
            dragStart(event) {
                this.start[0] = event.touches[0].clientX - event.target.offsetLeft;
                this.start[1] = event.touches[0].clientY - event.target.offsetTop;
            },
            //判斷防止懸浮球被拖出頁面
            dragMove(event) {
                this.isMove = true
                const touch = event.touches[0] || event.changedTouches[0]
                this.moveX = touch.clientX - this.start[0]
                this.moveY = touch.clientY - this.start[1]
            },
            dragStop (event) {
                // 判斷在左側(cè)還是右側(cè)
                if (this.isMove) {
                    this.isMove = false
                    if (this.moveX > this.windowWidth / 2) {
                        this.moveX = this.windowWidth - this.width - this.padding
                    } else {
                        this.moveX = 0
                    }
                } else {
                    this.$emit('click')
                }
            }
        }
    }
</script>

<style lang="scss" scoped>
    .float-button{
        position: fixed;
        z-index: 999;
        transition: all .2s;
    }
</style>

使用

<floatButton :width="40" :height="40" :x="90" :y="90" @click="clickFun">
  // 這里放置需要的內(nèi)容
</floatButton>

效果如圖所示

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 商城首頁App的編寫,首先我們要確定我們需要確定一下大框架: 如圖所示,我們可以看到,首先我們需要一個內(nèi)容根布局,...
    仲夏之雪夢旅人閱讀 918評論 0 1
  • 協(xié)程屬于Kotlin中非常有特色的一項技術(shù),因為大部分編程語言中是沒有協(xié)程這個概念的。 那么什么是...
    隨風cvil閱讀 1,226評論 0 1
  • 用兩張圖告訴你,為什么你的 App 會卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 13,945評論 2 59
  • 通過第 12 章的學(xué)習(xí),大家已經(jīng)知道后臺的請求處理方法可以包含多種參數(shù)類型。 在實際的項目開發(fā)中,多數(shù)情況下客戶端...
    遼A丶孫悟空閱讀 561評論 1 12
  • 第一章 初識Flink 大數(shù)據(jù)開發(fā)總體架構(gòu) 數(shù)據(jù)傳輸層:常用的數(shù)據(jù)傳輸工具有Flume、Sqoop、Kafka。F...
    日落_3d9f閱讀 10,037評論 0 9

友情鏈接更多精彩內(nèi)容