• js图片拖拽、缩放、添加图层功能(原创)


    最近项目中完成的需求,仿百度地图中的功能:

    要求:1.底层图可以拖拽、缩放。

          2.拖拽一个图标,在底层图上对应位置添加一个标注点,该标注点位置要随底层图移动。

       3.添加的标注点,可以拖动,删除。

    主要知识点和难点就是各个浏览器的点击、拖拽、缩放事件兼容性,对js运动属性、运动偏移位置的了解,以及js面向对象的应用。

    这里跟大家分享一下完成后的代码。

    html代码主要知识点就是运动元素和底层元素的相对绝对定位,css代码不再贴出:

    <div id="warp" style="position: relative; 100%;height: 100%;background: #d7d7d7;">
    		<img title="拖动" class="dragImg" id="dragImg" src="images/video_16px_566474.png">
    		<div class="dragAble bgDiv" id="block1" style="zoom:1;">
    			<img id="wheelImg" src="images/photo2FDIB963M30AI20009NOS.jpg" style="zoom:1;" title="底层图片">
    			<p>这段文字跟着div一起运动</p>
    		</div>
    </div>
    

     js代码,初始化:

     1 var clearSlct = "getSelection" in window ? function() {
     2                 window.getSelection().removeAllRanges();
     3             } : function() {
     4                 document.selection.empty();
     5             };
     6             $(window).on("mouseup keyup", function() {
     7                 clearSlct();
     8             });
     9             document.getElementById('warp').oncontextmenu = function(e){
    10                 e.preventDefault();
    11                };
    12             var dragDemo=new dragImg('block1','dragImg','wheelImg');
    View Code

    js代码,构造器+原型链进行面向对象开发:

    function dragImg(bgDivId, imgId, bgImgId) {
        this.disX = 0;
        this.disY = 0; //初始点击点
    
        this.xx = 0;
        this.yy = 0; //点击点相对于button的左上角的距离left,top
    
        this.marginX = 0;
        this.marginY = 0; //运动后底层图偏移量
    
        this.isdrag = false;
        this.clicky = 0;
        this.clickx = 0; //初始点击点
        this.oDragObj = null; //操作对象
    
        this.init(bgDivId, imgId);
        this.initBgDiv(bgDivId);
        this.initMouseWheel(bgImgId);
    }
    
    dragImg.prototype = {
        init: function(bgDivId, imgId) { //图标拖拽
            dragImg.imgId = imgId;
            dragImg.bgDivId = bgDivId;
            var drag_Img = document.getElementById(imgId),
                bg_div = document.getElementById(bgDivId);
            drag_Img.addEventListener('mousedown', dragDownEvent, false);
            drag_Img.addEventListener('mouseup', dragUpEvent, false);
    
            function dragDownEvent(e) {
                $('.dragBtnSpan').remove();
                var oevent = e || e.event;
                if(oevent.button == 0) {
                    var layerX = oevent.offsetX || oevent.layerX,
                        layerY = oevent.offsetY || oevent.layerY;
    
                    dragImg.disX = oevent.clientX - drag_Img.offsetLeft;
                    dragImg.disY = oevent.clientY - drag_Img.offsetTop;
    
                    dragImg.xx = oevent.clientX - drag_Img.offsetLeft;
                    dragImg.yy = oevent.clientY - drag_Img.offsetTop;
                    document.onmousemove = dragMoveEvent;
                }
            }
    
            function dragMoveEvent(e) {
                var oevent = e || e.event;
                var x = oevent.clientX,
                    y = oevent.clientY;
                var offsetx = x - dragImg.disX,
                    offsety = y - dragImg.disY;
                //                console.log(offsetx,offsety);
                if(offsetx < 0) {
                    offsetx = 0;
                } else if(offsetx > document.documentElement.clientWidth - drag_Img.offsetWidth) {
                    offsetx = document.documentElement.clientWidth - drag_Img.offsetWidth;
                }
                if(offsety < 0) {
                    offsety = 0;
                } else if(offsety > document.documentElement.clientHeight - drag_Img.offsetHeight) {
                    offsety = document.documentElement.clientHeight - drag_Img.offsetHeight;
                }
                $("#" + dragImg.imgId).css('left', offsetx);
                $("#" + dragImg.imgId).css('top', offsety);
            }
    
            function dragUpEvent(e) {
                //拖拽结束,判断是否在允许放置的范围内(当前位置是否与底层图相交)
                var oevent = e || e.event;
                if(oevent.button == 0) {
                    $('.dragBtn').remove();
                    var x = oevent.clientX,
                        y = oevent.clientY;
                    var zoom = bg_div.style.zoom; //缩放比例
                    var btn_X = drag_Img.offsetLeft,
                        btn_Y = drag_Img.offsetTop,
                        btn_width = drag_Img.offsetWidth * zoom,
                        btn_height = drag_Img.offsetHeight * zoom,
                        //缩放后长度,位置都会发生变化,需要*缩放倍率
                        map_X = bg_div.offsetLeft * zoom,
                        map_Y = bg_div.offsetTop * zoom,
                        map_left = bg_div.style.left,
                        map_top = bg_div.style.top,
                        map_width = bg_div.offsetWidth * zoom,
                        map_height = bg_div.offsetHeight * zoom;
                    var m = (btn_X + dragImg.xx > map_X + map_width) || (btn_X + dragImg.xx + btn_width < map_X);
                    var n = (btn_height + btn_Y + dragImg.yy < map_Y) || (btn_Y + dragImg.yy > map_Y + map_height);
                    if(m || n) {
                        console.log('相离');
                    } else {
                        //缩放后位置会偏移
                        var yesIE = IEVersion();
                        if(yesIE != -1) {
                            //ie浏览器获取的就是实际偏移量,需要清除缩放倍率
                            if(yesIE > 8 || yesIE == 'Edge') {
                                dragImg.marginX = bg_div.offsetLeft;
                                dragImg.marginY = bg_div.offsetTop;
                            }
                        } else {
                            dragImg.marginX = map_X,
                            dragImg.marginY = map_Y;
                        }
                        var percentX = (x - dragImg.marginX - dragImg.xx) / zoom;
                        var percentY = (y - dragImg.marginY - dragImg.yy) / zoom;
                        //                console.log('percentXxxxx',percentX);
                        //                console.log('percentYyyyy',percentY);
                        LONG=percentX;//选定坐标点,赋值全局变量
                        LAT=percentY;
                        var createImg = document.createElement('img');
                        createImg.src = 'resources/images/point_easyicon.png';
                        createImg.style.left = percentX + 'px';
                        createImg.style.top = percentY + 'px';
                        var btnId = 'btn_' + parseInt(percentX) + "_" + parseInt(percentY);
                        createImg.setAttribute('id', btnId);
                        createImg.setAttribute('class', 'dragBtn');
                        bg_div.appendChild(createImg);
                        $("#" + btnId).on('mousedown', function(event) {
                            if(event.button == 2) {
                                $('.dragBtnSpan').remove();
                                var dragBtnSpan = document.createElement('ul');
                                var htm = '<li><a href="javascript:(0);" onclick="alert(123);">移动</a></li><li><a href="javascript:(0);" onclick="alert(456);">删除</a></li>';
                                dragBtnSpan.innerHTML = htm;
                                dragBtnSpan.setAttribute('id', btnId + 'ul');
                                dragBtnSpan.setAttribute('class', 'dragBtnSpan');
                                bg_div.appendChild(dragBtnSpan);
                                $('#' + btnId + 'ul').css('left', percentX + 10).css('top', percentY + 10).show();
                            }
                        });
                        $("#dragImg").css('left', 10);
                        $("#dragImg").css('top', 10);
                    }
                    document.onmousemove = null;
                }
            }
        },
        initBgDiv: function(bgDivId) { //底层图拖拽
            dragImg.bgDivId = bgDivId;
            var bg_div = document.getElementById(bgDivId);
            bg_div.addEventListener('mousedown', initDrag, false);
            document.onmouseup = new Function("dragImg.isdrag=false");
    
            function initDrag(e) {
                if(e.button == 0) {
                    var nn6 = document.getElementById && !document.all;
                    var oDragHandle = nn6 ? e.target : event.srcElement;
                    var topElement = "HTML";
                    while(oDragHandle.tagName != topElement && oDragHandle.className.indexOf("dragAble") == -1) {
                        oDragHandle = nn6 ? oDragHandle.parentNode : oDragHandle.parentElement;
                    }
                    if(oDragHandle.className.indexOf("dragAble") != -1) {
                        dragImg.isdrag = true;
                        dragImg.oDragObj = oDragHandle;
                        nTY = parseInt(dragImg.oDragObj.style.top + 0); //当前初始位置
                        dragImg.clicky = nn6 ? e.clientY : event.clientY; //点击位置
                        nTX = parseInt(dragImg.oDragObj.style.left + 0);
                        dragImg.clickx = nn6 ? e.clientX : event.clientX;
                        // oDragObj.style.zIndex++;
                        document.onmousemove = moveMouse;
                        return false;
                    }
                }
            }
    
            function moveMouse(e) {
                if(dragImg.isdrag) { //初始位置+运动长度-点击时位置
                    var oevent = e || window.event;
                    var clientX = oevent.clientX,
                        clientY = oevent.clientY;
                    var moveX = nTX + clientX - dragImg.clickx,
                        moveY = nTY + clientY - dragImg.clicky;
                    dragImg.oDragObj.style.top = moveY + "px";
                    dragImg.oDragObj.style.left = moveX + "px";
                    return false;
                }
            }
    
        },
        initMouseWheel: function(bgImgId) { //底层图鼠标滚轮缩放
            var bg_img = document.getElementById(bgImgId);
            //        if (document.addEventListener) {
            bg_img.addEventListener('mousewheel', onWheelZoom, false); //IE9, Chrome, Safari, Oper
            //            bg_img.addEventListener('wheel', onWheelZoom, false); //Firefox
            //            bg_img.addEventListener('DOMMouseScroll', onWheelZoom, false); //Old Firefox
            //        } else {
            //            bg_img.attachEvent('onmousewheel', onWheelZoom); //IE 6/7/8
            //        }
            function onWheelZoom(e) {
                $('.dragBtnSpan').remove();
                var obj = e.srcElement ? e.srcElement : e.target;
                var parentNode = obj.parentNode || obj;
                zoom = parseFloat(parentNode.style.zoom); //操作行内样式zoom,行内必须有zoom属性,不支持firefox
                var wheelDelta = event.wheelDelta || event.deltaY;
    
                tZoom = zoom + (wheelDelta > 0 ? 0.1 : -0.1);
                if(tZoom < 0.5) {
                    return true;
                }
                parentNode.style.zoom = tZoom;
                return false;
            }
        },
        getPosition: function(node) {
            var left = node.offsetLeft; //获取元素相对于其父元素的left值var left
            var top = node.offsetTop;
            current = node.offsetParent; // 取得元素的offsetParent
              // 一直循环直到根元素
              
            while(current != null) {  
                left += current.offsetLeft;  
                top += current.offsetTop;  
                current = current.offsetParent;  
            }
            return {
                "left": left,
                "top": top
            };
        }
    }
    View Code

    由于ie8和火狐需要更多的兼容性考虑,时间关系就没有支持ie8和火狐。

    function IEVersion() {
        var version = -1;
        var userAgent = navigator.userAgent;
        var isIE = userAgent.indexOf('compatible') > -1 && userAgent.indexOf('MSIE') > -1;
        var isEdge = userAgent.indexOf('Edge') > -1 && !isIE;
        var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf('rv:11.0') > -1;
        if(isIE) {
            if(userAgent.indexOf("MSIE 5.5") > 0) {
                version = 5.5;
            } else if(userAgent.indexOf("MSIE 6.0") > 0) {
                version = 6;
            } else if(userAgent.indexOf("MSIE 7.0") > 0) {
                version = 7;
            } else if(userAgent.indexOf("MSIE 8.0") > 0 || (userAgent.indexOf("MSIE 9.0") > 0 && !window.innerWidth)) {
                version = 8;
            } else if(userAgent.indexOf("MSIE 9.0") > 0) {
                version = 9;
            } else {
                version = 10;
            }
        } else if(isEdge) {
            version = 'Edge';
        } else if(isIE11) {
            version = 11;
        } else {
            version = -1;
        }
        return version;
    }
    View Code

    代码写的都很简单,关键位置都有注释,各位不要见笑。

  • 相关阅读:
    2019牛客暑期多校训练营(第二场)H Second Large Rectangle
    HDU -1506 Largest Rectangle in a Histogram&&51nod 1158 全是1的最大子矩阵 (单调栈)
    吉哥系列故事——完美队形II(马拉车算法)
    Theme Section
    激光雷达和毫米波雷达
    模型压缩95%:Lite Transformer,MIT韩松等人
    分布式深度学习DDL解析
    TOF摄像机可以替代Flash激光雷达吗?
    毫米波雷达分类和技术方案
    高精地图与自动驾驶(下)
  • 原文地址:https://www.cnblogs.com/cm1236/p/9640628.html
Copyright © 2020-2023  润新知