JavaScript和SVG實現點擊連線


轉載https://www.cnblogs.com/xiaozhuzhuandxiaomoney/p/7570765.html

效果:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>獲取坐標點位置,並連接點</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .svgcontainer, .container {
            position: absolute;
            top: 50%;
            left: 50%;
            margin-left: -400px;
            margin-top: -250px;
            width: 800px;
            height: 500px;
        }

        .container {
            border: 1px solid #ccc;
            cursor: pointer;
        }

        .dot {
            width: 10px;
            height: 10px;
            border-radius: 50%;
            position: absolute;
            background: #0078B6;
            margin-top: -5px;
            margin-left: -5px;
        }
    </style>
</head>
<body>
<div class="svgcontainer" id="svgcontainer"></div>
<div class="container" id="container">
    <div class="dot" style="top: 0px;left: 0px"></div>
</div>
</body>
</html>
<script>
    var timepath;
    var container = document.getElementById("container");
    var svgcontainer = document.getElementById("svgcontainer");
    //創建svg 注:動態創建svg ie8及以下不支持該方法
    var svgns = "http://www.w3.org/2000/svg";
    var svger = document.createElementNS(svgns, "svg");
    svger.setAttribute("width", container.clientWidth);
    svger.setAttribute("height", container.clientHeight);
    svger.setAttribute("viewBox", "0 0 " + container.clientWidth + " " + container.clientHeight);
    svgcontainer.appendChild(svger);

    container.onclick = function (e) {
        var e = e || window.event;//事件對象
        //獲取點擊地鼠標位置
        var mousePosition = mousePos(e);
        //新增點
        creatdot(mousePosition.x, mousePosition.y);
        //連接點
        var dots = container.children;
        linedot(dots[dots.length - 2], dots[dots.length - 1]);
    }

    //位置像素 數值化
    function intpixel(str) {
        return str.substring(0, str.length - 2) * 1;
    }

    //獲取鼠標坐標
    function mousePos(e) {
        if (e.pageX) {
            //IE9及以上支持pageX屬性 相對文檔
            return {x: e.pageX, y: e.pageY}
        } else {
            return {
                x: e.clientX + document.body.scrollLeft - document.body.clientLeft,
                y: e.clientY + document.body.scrollTop - document.body.clientTop
            }
        }
    }

    //新增點
    function creatdot(posX, posY) {
        //相對container坐標
        var newposX = posX - container.offsetLeft;
        var newposY = posY - container.offsetTop;
        var dot = document.createElement("div");
        dot.setAttribute("class", "dot");
        //定位
        dot.style.left = newposX + "px";
        dot.style.top = newposY + "px";
        container.appendChild(dot);
    }

    //連接點
    function linedot(dot1, dot2) {
        clearTimeout(timepath);
        var start = {x: intpixel(dot1.style.left), y: intpixel(dot1.style.top)};
        var end = {x: intpixel(dot2.style.left), y: intpixel(dot2.style.top)};
        var current = {x: start.x, y: start.y};
        //創建直線
        var line = document.createElementNS(svgns, "line");
        line.setAttribute("x1", dot1.style.left);
        line.setAttribute("y1", dot1.style.top);
        line.setAttribute("x2", dot2.style.left);
        line.setAttribute("y2", dot2.style.top);
        line.setAttribute("stroke", "red");
        line.setAttribute("fill", "none");
        svger.appendChild(line);
        //角度
        var tangle = {
            sin: (end.y - start.y) / Math.sqrt((end.y - start.y) * (end.y - start.y) + (end.x - start.x) * (end.x - start.x)),
            cos: (end.x - start.x) / Math.sqrt((end.y - start.y) * (end.y - start.y) + (end.x - start.x) * (end.x - start.x))
        };
        //動畫
        var step = function () {
            //定義每幀移動位移大小為10
            if (Math.abs(current.x - end.x) < 10 && Math.abs(current.y - end.y) < 10) {
                current.x = end.x;
                current.y = end.y;
            } else {
                current.x += 10 * tangle.cos;
                current.y += 10 * tangle.sin;
                timepath = setTimeout(step, 17);//瀏覽器重繪速度為60幀每秒
            }
            line.setAttribute("x2", current.x + "px");
            line.setAttribute("y2", current.y + "px");
        }
        step();
    }
</script>

喵先貼代碼。

一、問題描述

點擊指定區域,mark該點后與緊鄰前面一點連線。初始點在(0,0)。

二、解決思路

點擊指定區域,獲取點擊位置相對document的位置;

計算與指定區域的相對位置;

創建mark點,相對指定區域絕對定位;

創建svg,大小與指定區域相同,層級位於指定區域下方,創建直線line,根據初始位置與結束位置即可得到直線;

連線動畫,每幀畫線確定。

三、注意項

1、動態創建svg  document.creatElementNS方法在IE8及以下報錯,這里可以選擇不動態創建;

2、獲取鼠標先對文檔的坐標,ie9及以上可以直接使用e.pageX,e.pageY,ie8及以下為e.clientX+document.body.scollLeft-document.body.clientLeft;

3、原生js寫內聯樣式注意加“px”;

4、動畫通過setTimeout()繪制(大多數瀏覽器重繪速度為60幀每秒)。定義每幀直線增長的長度,根據角度確定每幀終點的坐標,連線。當某幀坐標點的位置和終點位置距離小於定義每幀增長得長度時,直接將最后一幀的位置確定為終點坐標。 

5、setTimeout()與函數結合構成條件循環。


免責聲明!

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



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