美文网首页
vue移动端——固定盒子计算拖拽元素的位置案例二

vue移动端——固定盒子计算拖拽元素的位置案例二

作者: 加冰宝贝 | 来源:发表于2020-11-28 03:00 被阅读0次

1.给后台提交拖拽位置数据

  • 由于前端的(x,y)轴是根据页面来计算元素距离页面的上左边距的距离,所有当你将拖拽的元素拖到合适的位置时,给后台提交数据的时候并不是将你拖拽好的(x,y)轴数值给后台。首先你要知道你给传的是拖拽好的元素的距离固定元素的 左边距 顶边距。如下图 有计算法(具体 查看 代码 标有注意点二)

    1 .根据屏幕 固定元素(屏幕中套有固定元素,在这个元素中 进行昵称 头像 二维码的拖拽) 例如图: 微信图片_20201127165453.png

// 拖拽元素的左边距 = 拖拽圆的左边距 - 固定元素的左边距
this.posterone.positionX = document.getElementById("circlebox").offsetLeft - this.PosterimgLeft;
// 拖拽元素的顶边距 = 拖拽圆的顶边距 - 固定元素的顶边距
this.posterone.positionY = document.getElementById("circlebox").offsetTop - this.PosterimgTop;


2.由于后台根据前端传入的值来生成图片,拖拽的元素位置还是有偏差问题,因为后台生成海报 是根据图片的原始宽高度进行计算,前端的图片宽高度是居于手机屏幕 宽高对缩小的。如果你想要计算的更精确的话,你需要后台将图片的实际宽度传给前端进行计算,计算好元素的在前端的宽度,再进行拖拽,拖拽好的位置根据以上解释进行计算,位置就刚刚好了。(具体 查看 代码 标有注意点一)

注意点一的计算放大
let odiv = document.getElementById(data); //移动 盒子
let odiv1 = document.getElementById(data1); //固定 图片
// 拖拽元素的宽 = 前端固定图片的宽度 / 后台传回的固定图片的实际kua
var width = (odiv1.offsetWidth / this.imgW) * num;
odiv.style.width = width + 'px';
odiv.style.height = width + 'px';

<template>
    <div ref="content" style="display: flex;justify-content: center;align-items: center;">
        <van-nav-bar :placeholder="true" :fixed='true' title="海报内容位置设置" left-text="返回" right-text="确认" left-arrow :safe-area-inset-top="true" @click-left="onClickLeft" @click-right="Posterbtn" />
        <div class="poster-bgdiv" style="margin-top:30px;">
            <img :src="Posterimg" alt="" id="Posterimg">
            <div @touchstart="down" @touchmove="move" @touchend="end" id="circlebox" class="circle name">昵称</div>
            <div @touchstart="downone" @touchmove="moveone" @touchend="endone" id="circlebox1" class="circle photo">头像</div>
            <div @touchstart="downtwo" @touchmove="movetwo" @touchend="endtwo" id="circlebox2" class="circle code">二维码</div>
            <!-- <van-uploader :after-read="afterRead">更换图片</van-uploader> -->
        </div>
    </div>
