vue移动端悬浮按钮吸边效果

<template>
    <div>
        <div class="short-box" v-if="path != '/login'" ref="shortList">
            <div class="short-btn customer-service" @click="showMask = !showMask" ref="customerService"
             @touchstart="!showMask && touchstartHandle('customerService',$event)"
             @touchmove="!showMask && touchmoveHandle('customerService',$event)"
             @touchend="!showMask && end('customerService')">
                <div class="short-list" :class="{ show: showMask, classFlag: classFlag, topPos: !classFlag}">
                    <div class="short-item">
                        <p><van-icon class="iconfont icon-shouye" /></p>
                        <p>首页</p>
                    </div>
                    <div class="short-item">
                        <p><van-icon class="iconfont icon-xinjian" /></p>
                        <p>新建</p>
                    </div>
                    <div class="short-item">
                        <p><van-icon class="iconfont icon-qiehuan" /></p>
                        <p>切换</p>
                    </div>
                    <div class="short-item">
                        <p><van-icon class="iconfont icon-fanhui" /></p>
                        <p>返回</p>
                    </div>
                </div>
                <van-icon class="iconfont" :class="{ 'icon-guanbi1': showMask, 'icon-caidan1': !showMask }" />
            </div>
        </div>
    </div>
</template>

以上为HTML代码里面带有可展开的操作项,项目中用到了vant框架,和阿里的字体图标

.customer-service{
    position: fixed;
    right: 20px;
    width: 88px;
    bottom: 180px;
    z-index: 99;
}
    .short-btn {
        width: 88px;
        height: 88px;
        border-radius: 50%;
        text-align: center;
        background: linear-gradient(321deg, #4575F4 0%, #5B85F2 30%, #79C1FF 100%);
        box-shadow: 0px 3px 5px 0px #B4C8FF;
        position: fixed;
        display: flex;
        justify-content: center;
        align-items: center;

        i {
            font-size: 44px;
            border-radius: 50%;
            color: #fff;

            &.icon-guanbi1 {
                font-size: 30px;
            }
        }
    }

    .short-list {
        width: 88px;
        background: #E0EBF7;
        border-radius: 48px;
        margin-bottom: 20px;
        box-sizing: border-box;
        min-height: 0px;
        max-height: 0px;
        overflow: hidden;
        transition: max-height ease-out 0.2s;
        position: absolute;
        &.topPos{
            bottom: 88px;
        }
        &.classFlag{
            top: 100px;
        }
        .short-item {
            text-align: center;
            padding: 24px 0;
            p {
                font-size: 20px;
                color: #999999;
                margin: 0;
                line-height: 20px;

                i {
                    font-size: 44px;
                    color: #0179FF;
                    margin-bottom: 10px;
                }
            }

            +.short-item {
                border-top: 1px solid #C4D3E4;
            }
        }

        &.show {
            max-height: 500px;
            transition: max-height ease-out 0.2s;
        }
    }

由于拖拽按钮需要根据悬浮按钮的定位上面展开或者悬浮按钮下面展开,所以需要设置不同的定位方式,根据类名topPos或者classFlag类名定义不同的定位方式。

<script>
    export default {
        data() {
              return {
                touch: {
                    initialPosition: {
                        x: 0,
                        y: 500
                    },
                    movePostion: {}
                },
                element: {
                    initialPosition: {},
                    movePostion: {}
                },
                nowLeft: -1,
                classFlag: false     
              }
        },
        methods:{
            touchstartHandle (refName, e) {
                // 触摸开始
                let touchTarget = e.targetTouches[0];
                // 记录触摸点的坐标(初始位置)
                this.touch.initialPosition = {
                    x: touchTarget.clientX,
                    y: touchTarget.clientY
                }
                // 记录需要移动的元素坐标(初始位置)
                this.element.initialPosition = {
                    x: this.$refs[refName].offsetLeft,
                    y: this.$refs[refName].offsetTop
                }
            },
            touchmoveHandle (refName, e) {
                e.preventDefault();
                let touchTarget = e.targetTouches[0];
                let X = this.element.initialPosition.x + (touchTarget.clientX - this.touch.initialPosition.x);
                let Y = this.element.initialPosition.y + (touchTarget.clientY - this.touch.initialPosition.y);
                let maxWidth = innerWidth - this.$refs[refName].offsetWidth;
                let maxHeight = innerHeight - this.$refs[refName].offsetHeight;
                X = X <= 0 ? 0 : X >= maxWidth ? maxWidth : X;
                Y = Y <= 0 ? 0 : Y >= maxHeight ? maxHeight : Y;
                this.nowLeft = X;
                this.classFlag = Y < 300
                // 移动元素
                this.$refs[refName].style.left = X + 'px'
                this.$refs[refName].style.top = Y + 'px';
            },
            end (refName) {
                if (this.nowLeft < 0) {
                    return;
                }
                // 吸边处理
                let halfMaxWidth = (innerWidth - this.$refs[refName].offsetWidth) / 2;
                const dragDiv = this.$refs[refName];
                if (this.nowLeft> halfMaxWidth) {
                    // 右吸边
                    dragDiv.style.left = document.documentElement.clientWidth - parseInt(dragDiv.clientWidth) -10 + 'px';
                }
                else {
                    // 左吸边
                    dragDiv.style.left = "10px";
                }
                dragDiv.style.top = dragDiv.offsetTop + 'px';
            },
        }
    }
</script>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值