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

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>

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,919评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,567评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,316评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,294评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,318评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,245评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,120评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,964评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,376评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,592评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,764评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,460评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,070评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,697评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,846评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,819评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,665评论 2 354

推荐阅读更多精彩内容