</template>
<script>
    import { Toast } from 'vant';
    import { HeightAuto } from '../../assets/js/height.js'; //公共 js 判断是否给html 和 body 添加 height1
    export default {
        data() {
            return {
                user_activity_id:this.$route.query.user_activity_id,
                activity_id:this.$route.query.activity_id,// 成功领取活动后 领取活动id
                table_id:this.$route.query.table_id,//编辑列表 id
                url:this.$route.query.url, //上一页路由
                post_url: localStorage.getItem("post_url"), //接口
                Posterimg: localStorage.getItem("posterImg"), //海报img
                imgW:0,
                loadingImg:false,
                innerHeight: 0,
                innerWidth: 0,
                posterone:{ /* 昵称 */
                    positionX: 0,
                    positionY:0,
                },
                postertwo:{ /* 头像 */
                    positionXone:0,
                    positionYone: 0,
                },
                posterthree:{/* 二维码 */
                    positionXtwo: 0,
                    positionYtwo: 0,
                },
                PosterimgLeft:0,
                PosterimgTop:0,
            };
        },
        created: function() {
            this.getPosition();
            this.clientHeight();
        },
        methods: {
            /* 获取 拖拽位置 */
            getPosition(){
                let data = {
                    user_activity_id: this.activity_id,
                    type:1,
                    table_id:this.table_id,
                }
                this.$api.post('/request' + this.post_url, data).then(res => {
                    console.log("表单数据回显", res)
                    if (res.code == 0) {
                        //注意点一
                        this.imgW = res.data.imgW; // 后台 海报背景的实际宽度
                        this.getImgshi("circlebox1","Posterimg",80);
                        this.getImgshi("circlebox2","Posterimg",120);

                        let arr = res.data.json.split("|");
                        this.PosterimgLeft = document.getElementById("Posterimg").offsetLeft;
                        this.PosterimgTop = document.getElementById("Posterimg").offsetTop;
                        if(arr.length!=0){
                            this.posterone = JSON.parse(arr[0])
                            this.postertwo= JSON.parse(arr[1]);
                            this.posterthree = JSON.parse(arr[2]);
                            this.posone = JSON.parse(arr[0])
                            this.postwo= JSON.parse(arr[1]);
                            this.posthree = JSON.parse(arr[2]);
                            this.getThis("circlebox",JSON.parse(arr[0]).positionX,JSON.parse(arr[0]).positionY)
                            this.getThis("circlebox1",JSON.parse(arr[1]).positionXone ,JSON.parse(arr[1]).positionYone)
                            this.getThis("circlebox2",JSON.parse(arr[2]).positionXtwo,JSON.parse(arr[2]).positionYtwo)
                        }else{
                            this.posterone.positionX = document.getElementById("circlebox").offsetLeft - this.PosterimgLeft;
                            this.posterone.positionY = document.getElementById("circlebox").offsetTop - this.Posterimgtop;
                            this.postertwo.positionXone = document.getElementById("circlebox1").offsetLeft - this.PosterimgLeft;
                            this.postertwo.positionYone = document.getElementById("circlebox1").offsetTop - this.Posterimgtop;
                            this.posterthree.positionXtwo = document.getElementById("circlebox2").offsetLeft - this.PosterimgLeft;
                            this.posterthree.positionXtwo = document.getElementById("circlebox2").offsetTop - this.Posterimgtop;
                        }
                    }
                });
            },
            
            /* 图片 适配 */
            getImgshi(data,data1,num){
                let odiv = document.getElementById(data); //移动 盒子
                let odiv1 = document.getElementById(data1); //固定 图片
                var width = (odiv1.offsetWidth / this.imgW) * num;
                odiv.style.width = width + 'px';
                odiv.style.height = width + 'px';
            },
            
            /* 默认回显位置 */
            getThis(data,left ,top) {
                let odiv = document.getElementById(data); //移动 盒子
                odiv.style.left = left +'px';
                odiv.style.top = top + 'px';
            },
            
            /* 阻止移动端屏幕默认滑动 */
            default (e, data) {
                let divv = document.getElementById(data);
                divv.addEventListener('touchmove',function(e) {
                        e.preventDefault();
                    }, {
                        passive: false
                    }
                );
            },

            getThisNode(positionXs, positionYs, innerWidths, innerHeights, data) {
                let odiv = document.getElementById(data); //移动 盒子
                let div = document .getElementsByClassName("poster-bgdiv")[0]; //固定 盒子
                //最小左边距 (屏幕宽 - 固定盒子宽)的一半 + 移动元素宽度的一半
                let minleft = (innerWidths - div.clientWidth) / 2 + odiv.clientWidth / 2;
                //最大左边距 (屏幕宽 - 固定盒子宽)的一半  + 固定盒子宽 - 移动元素宽度的一半
                let maxleft = (innerWidths - div.clientWidth) / 2 + div.clientWidth  - odiv.clientWidth / 2;
                //最小顶边距 (屏幕高 - 固定盒子高)的一半 + 移动元素高度的一半
                let mintop = (innerHeights - div.clientHeight) / 2 + odiv.clientHeight / 2 + 30;
                //最大顶边距 (屏幕高 - 固定盒子高)的一半  + 固定盒子高 - 移动元素高度的一半
                let maxtop = (innerHeights - div.clientHeight) / 2 + div.clientHeight  - odiv.clientHeight / 2 + 28;
                if (positionXs <= minleft) {
                    positionXs = minleft;
                } else if (positionXs >=  maxleft) {
                    positionXs = maxleft;
                } else {
                    positionXs = positionXs;
                }
                if (positionYs <= mintop) {
                    positionYs = mintop
                } else if (positionYs >= maxtop) {
                    positionYs = maxtop
                } else {
                    positionYs = positionYs
                }
                odiv.style.left = `${positionXs - minleft}px`;
                odiv.style.top = `${positionYs - mintop}px`;
            },

            // 光标按下
            down(e) {
                this.default(e, "circlebox");
                this.innerHeight = e.view.innerHeight;
                this.innerWidth = e.view.innerWidth;
                this.posterone.positionX = e.changedTouches[0].pageX.toFixed(0);
                this.posterone.positionY = e.changedTouches[0].pageY.toFixed(0);
            },
            // 光标移动
            move(e) {
                this.getThisNode(this.posterone.positionX, this.posterone.positionY, this.innerWidth, this.innerHeight, "circlebox");
                this.default(e, "circlebox");
                this.posterone.positionX = e.changedTouches[0].pageX.toFixed(0);
                this.posterone.positionY = e.changedTouches[0].pageY.toFixed(0);
                this.getThisNode(this.posterone.positionX, this.posterone.positionY, this.innerWidth, this.innerHeight, "circlebox");
            },
            // 光标抬起
            end(e) {
                // console.log('end');
            },

            // 光标按下
            downone(e) {
                this.default(e, "circlebox1");
                this.innerHeight = e.view.innerHeight;
                this.innerWidth = e.view.innerWidth;
                this.postertwo.positionXone = e.changedTouches[0].pageX.toFixed(0);
                this.postertwo.positionYone = e.changedTouches[0].pageY.toFixed(0);
            },
            // 光标移动
            moveone(e) {
                this.getThisNode(this.postertwo.positionXone, this.postertwo.positionYone, this.innerWidth, this.innerHeight,"circlebox1");
                this.default(e, "circlebox1");
                this.postertwo.positionXone = e.changedTouches[0].pageX.toFixed(0);
                this.postertwo.positionYone = e.changedTouches[0].pageY.toFixed(0);
                this.getThisNode(this.postertwo.positionXone, this.postertwo.positionYone, this.innerWidth, this.innerHeight,"circlebox1");
            },
            // 光标抬起
            endone(e) {
                // console.log('end');
            },

            // 光标按下
            downtwo(e) {
                this.default(e, "circlebox1");
                this.innerHeight = e.view.innerHeight;
                this.innerWidth = e.view.innerWidth;
                this.posterthree.positionXtwo = e.changedTouches[0].pageX.toFixed(0);
                this.posterthree.positionYtwo = e.changedTouches[0].pageY.toFixed(0);
            },
            // 光标移动
            movetwo(e) {
                this.getThisNode(this.posterthree.positionXtwo, this.posterthree.positionYtwo,this.innerWidth, this.innerHeight,"circlebox2");
                this.default(e, "circlebox2");
                this.posterthree.positionXtwo = e.changedTouches[0].pageX.toFixed(0);
                this.posterthree.positionYtwo = e.changedTouches[0].pageY.toFixed(0);
                this.getThisNode(this.posterthree.positionXtwo, this.posterthree.positionYtwo,this.innerWidth, this.innerHeight, "circlebox2");
            },
            
            // 光标抬起
            endtwo(e) {
                // console.log('end');
            },
            
            /* 点击更换图片*/
            // afterRead(file) {
            //     // 此时可以自行将文件上传至服务器
            //     this.poster.loadingImg = true;
            //     let imgData = new FormData();
            //     imgData.append('img[]', file.file);
            //     this.$api.post('/request/index/market/upload2OSS', imgData).then(res => {
            //         console.log(res);
            //         setTimeout(()=>{
            //             this.loadingImg = false;
            //             this.Posterimg = res[0];
            //             Toast('上传图片成功');
            //         },1500);
            //     })
            // },
            
            /* 点击 确认 */
            Posterbtn(){
                if(this.Posterimg == ''){
                    Toast("请上传背景图");
                }else{
                    //注意点二
                    this.posterone.positionX = document.getElementById("circlebox").offsetLeft - this.PosterimgLeft;
                    this.posterone.positionY = document.getElementById("circlebox").offsetTop - this.PosterimgTop;
                    this.postertwo.positionXone= document.getElementById("circlebox1").offsetLeft - this.PosterimgLeft;
                    this.postertwo.positionYone = document.getElementById("circlebox1").offsetTop - this.PosterimgTop;
                    this.posterthree.positionXtwo = document.getElementById("circlebox2").offsetLeft - this.PosterimgLeft;
                    this.posterthree.positionYtwo = document.getElementById("circlebox2").offsetTop - this.PosterimgTop;
                    var arr=[JSON.stringify(this.posterone),JSON.stringify(this.postertwo),JSON.stringify(this.posterthree)];
                    let div = document .getElementsByClassName("poster-bgdiv")[0]; //固定 盒子
                    let data={
                        user_activity_id:this.activity_id,
                        json:arr.join("|"),
                        clientWidth:div.clientWidth,
                        clientHeight:div.clientHeight,
                    };
                    this.$api.post("/request/index/face/distr/index/actman", data).then(res => {
                        console.log(res)
                        if(res.code==0){
                            Toast(res.msg);
                            this.onClickLeft();
                        }
                    }).catch(error => {
                        console.log(error);
                    });
                }
            },
            
            /* 返回我的页 */
            onClickLeft() {
                this.$router.push({
                    path: this.url,
                    query:{
                        user_activity_id:this.user_activity_id,
                        activity_id:this.activity_id,
                        url:'/Administration'
                    }
                });
                localStorage.removeItem("post_url");
                localStorage.removeItem("posterImg");
            },

            /* 页面 填充 */
            clientHeight() {
                var timer = setInterval(() => {
                    if (this.$refs.content.offsetHeight != undefined) {
                        clearInterval(timer);
                        let eleObj = {
                            offsetHeight: this.$refs.content.offsetHeight,
                            clientHeight: Number(`${document.documentElement.clientHeight}`),
                        };
                        this.$refs.content.style.height = HeightAuto(eleObj);
                    }
                }, 500);
            },
        }
    };
