【SVG】前端-不依靠第三方包怎么画连线???

如何用SVG实现连线功能

在Web开发中,我们经常会遇到需要在页面上绘制图形或者实现一些图形交互的场景。SVG(Scalable Vector Graphics)作为一种用于描述二维图形的XML标记语言,在这方面提供了极大的便利。本文将以一个具体的例子——如何使用SVG来实现连线功能,来介绍SVG的使用方法。

基本概念

在开始之前,我们先简单了解一下SVG的一些基本概念。SVG允许我们以XML格式定义图形,这意味着你可以直接在HTML文档中嵌入SVG代码。SVG图形是矢量的,这意味着它们可以在不失真的情况下被放大。
示例项目
假设我们有一个需求,需要在一个页面上展示两组方块,然后根据一定的规则用线将它们连接起来。这个场景在实际开发中很常见,比如在展示工作流、组织结构图等场景。

项目结构

我们的项目使用Vue.js框架,并且在一个.vue文件中定义了我们的组件。这个组件的模板部分包含了两组方块和一个用于绘制连线的SVG容器。

<template>
    <div class="container">
        <div class="left">
            <div v-for="(block, index) in leftBlocks" :key="index" class="block">{{ block }}</div>
        </div>
        <div v-if="ready" ref="svg" class="arrows">
            <svg v-if="draw" style="width: 100%;height: 100%;">
                <path v-for="(link, index) in links" :key="index" :d="drawArrow(link)"
                    :stroke="link.type === 'dashed' ? 'blue' : 'black'" stroke-width="2" fill="none"
                    :stroke-dasharray="link.type === 'dashed' ? '5,5' : ''" />
            </svg>
        </div>
        <div class="right">
            <div v-for="(block, index) in rightBlocks" :key="index" class="block">{{ block }}</div>
        </div>
    </div>
</template>

数据和方法

在组件的script部分,我们定义了一些数据和方法。leftBlocks和rightBlocks分别存储左右两组方块的数据。links数组存储了连接信息,包括起点、终点和线条类型(实线或虚线)。
在这里插入图片描述

export default {
    data() {
        return {
            ready: false,
            draw: false,
            leftBlocks: ['A', 'B', 'C'],
            rightBlocks: ['X', 'Y', 'Z'],
            links: [
                { from: 0, to: 1, type: 'solid' },
                { from: 1, to: 2, type: 'dashed' }
            ]
        };
    },
    mounted() {
        this.$nextTick(() => {
            this.ready = true;
            this.$nextTick(()=>{
                this.draw=true;
            });
        });
    },
    methods: {
        drawArrow(link) {
            // 绘制箭头的逻辑
        }
    }
};

绘制连线

drawArrow方法是本示例的核心。它根据传入的连接信息计算出起点和终点的坐标,然后生成一个SVG的path元素的d属性值,这个属性值描述了一条从起点到终点,然后再到箭头两个端点的路径。

drawArrow(link) {
            const svgBox = this.$refs.svg;
            // 假设左侧方块中心为起点,右侧方块中心为终点
            const startX = 0; // 左侧方块中心X坐标
            const startY = 20 + 60 * link.from; // 计算起点Y坐标
            const endX = svgBox.clientWidth; // 右侧方块中心X坐标,考虑到SVG容器的位置
            const endY = 40 + 100 * link.to; // 计算终点Y坐标

            // 箭头头部的大小和角度
            const arrowLength = 10; // 箭头长度
            // const arrowWidth = 5; // 箭头宽度

            // 计算箭头头部的两个点
            const angle = Math.atan2(endY - startY, endX - startX);
            const arrowEnd1X = endX - arrowLength * Math.cos(angle - Math.PI / 6);
            const arrowEnd1Y = endY - arrowLength * Math.sin(angle - Math.PI / 6);
            const arrowEnd2X = endX - arrowLength * Math.cos(angle + Math.PI / 6);
            const arrowEnd2Y = endY - arrowLength * Math.sin(angle + Math.PI / 6);

            // 绘制线条和箭头头部
            return `M${startX},${startY} L${endX},${endY} M${endX},${endY} L${arrowEnd1X},${arrowEnd1Y} M${endX},${endY} L${arrowEnd2X},${arrowEnd2Y}`;
        }

实现效果

通过上述代码,我们可以在页面上绘制出从左侧方块指向右侧方块的连线,并且根据links数组中定义的连接信息,自动调整连线的起点、终点和类型(实线或虚线)。SVG的 元素非常强大,它不仅可以用来绘制直线,还可以绘制曲线、圆形等复杂的图形。

结论

SVG提供了一种非常灵活和强大的方式来在Web页面上绘制和操作图形。通过简单的XML标记,我们可以实现复杂的视觉效果,而且由于SVG图形是矢量的,它们在任何分辨率下都能保持清晰。本文通过一个实现连线功能的示例,展示了如何使用SVG来增强Web应用的交互性和视觉效果。希望这篇文章能够帮助你在未来的项目中更好地利用SVG。

扩展阅读

SVG教程
通过结合这些资源,你可以进一步深入了解SVG,从而在你的Web开发项目中创造出更加丰富和动态的用户体验。

  • 24
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现连线的方法有很多种,以下是一种基于 HTML5 Canvas 和 jQuery 的实现方式: 1. 在 HTML 中添加两个 Canvas 标签,一个用于绘制节点,一个用于绘制连线。 2. 使用 jQuery 将节点拖拽到 Canvas 上,并在节点上添加事件监听器,记录节点的位置信息。 3. 在连线 Canvas 上使用 JavaScript 绘制连线,根据节点位置信息计算连线起点和终点的坐标。 4. 如果需要实现动态连线,可以在节点上添加事件监听器,在节点拖拽时实时更新连线位置。 下面是一个简单的示例代码,仅供参考: HTML 代码: ``` <canvas id="node-canvas"></canvas> <canvas id="line-canvas"></canvas> ``` JavaScript 代码: ``` var nodeCanvas = document.getElementById("node-canvas"); var lineCanvas = document.getElementById("line-canvas"); var nodeCtx = nodeCanvas.getContext("2d"); var lineCtx = lineCanvas.getContext("2d"); var nodes = []; // 保存节点信息的数组 // 监听节点的mousedown事件,记录节点位置信息 $("#node-canvas").on("mousedown", function(e) { var offsetX = e.offsetX; var offsetY = e.offsetY; var newNode = { x: offsetX, y: offsetY }; nodes.push(newNode); }); // 监听节点的mouseup事件,绘制连线 $("#node-canvas").on("mouseup", function(e) { var offsetX = e.offsetX; var offsetY = e.offsetY; var lastNode = nodes[nodes.length - 1]; lineCtx.beginPath(); lineCtx.moveTo(lastNode.x, lastNode.y); lineCtx.lineTo(offsetX, offsetY); lineCtx.stroke(); }); // 监听节点的drag事件,实时更新连线位置 $("#node-canvas").on("drag", function(e) { var offsetX = e.offsetX; var offsetY = e.offsetY; var lastNode = nodes[nodes.length - 1]; lineCtx.clearRect(0, 0, lineCanvas.width, lineCanvas.height); lineCtx.beginPath(); lineCtx.moveTo(lastNode.x, lastNode.y); lineCtx.lineTo(offsetX, offsetY); lineCtx.stroke(); }); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值