写点什么

如何使用 SVG 制作沿任意路径排布的文字效果

  • 2022 年 7 月 17 日
  • 本文字数:2633 字

    阅读完需:约 9 分钟

前言

记得之前有段时间罗盘时钟特别火,大冰块也跟风写了一个罗盘时钟的 demo ,其中环形的文字大冰块使用了 transform 来制作。制作过程中,大冰块发现使用纯 css 实现文字沿指定路径排列的效果会显得特别复杂,如果路径发生了变化,就需要要改很多 css 属性来适应路径变化。


在这时候,SVG 的优势就凸显了出来,因为 SVG 原生支持以任意路径排列的文字,不只是环形,还有三角形、平行四边形等任意花里胡哨的形状路径都可以支持。


那么今天,来跟大冰块一起来复习一下 SVG 生成沿任意路径排布的文字 的问题吧~



SVG的基础知识

什么是SVG

  1. SVG 指可伸缩矢量图形 (Scalable Vector Graphics),在放大或改变尺寸的情况下其图形质量不会有所损失。

  2. SVG 使用 XML 格式定义图形,用来定义用于网络的基于矢量的图形。

  3. SVG 是万维网联盟的标准,与诸如 DOMXSL 之类的 W3C 标准是一个整体。

<path>路径元素

<path> 元素是用来定义形状的通用元素,理论上,我们可以用 <path> 元素来定义的任何路径。


我们来看一下 <path> 元素的某些基本操作:


  • M:将笔移动到指定点 x,y 而不绘图。

  • a:从当前点到点 x,y 绘制一个椭圆弧。

  • z:通过从当前点到第一个点画一条线来封闭路径。

viewBox属性

viewBox(视图框) 属性用来定义 <svg> 所占的空间大小。两个坐标定义元素左上角的用户坐标,后两个坐标定义右下角的用户坐标。

<svg> 所占的空间大小就是 ViewBox 左上坐标到右下坐标的空间。


如果我们给 SVG 设置 width:500px; height:500px; viewBox="0 0 50 20" 在这种情况下, 视图框(ViewBox) 从(0,0)处开始,并且 100 宽,100 高。也就是说,500 x 500 像素的 <svg> 元素,在内部使用从(0,0)到(100,100)的坐标系,相当于它被分成了 100*100 个单元格。所以当前 SVG 形状坐标中的每 1 个单位对应宽度为:500/100 = 5 像素,高度为:500/100 = 5 像素。


如果此时我们给这个 SVG 内部某元素设置 x="10" y="10" width="20" height="20" ,则表示这个元素距离 SVG 元素的上面 50px ,左边 50px ,宽为 100px ,高也是 100px


掌握了上面的知识,下面我们尝试用 path 绘制一个圆形路径:


<style>    .box {        width: 200px;        height: 200px;    }</style>
<div class="box"> <svg viewBox="0 0 100 100"> <path d="M0, 50 a50, 50 0 1, 1 0, 1z"></path> </svg><div>
复制代码


如下图所示:



使用 <textPath> 让文本沿路径排布

<textpath> 元素用于沿路径(例如,圆形)排列文本。<text> 元素用于在 SVG 图像中绘制文本。


我们可以使用一个 <textPath> 元素来包裹住这段文本,并通过 xlink:href="#xxx" 属性来把它链接到 IDxxx<path> 定义路径的元素。字体的样式可以继承自外层的元素,所以不用单独给文本设置字体样式。然后我们再把 <textPath> 放在 <text> 元素中:


<style>    body {        background-color: #b0b0b0;    }
.box { width: 200px; height: 200px; margin: 50px; background-color: #fff; }</style>
<div class="box"> <svg viewBox="0 0 100 100"> <path d="M0,50 a50,50 0 1,1 0,1z" id="circle" ></path> <text> <textPath xlink:href="#circle">这是围绕路径生成的环形文字~</textPath> </text> </svg><div>
复制代码


如下图所示:



从上图可以看到两个问题:


  • 1,圆形路径被默认的黑色填充了。

  • 2,SVG 实际宽高继承自 .box 盒子,宽高均为 200px,而文字溢出部分被隐藏了。


解决方式如下:


  • 1,我们可以把 <path> 元素的 fill 设置为 fill: none; ,这样,圆形路径的背景就是透明的了。

  • 2,给 SVG 设置 overflow: visible; ,这样,超出 SVG 部分的文字就不会被隐藏了。


增加 css 代码如下:


.box svg {    overflow: visible;}.box path {     fill: none; }
复制代码


如下图所示:


完美!



制作沿任意路径排布的文字效果

有了上面的经验,我们把 <path> 元素的路径调整一下,比如可以使用SVG在线编辑器来制作 path 路径。然后我们给文字添加颜色渐变效果,字间距调整一下试试看:


    <style>        .box {            width: 200px;            height: 200px;            margin: 50px;            font-size: 12px;            letter-spacing: 2px;        }        .box svg {            overflow: visible;        }        .box path {             fill: none;         }    </style>    <div class="box">        <svg viewBox="0 0 100 100">            <path d="m36.04045,45.99612c0.72238,0 18.78177,-17.27891 34.67404,-2.30385c15.89227,14.97505 -2.06122,51.71385 -33.12338,49.40999c-31.06217,-2.30385 -51.39459,-47.6821 -23.94431,-74.17643c27.45028,-26.49433 76.46594,-21.1417 90.427,-2.34993c13.96106,18.79177 9.22214,37.08444 7.59483,52.18238c-1.62731,15.09794 5.01952,28.13002 23.57052,28.88256c18.551,0.75254 68.69884,1.13642 61.38299,-46.48421" fill-opacity="null" id="circle" ></path>            <linearGradient id="myLinearGradient" x1="0%" y1="0%" x2="100%" y2="0%">                <stop offset="0%" stop-color="red"></stop>                <stop offset="15%" stop-color="orange"></stop>                <stop offset="30%" stop-color="yellow"></stop>                <stop offset="45%" stop-color="green"></stop>                <stop offset="60%" stop-color="cyan"></stop>                <stop offset="80%" stop-color="blue"></stop>                <stop offset="100%" stop-color="purple"></stop>            </linearGradient>            <text fill="url(#myLinearGradient)">                <textPath xlink:href="#circle">如何使用SVG制作沿任意路径排布的文字效果~来跟大冰块一起来复习一下吧~</textPath>            </text>        </svg>    </div>
复制代码


如下图所示:


制作完成!是不是很简单呢?轻轻松松又掌握了一个小知识点~


后记

SVG 的内容其实不多,花一天的时间基本就能全部看明白了,除了 <path>元素 的绘制实在太复杂之外,其他元素和属性还都是比较容易让人接受的。我们不必去费尽心思领悟 SVG <path>元素 语法的神秘魅力,反正即使学会了也会在几分钟内忘得一干二净【手动狗头】。学一下根据路径排列文字的方法还是很有用的,毕竟这个样式在设计图中也是会用到的~

发布于: 刚刚阅读数: 4
用户头像

还未添加个人签名 2022.07.01 加入

还未添加个人简介

评论

发布
暂无评论
如何使用SVG制作沿任意路径排布的文字效果_7月月更_南极一块修炼千年的大冰块_InfoQ写作社区