</script>
<style>
    .poster-bgdiv {
        width: 85%;
        margin:0px auto 0px auto;
        position: relative;
    }

    .circle {
        position: absolute;
        z-index: 999;
        touch-action: none;
        background: #eee;
        color: #777;
        display: flex;
        justify-content: center;
        align-items: center;
    }

    .name {
        left:5%;
        top: 7.5%;
        padding:4px 8px;
        font-size:16px;
    }

    .photo {
        width: 60px;
        height: 60px;
        right: 5%;
        top: 5%;
        overflow: hidden;
        font-size:18px;
    }

    .code {
        width: 80px;
        height: 80px;
        left:5%;
        bottom: 5%;
        font-size:18px;
    }

    img {
        width: 100%;
        height: 100%;
    }
    .poster-bgdiv .van-uploader{
        width:22%;
        background:rgba(0,0,0,0.7) ;
        padding:8px 12px;
        position: fixed;
        display: flex;
        justify-content: center;
        align-items: center;
        top:50px;
        right: 0px;
        z-index: 999;
        color: #fff;
        font-size:14px;
    }
</style>

相关文章

  • vue移动端——固定盒子计算拖拽元素的位置案例二

    1.给后台提交拖拽位置数据 由于前端的(x,y)轴是根据页面来计算元素距离页面的上左边距的距离,所有当你将拖拽的元...

  • vue移动端——固定盒子计算拖拽元素的位置案例

  • 移动端和pc端的拖拽事件

    pc端拖拽事件 移动端的拖拽事件 移动端的拖拽事件的思路是当手指点下记录手指的坐标和box的位置。当手指移动的时候...

  • jQuery拖拽

    思路 父盒子相对定位,子元素,也就是被拖拽的元素绝对定位 当鼠标在子元素中按下时,绑定鼠标移动事件,根据鼠标位置改...

  • 封装移动端 vue 拖拽指令

    封装移动端 vue 拖拽指令 通过vue自定义指令,将拖拽行为封装为指令 使用transform做移动效果,需要注...

  • 总结

    1,1)移动端拖拽vue-draggablehttp://www.itxst.com/vue-draggable/...

  • css hover 隐藏与显示(替换)

    我这里是写在vue 项目里面的,style用的是less,上代码核心思想:固定父盒子的宽高,移动子盒子的位置,实现...

  • CSS三大核心-定位

    定位可以让盒子自由的在某个盒子内移动位置或者固定屏幕中的某个位置,并且可以压住其他盒子。或者固定在屏幕中的某个位置...

  • UI自动化07 屏幕动作ActionChains

    点击操作单击、双击、右键 鼠标移动移动到某个控件、移动到某个位置、移动到某个元素的某个位置 拖拽点击、移动、放松 ...

  • CSS面试考点准备之定位

    1、定位 定位是将盒子定在某一个位置,所以定位也是在摆放盒子,按照定位的方式移动盒子。定位可以让元素固定屏幕中的某...

网友评论

      本文标题:vue移动端——固定盒子计算拖拽元素的位置案例二

      本文链接:https://www.haomeiwen.com/subject/avwxwktx.html