H5实现图片随意拖动

533 阅读2分钟

原理:

移动后的位置坐标减去初始位置的坐标所得到的结果,
再加上图片位置偏移量(offsetLeft, offsetTop),就可以得到最终图片位置坐标。

HTML:

<div id="look-image">
    <!-- 图片展示区 -->
    <div class="look-image-content">
        <div class="show-image">
            <img :src="url" alt="" :id="id" ref="puzzle_img" :style="styleObj" @touchstart="start" @touchend="stop" @touchmove="move">
        </div>
    </div>
    <!-- 底部按钮操作去 -->
    <div class="look-image-footer" v-show="showTabs">
        <div class="enlargement" @click="magnify">
            <img src="@/assets/img/icon-plus.png" alt="">
        </div>
        <div class="shrink" @click="shrink">
            <img src="@/assets/img/icon-minus.png" alt="">
        </div>
    </div>
</div>

JS:

data() {
    return {
        multiples: 1,       // 放大或者缩小
        deg: 0,             // 旋转的角度
        styleObj: null,       // 拖拽时修改图片的样式
        isDrag: false,      // 是否开始拖拽
        startX: 0,          // 鼠标的点击X轴
        startY: 0,          // 鼠标的点击Y轴
        moveX: 0,           // 鼠标移动的X轴
        moveY: 0,            // 鼠标移动的Y轴
        endX: 100,
        endY: 100,
    }
},
props: {
    id: {                      // 图片链接
        type: String,
        default: ""
    },
    url: {                      // 图片链接
        type: String,
        default: ""
    },
    visible: {                  // 控制组件的显示与隐藏
        type: Boolean,
        default: false
    },
    type:{
        type: String,
        default: ""
    },
    showTabs:{
        type: Boolean,
        default: true
    }
},
created(){

    console.log(77777, this.id);
    
    if(this.type == '1'){
        this.styleObj = 'left: 100px;top:100px;'
    }else if(this.type == '2_1' || this.type == '2_2'){
        this.endX = 25
        this.styleObj = 'left: 25px;top:100px;'
    }else if(this.type == '3_1'){
        this.endX = 25
        this.styleObj = 'left: 25px;'
    }else if(this.type == '3_2'){
        this.endX = 25
        this.endY  = 15
        this.styleObj = 'left: 25px;top:15px'

    }else if(this.type == '4_1' || this.type == '4_2'){
        /* this.endY  = 45 */
        this.styleObj = 'left: 100px;top:45px'
    }
},
methods: {
    // 放大
    magnify() {

        if(this.type == '1'){
            this.endX = 100
        }else if(this.type == '2_1' || this.type == '2_2'){
            this.endX = 25
        }else if(this.type == '4_1'){
            this.endX = 100
            this.endY = 25
        }

        if(this.multiples >= 10){
            return
        }

        this.multiples += 0.25;
        this.styleObj = `transform: scale(${this.multiples}) rotateZ(${this.deg}deg);left:${this.endX}px;top:${this.endY}px`;
    },
    // 缩小
    shrink() {
        if(this.type == '1' ){
            this.endX = 100
        }else if(this.type == '2_1' || this.type == '2_2'){
            this.endX = 25
        }else if(this.type == '4_1'){
            this.endX = 100
            this.endY = 25
        }
        
        if(this.multiples <= 0){
            return
        }
        this.multiples -= 0.25;
        this.styleObj = `transform: scale(${this.multiples}) rotateZ(${this.deg}deg);left:${this.endX}px;top:${this.endY}px`;
    },
    // 旋转
    rotate(){
        this.deg += 90;
        if(this.deg >= 360){
            this.deg = 0
        }
        this.styleObj = `transform: scale(${this.multiples}) rotateZ(${this.deg}deg);left:${this.endX}px;top:${this.endY}px`;
    },
    start(e) {
        // 当点击图片时,开始拖拽
        this.isDrag = true;
        this.startX = e.targetTouches[0].pageX;
        this.startY = e.targetTouches[0].pageY;
        //this.styleObj = `transform: scale(${this.multiples}) rotateZ(${this.deg}deg);left:${this.endX}px;top:${this.endY}px`;
 

      /*   console.log('点击开始',  this.startX, this.endX, this.startY, this.endY);
        console.log('左右移动', this.styleObj)
        console.log(2222, e, e.targetTouches[0].pageX, test.offsetLeft, e.targetTouches[0].pageY, test.offsetTop); */
    },
    stop() {
        this.isDrag = false;
    },

    move(e) {
        // 当鼠标拖拽图片的时候,才计算移动距离
        // 移动图片相对于父元素的位置
        if(this.isDrag) {

       	    // 鼠标移动的距离
            this.moveX = e.targetTouches[0].pageX;
            this.moveY = e.targetTouches[0].pageY;
            // 相对页面的距离
            let x=this.moveX-this.startX;
            let y=this.moveY-this.startY;

            let test =  document.getElementById(this.id)
            
            // 移动后的距离 + 当前图片的偏移量 = 获取最后的图片位置
            this.endX = test.offsetLeft + x;
            this.endY = test.offsetTop + y; 

            console.log('x---轴', this.moveX, this.startX, test.offsetLeft, this.endX);
            console.log('y---轴',this.moveY, this.startY,  test.offsetTop, this.endY);

            this.startX = this.moveX
            this.startY = this.moveY

            this.styleObj = `transform: scale(${this.multiples}) rotateZ(${this.deg}deg);left:${this.endX}px;top:${this.endY}px`;
            console.log(99999, this.styleObj);  
            
            // 阻止屏幕滚动的默认行为
            e.preventDefault()

           
        }

       
    },

    limitScope(e){
        if(this.endX < 0){
            this.endX = 0
        }

        if(this.endY < 0){
            this.endY = 0
        }

        if(e == '1'){
            if(this.endX > 210){
                this.endX = 210
            }

            if(this.endY > 240){
                this.endY = 240
            }
        }else if(e == '2_1'){
            if(this.endX > 48){
                this.endX = 48
            }

            if(this.endY > 250){
                this.endY = 250
            }
        }
    },

}

}

CSS:

#look-image {
   /*  position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%); */
    /* width: 858px;
    height: 768px;
    background-color: #fefefe;
    border-radius: 10px;
    border: 1px solid #c5c5c5;
    overflow: hidden;
    z-index: 99; */
    width: 100%;
    height: 100%;

    .look-image-content {
        width: 100%;
        height: 100%;

        .show-image {
           /*  margin: 44px 148px 74px;
            height: 539px;
            width: 562px;
            position: relative;
            overflow: hidden; */
           
            img {
                width: 100px;
                height: auto;
                position: absolute;
                top: 30%;
                left: 30%;
          
            }
        }
    }
    .look-image-footer {
        display: flex;
       /*  height: 110px;
        line-height: 110px; */
        position: absolute;
        bottom: 0;
        width: 100%;
        justify-content: space-between;
        height: 30px;
        border:1px solid #fff;
        >div {
            width: 50%;
            text-align: center;
            color: #fff;
            background: rgb(38 32 32 / 12%);
            display: flex;
            align-items: center;
            justify-content: center;
        }

        div:nth-child(1){
            border-right: 1px solid #fff;
        }

        div{
            img{
                height: 20px;
            }
        }
    }
}