要实现类似思维导图的效果,可以使用 HTML5 的 canvas 元素来绘制节点和连线。具体实现步骤如下:

  1. 创建 canvas 元素,并设置其宽高。可以使用 CSS 样式或 JavaScript 动态设置。
  2. 定义节点对象。节点包括位置、大小、颜色、文字等属性。可以使用 JavaScript 的类或对象来实现。
  3. 定义连线对象。连线包括起点、终点、线型、颜色等属性。可以使用 JavaScript 的类或对象来实现。
  4. 编写绘制函数。绘制函数根据节点和连线的属性,使用 canvas 的 2D 绘图 API 来绘制图形。
  5. 实现节点的拖拽、放缩、添加、删除等操作。可以使用 JavaScript 的事件处理函数来实现。
  6. 最后,将绘制函数和事件处理函数绑定到 canvas 元素上,就可以实现类似思维导图的效果了。

示例代码

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <title>Canvas Mind Map</title>
    <style>
        canvas {
            width: 600px;
            height: 400px;
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id='myCanvas'></canvas>
    <script>
        const canvas = document.getElementById('myCanvas');
        const ctx = canvas.getContext('2d');

        // 定义节点对象
        class Node {
            constructor(x, y, width, height, color, text) {
                this.x = x;
                this.y = y;
                this.width = width;
                this.height = height;
                this.color = color;
                this.text = text;
            }

            draw() {
                ctx.fillStyle = this.color;
                ctx.fillRect(this.x, this.y, this.width, this.height);
                ctx.fillStyle = '#fff';
                ctx.fillText(this.text, this.x + this.width / 2, this.y + this.height / 2);
            }

            contains(x, y) {
                return x >= this.x && x <= this.x + this.width && y >= this.y && y <= this.y + this.height;
            }
        }

        // 定义连线对象
        class Line {
            constructor(startX, startY, endX, endY, color) {
                this.startX = startX;
                this.startY = startY;
                this.endX = endX;
                this.endY = endY;
                this.color = color;
            }

            draw() {
                ctx.beginPath();
                ctx.moveTo(this.startX, this.startY);
                ctx.lineTo(this.endX, this.endY);
                ctx.strokeStyle = this.color;
                ctx.stroke();
            }
        }

        // 创建节点和连线数组
        const nodes = [];
        const lines = [];

        // 添加节点和连线示例
        const node1 = new Node(100, 100, 80, 40, '#f00', 'Node 1');
        const node2 = new Node(300, 100, 80, 40, '#0f0', 'Node 2');
        const line1 = new Line(node1.x + node1.width, node1.y + node1.height / 2, node2.x, node2.y + node2.height / 2, '#00f');
        nodes.push(node1, node2);
        lines.push(line1);

        // 绘制函数
        function draw() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            lines.forEach(line => line.draw());
            nodes.forEach(node => node.draw());
        }

        // 事件处理函数
        let dragging = false;
        let resizing = false;
        let startX, startY, nodeIndex, resizingIndex;

        canvas.addEventListener('mousedown', function(e) {
            startX = e.offsetX;
            startY = e.offsetY;
            nodeIndex = nodes.findIndex(node => node.contains(startX, startY));
            resizingIndex = nodes.findIndex(node => startX >= node.x + node.width - 5 && startX <= node.x + node.width + 5 && startY >= node.y + node.height - 5 && startY <= node.y + node.height + 5);
            if (nodeIndex !== -1) {
                dragging = true;
            } else if (resizingIndex !== -1) {
                resizing = true;
            }
        });

        canvas.addEventListener('mousemove', function(e) {
            if (dragging) {
                const node = nodes[nodeIndex];
                node.x += e.offsetX - startX;
                node.y += e.offsetY - startY;
                startX = e.offsetX;
                startY = e.offsetY;
                draw();
            } else if (resizing) {
                const node = nodes[resizingIndex];
                node.width += e.offsetX - startX;
                node.height += e.offsetY - startY;
                startX = e.offsetX;
                startY = e.offsetY;
                draw();
            }
        });

        canvas.addEventListener('mouseup', function(e) {
            dragging = false;
            resizing = false;
        });

        canvas.addEventListener('dblclick', function(e) {
            const newNode = new Node(e.offsetX, e.offsetY, 80, 40, '#000', 'New Node');
            nodes.push(newNode);
            draw();
        });

        // 初始化绘制
        draw();
    </script>
</body>
</html>

注意:

  • 以上代码仅供参考,你可以根据自己的需求进行修改和扩展。
  • 代码中使用了 JavaScript 的事件处理函数来实现拖拽、缩放、添加和删除操作,你也可以使用其他方法来实现。
  • 为了方便理解,代码中没有添加对连线操作的实现,你可以参考节点操作的实现来实现连线操作。
  • 你可以在代码中添加更多功能,例如:
    • 添加对节点文本的编辑功能
    • 添加对节点样式的自定义功能
    • 添加对节点连接线的自定义功能
    • 添加对节点布局的控制功能
Canvas 思维导图:实现节点拖拽、缩放、添加和删除

原文地址: https://www.cveoy.top/t/topic/mU4V 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录