SVG实战:实现港珠澳大桥logo

2022-03-15 08:12:55 浏览数 (1)

SVG在网页中被大量应用,因为svg能大大减小网页请求的数据量,节省带宽,尤其是各种格式化的管理平台,包含大量的图表和图标,这些图表和图标都是可以svg化的。

由于网上找不到港珠澳logo的原始矢量图,光栅图也只剩下很模糊的版本了,所以教大家用svg矢量图动手实现一个,反正也不复杂。SVG在计算机矢量图形学领域中是扛把子的地位,制造业各种图纸都有svg的身影。SVG主要有以下特点:

  • 支持各种基本矢量图形、 Bézier曲线
  • 以矢量格式存储,体积巨小,放大不失真
  • 可联动html、CSS、JavaScript
  • 可插拔、可扩展、可复用、可抽象、可继承、可分离

我们知道,浏览器生态是整个软件行业最大的生态,SVG语法和语义上是html的一个子集,也属于DOM规范,所以能被css渲染,也能被javascript操作,SVG兼容浏览器生态大大提升了svg的可用性,也提升了它在行业中的地位。svg叫做scalable vector graphics,可缩放的矢量图,顾名思义,svg放大不失真,这是相对于光栅图(位图)的优势,而且所需存储的体积巨小。svg支持各种基本的图元,包括点、线、面、体各种维度上的基本图形元素,尤其是Bézier曲线。

应该能感觉到,哪儿都有Bézier曲线(贝塞尔曲线)的身影,为何它这么流行呢,为什么在所有的曲线中唯独Bézier曲线占据了图形学的半壁江山?难免让我们对它产生了浓厚的兴趣,为此,我还专门研究了一下Bézier曲线:Bézier曲线是最常用的矢量曲线,因其简单、轻量、自然、平滑的特点而被广泛使用。Bézier曲线能够用最少的控制点表示任意一段光滑的曲线,虽然做不到100%精确,但能满足绝大部分场景。

Bézier曲线本质上是多项式方程,而生活中大部分看到的曲线都可以近似为一个多项式曲线,因此Bézier曲线几乎能表示所有常见的曲线,虽然不能完全精确表示(毕竟只存储了几个点的坐标,表示的信息量有限),但对于民用产品非常方便,因此Bézier曲线才得以流行开来。

  • SVG代码编辑器:VScode
  • 矢量图形编辑器:boxy-svg.com
  • 半透明窗口蒙版:nomacs

因为svg是基于xml的文本格式,用vscode来编辑再合适不过了,除此之外,还需要一款可视化的编辑工具,当然矢量界有无数款软件,这里选用一款PWA在线应用:boxy-svg。除此之外,还需要一款能够将光栅图置顶并半透明化,这样才能将svg和jpg对齐叠在一起操作,这里推荐一款叫做nomacs的Windows平台的软件,它有如下功能:将光栅图(jpg)置于所有窗口顶层(但不聚焦),将图片半透明化,这样可看到聚焦的app(boxy-svg)。

分析一下港珠澳logo,其实就是由“2撇1捺”3个色块组成:黑青渐变、黄绿渐变、橘色。它们的边缘包括直线、二次曲线、三次曲线。三次曲线比二次曲线多了一个控制点,能够表示更弯曲的曲线。

一开始现在vscode中设定所有的这些点,包括3个<path>元素和2个<linearGradient>元素,分别代表3个色块和2个渐变,点的位置以及渐变的程度统统放在boxy-svg中微调,同时利用nomacs调整到最佳位置。最终的代码如下:

代码语言:javascript复制
<svg viewBox="75.646 128.536 345.633 270.603" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <linearGradient gradientUnits="userSpaceOnUse" x1="243.933" y1="161.482" x2="243.933" y2="360.324" id="b" gradientTransform="matrix(-.89488 .4463 -1.02686 -2.05892 782.409 736.874)">
      <stop offset="0"/>
      <stop offset="1" style="stop-color:#00d5ff"/>
    </linearGradient>
    <linearGradient gradientUnits="userSpaceOnUse" x1="380.411" y1="96.752" x2="380.411" y2="439.753" id="a" gradientTransform="matrix(-1 0 0 -1.21975 482.424 548.218)">
      <stop offset="0" style="stop-color:#f7ff00"/>
      <stop offset="1" style="stop-color:#15ff00"/>
    </linearGradient>
  </defs>
  <path style="fill:#ffb300" d="m301.08 129.561 57.196 46.125c-17.22 186.142-134.071 197.417-134.071 197.417s114.586-84.096 76.875-243.542Z"/>
  <path style="stroke-width:0;fill:url(#a)" d="m134.407 288.817.661 109.234c41.679-37.559 108.503-136.053 110.386-248.595 1.885-112.636-43.352-93.112-43.352-93.112s35.317-3.726 31.757 71.141c-2.318 48.737-55.252 155.605-99.452 161.332Z" transform="rotate(-90 277.899 255.488)"/>
  <path style="fill:url(#b)" d="m161.415 230.175-31.473-67.031c99.726-17.99 212.989 33.916 230.884 84.34 38.057 107.237-32.039 112.84-32.039 112.84s66.869-40.637 4.03-105.684c-34.362-35.569-102.873-46.742-171.402-24.465Z" transform="rotate(90 218.054 220.221)"/>
</svg>

0 人点赞