Recently, in order to establish geometric intuition in linear algebra, I tried to step on the map pit: some boundary lines are not drawn, please do not outline the line. Data from Ali datav, please download, link.js internal vector data reference for the current variety can be.

Support mouse wheel zoom, drag and move (please ignore small problems, displacement drag bug, if there is a solution, please leave a message below).

Cut the crap and get right to the code.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        html,body{
            width: 100%;
            height: 100%;
            padding: 0;
            margin: 0;
        }
    </style>
    <script src="../rxjs.umd.js"></script>
    <script src="link.js"></script>
    <script>
        let dip = 3;
        let startX = 0;
        let startY = 0;
        let endX = 0;
        let endY = 0;
        function draw() {
            const canvas = document.getElementById('canvas');
            let windowGlobalSize = getWindowSize();
            canvas.width = windowGlobalSize.width;
            canvas.height = windowGlobalSize.height;
            setTimeout(() => {
                setRect(canvas);
            }, 1000);

            window.addEventListener('resize', () => {
                setTimeout(() => {
                    let windowGlobalSize = getWindowSize();
                    canvas.width = windowGlobalSize.width;
                    canvas.height = windowGlobalSize.height;
                    setRect(canvas);
                }, 1000);
            })
            window.addEventListener('mousewheel', (event) => {
                if (event.wheelDelta > 0) {
                    dip++;
                    let windowGlobalSize = getWindowSize();
                    canvas.width = windowGlobalSize.width;
                    canvas.height = windowGlobalSize.height;
                    setRect(canvas);
                } else {
                    if (dip > 1) {
                        dip--;
                    }
                    let windowGlobalSize = getWindowSize();
                    canvas.width = windowGlobalSize.width;
                    canvas.height = windowGlobalSize.height;
                    setRect(canvas);
                }
            });

            const mouseDown = rxjs.fromEvent(canvas, "mousedown");
            const mouseUp = rxjs.fromEvent(document, "mouseup");
            const mouseMove = rxjs.fromEvent(document, "mousemove");

            let isMove = false;
            mouseDown
                .pipe(
                    rxjs.map((e) => {
                        return {
                            x: e.pageX,
                            y: e.pageY
                        };
                    })
                ).subscribe(e => {
                    if (!isMove) {
                        startX = e.x;
                        startY = e.y;
                        isMove = true;
                    }
            })

            mouseUp
                .pipe(
                    rxjs.map((e) => {
                        return {
                            x: e.pageX,
                            y: e.pageY
                        };
                    })
                ).subscribe(e => {
                startX = e.x - endX;
                startY = e.y - endY;
            })

            mouseDown
                .pipe(
                    rxjs.switchMap(e => {
                        return mouseMove.pipe(rxjs.takeUntil(mouseUp))
                    }),
                    rxjs.map((e) => {
                        return {
                            x: e.pageX,
                            y: e.pageY
                        };
                    })
                )
                .subscribe(e => {
                    endY = e.y - startY
                    endX = e.x - startX
                    let windowGlobalSize = getWindowSize();
                    canvas.width = windowGlobalSize.width;
                    canvas.height = windowGlobalSize.height;
                    setRect(canvas);
                })
        }

        function setRect(canvas) {

            // 当前画布宽度
            const width = canvas.width;
            // 当前画布高度
            const height = canvas.height;
            // 当前X轴原点处于Y轴位置
            const x = height / 2;
            // 当前Y轴原点处于X轴位置
            const y = width / 2;
            const ctx = canvas.getContext('2d');
            ctx.fillStyle = 'rgba(0,0,0,.3)'
            ctx.fillRect(0, 0, width, height);
            setColY(ctx, x, width, height);
            setRowX(ctx, y, width, height);
            setXY(ctx, x, y, width, height);
            const arrX = []
            const arrY = []
            map.features.forEach(item => {
                let coordinates = item.geometry.coordinates;
                coordinates.forEach(data => {
                    data.forEach(data1 => {
                        if (data1.length > 2) {
                            data1.forEach((data2, i) => {
                                arrX.push(data2[0]);
                                arrY.push(data2[1]);
                            });
                        }
                    });
                });
            });
            const left = Math.min(...arrX);
            const right = Math.max(...arrX);
            const top = Math.min(...arrY);
            const bottom = Math.max(...arrY);
            let movex = (y - ((right + left) / 2));
            let moveY = (x - ((top + bottom) / 2));
            map.features.forEach(item => {
                let coordinates = item.geometry.coordinates;
                coordinates.forEach(data => {
                    data.forEach(data1 => {
                        if (data1.length > 2) {
                            ctx.beginPath();
                            data1.forEach((data2, i) => {
                                let mapX = data2[0] + movex;
                                let mapY = data2[1] + moveY;
                                const valX = mapX - y;
                                const valY = mapY - x;
                                if (valX) {
                                    mapX += (valX * dip)
                                } else {
                                    mapX -= (valX * dip)
                                }
                                if (valY) {
                                    mapY += (valY * dip)
                                } else {
                                    mapY -= (valY * dip)
                                }
                                if (mapY < x) {
                                    mapY = x + (x - mapY)
                                } else {
                                    mapY = x - (mapY - x)
                                }
                                if (i === 0) {
                                    ctx.moveTo(mapX + endX, mapY + endY);
                                }
                                ctx.lineTo(mapX + endX, mapY + endY);
                            });
                            ctx.stroke();
                        }
                    });
                });
            });

        }



        // 绘制X轴刻度线
        function setColY(ctx, x, w, h) {
            /**
             * 当前从那个位置开始画Y轴刻度线
             * @param colYPositive {number} 向正半轴开始绘制
             * @param colYMinus {number} 向负半轴开始绘制
             */
            const obj = {
                colYPositive: x,
                colYMinus: x
            };
            ctx.strokeStyle = 'rgb(213,208,208)'
            ctx.beginPath();
            while (obj.colYPositive > 0) {
                obj.colYPositive = obj.colYPositive - 30;

                ctx.moveTo(0, obj.colYPositive);
                ctx.lineTo(0, obj.colYPositive);
                ctx.lineTo(w, obj.colYPositive);
            }
            while (obj.colYMinus <= h) {
                obj.colYMinus = obj.colYMinus + 30;

                ctx.moveTo(0, obj.colYMinus);
                ctx.lineTo(0, obj.colYMinus);
                ctx.lineTo(w, obj.colYMinus);
            }
            ctx.stroke();

        }

        // 绘制X轴单元格
        function setRowX(ctx, y, w, h) {
            // 当前从那个位置开始画Y轴刻度线
            /**
             * 当前从那个位置开始画Y轴刻度线
             * @param colYPositive {number} 向正半轴开始绘制
             * @param colYMinus {number} 向负半轴开始绘制
             */
            const obj = {
                rowXPositive: y,
                rowXMinus: y
            };
            ctx.strokeStyle = 'rgb(213,208,208)'
            ctx.beginPath();
            while (obj.rowXPositive > 0) {
                obj.rowXPositive = obj.rowXPositive - 30;

                ctx.moveTo(obj.rowXPositive, 0);
                ctx.lineTo(obj.rowXPositive, 0);
                ctx.lineTo(obj.rowXPositive, h);
            }
            while (obj.rowXMinus <= w) {
                obj.rowXMinus = obj.rowXMinus + 30;

                ctx.moveTo(obj.rowXMinus, 0);
                ctx.lineTo(obj.rowXMinus, 0);
                ctx.lineTo(obj.rowXMinus, h);
            }
            ctx.stroke();
        }

        function setXY(ctx, x, y, w, h) {
            ctx.strokeStyle = 'rgb(0,0,0)'
            ctx.beginPath();
            ctx.moveTo(0, x);
            ctx.lineTo(0, x);
            ctx.lineTo(w, x);
            ctx.stroke();
            ctx.strokeStyle = 'rgb(0,0,0)'
            ctx.beginPath();
            ctx.moveTo(y, 0);
            ctx.lineTo(y, 0);
            ctx.lineTo(y, h);
            ctx.stroke();
        }

        function getWindowSize() {
            const width = document.documentElement.clientWidth;
            const height = document.documentElement.clientHeight;
            return {
                width,
                height
            }
        }
    </script>
</head>

<body onload="draw()">
<canvas id="canvas" width="150" height="150"></canvas>
</body>
</html>
Copy the code