HTML/JavaScript實現地圖以鼠標為圓心縮放和移動


代碼如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }


        #box {
            position: relative;
            width: 1000px;
            height: 400px;
            background-color: rosybrown;
            overflow: hidden;
            left: 50%;
            margin-left: -500px;
            top: 100px;
        }

        #map {
            position: absolute;
        }
    </style>
</head>
<body>
<div id="box">
    <img src="map_test.png" alt="" id="map">
</div>
</body>
<script>
    var box = document.getElementById("box");
    var map = document.getElementById("map");
    var isRun,  // 是否可移動
        startX, // 鼠標落下的位置
        startY,
        endX,   // 鼠標放開的位置
        endY,
        rX,     // 圖片最終的位置(中間量)
        rY,
        scaleSize = 1, // 縮放比例
        bgX = 0, // left   圖片的最終位置
        bgY = 0; // top
    var box_width = parseFloat(window.getComputedStyle(box, false)["width"].slice(0, -2));
    var box_height = parseFloat(window.getComputedStyle(box, false)["height"].slice(0, -2));
    var map_width = parseFloat(window.getComputedStyle(map, false)["width"].slice(0, -2));
    var map_height = parseFloat(window.getComputedStyle(map, false)["height"].slice(0, -2));

    function restart() {
        // 初始設置顯示全部地圖
        var map_w, map_h;
        if (box_width / box_height > map_width / map_height) {
            // 此時以高為基准
            scaleSize = box_height / map_height;
            map_h = box_height;
            map_w = map_width * scaleSize;
            bgX = (box_width - map_w) / 2;
            bgY = 0;
        } else {
            // 此時以寬為基准
            scaleSize = box_width / map_width;
            map_h = map_height * scaleSize;
            map_w = box_width;
            bgX = 0;
            bgY = (box_height - map_h) / 2;
        }
        map.style.height = map_h + "px";
        map.style.width = map_w + "px";
        map.style.top = bgY + "px";
        map.style.left = bgX + "px";
    }

    restart();
    box.onmousedown = function (ev) {
        if (ev.which === 1) {
            // 鼠標左鍵
            isRun = true;
            startX = ev.pageX;
            startY = ev.pageY;
            return false;
        }
        if (ev.which === 2) {
            restart();
            return false;
        }
    };
    box.onmouseup = function (ev) {
        if (ev.which === 1) {
            isRun = false;
            bgX = rX;
            bgY = rY;
        }
        return false;
    };
    box.onmousemove = function (ev) {
        if (ev.which === 1 && isRun) {
            endX = ev.pageX;
            endY = ev.pageY;
            rX = bgX + endX - startX;
            rY = bgY + endY - startY;
            map.style.left = rX + "px";
            map.style.top = rY + "px";
        }
    };
    box.onwheel = function (ev) {
        // 以鼠標為中心縮放

        // 1.記錄鼠標當前位置(相對於window)
        var x = ev.pageX;
        var y = ev.pageY;
        // 2.阻止默認事件
        ev.preventDefault();
        // ev.target  滾輪滑動的目標
        // 3.計算出鼠標相對於地圖的位置
        x = x - box.offsetLeft;
        y = y - box.offsetTop;
        // 4.記錄滾輪的變化值 -100/+100
        var change_scale = -(ev.deltaY) / 1000;
        var current_scale = scaleSize;
        current_scale += change_scale;
        // 5.限制縮放的倍數0.1-10
        current_scale = current_scale < 0.1 ? 0.1 : (current_scale > 10 ? 10 : current_scale);

        // 6.計算出相對於圖片的同樣倍數對應的位移距離
        bgX = bgX - (x - bgX) * (current_scale - scaleSize) / scaleSize;
        bgY = bgY - (y - bgY) * (current_scale - scaleSize) / scaleSize;
        scaleSize = current_scale;

        // 7.更新屬性
        map.style.width = map_width * scaleSize + "px";
        map.style.height = map_height * scaleSize + "px";
        map.style.top = bgY + "px";
        map.style.left = bgX + "px";
        // 注意:要求box標簽的父級標簽不能出現定位屬性,否則會以出現定位屬性的父級為基准計算offset
    }
</script>
</html>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM