内容简介:最近需要在 React-Native 项目里实现一个填满特定图形的效果,找很久都没发现能满足需求的开源库,于是就打算用 SVG 自己怼一个。好在这方面教程还不少,虽然不能一步到位,但几篇文章加一起也能把效果实现出来,于是在这里把入门过程记录一下,希望帮后来者省点功夫。SVG(Scalable Vector Graphics) 是一种基于 XML 语法的图像格式。跟基于像素处理的图片格式不同,它是基于对图像形状的描述来实现的,本质上是一个文本文件,体积上较小,而且在放大的时候也不会失真。因为 SVG 是基于
最近需要在 React-Native 项目里实现一个填满特定图形的效果,找很久都没发现能满足需求的开源库,于是就打算用 SVG 自己怼一个。好在这方面教程还不少,虽然不能一步到位,但几篇文章加一起也能把效果实现出来,于是在这里把入门过程记录一下,希望帮后来者省点功夫。
SVG 是个啥?
SVG(Scalable Vector Graphics) 是一种基于 XML 语法的图像格式。跟基于像素处理的图片格式不同,它是基于对图像形状的描述来实现的,本质上是一个文本文件,体积上较小,而且在放大的时候也不会失真。
因为 SVG 是基于 XML 语法的,所以对于前端开发者来说,写起来应该比较顺手;对于 React-Native 的项目,因为 JSX 的关系,用起 SVG 来也是没有“语言障碍”的。
SVG 长什么样?
直接上源码:
<svg width='100' height="100" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<clipPath id="heart">
<path d="M81.495,13.923c-11.368-5.261-26.234-0.311-31.489,11.032C44.74,13.612,29.879,8.657,18.511,13.923 C6.402,19.539,0.613,33.883,10.175,50.804c6.792,12.04,18.826,21.111,39.831,37.379c20.993-16.268,33.033-25.344,39.819-37.379 C99.387,33.883,93.598,19.539,81.495,13.923z"/>
</clipPath>
</defs>
<rect x='0' y='0' fill='rgb(217,217,217)' width="100%" height="100%" clip-path="url(#heart)" />
<rect x='0%' y="50%" fill='red' width="100%" height="100%" clip-path="url(#heart)" />
</svg>
这张 SVG 图渲染出来是这样的:
直接把上面的代码保存为文本,就可以用浏览器打开并显示了。macOS 的用户还可以直接空格预览。
配合一些参数的改变,做动画也是分分钟的事情。对于之前没有怎么用过 SVG 的我来说,简直是打开了新世界的大门。
接下来就让我们一起探究一下上面这个图是怎么来的。
SVG 显示原理
根据上面的例子,我们可以大胆猜测一下: <path> 标签下 d 属性的值就是用来描绘这个心形的外框路径的。既然描绘路径已经是确定的了,那一张 SVG 图片是怎么实现缩放不失真的特性的呢?
要回答这个问题,就要让我们先了解一下 SVG 的一些基本显示原理。
The SVG Canvas
假设我们要将一个 SVG 图形绘制到一张画布(Canvas)上,概念上这张画布应该是无限大的,这样我们的图形才可以是任意大小。然而,实际上 SVG 图片是显示在一个有限的区域里的,就像我们透过窗户看窗外的风景一样,这个有限区域被称为“观察孔”(Viewport)。
The Viewport
“观察孔”指的是 SVG 图片可见的那一部分,想象我们透过窗户看窗外的风景,这个窗子就是外面风景的观察孔。
类似的,我们在浏览网页的时候面对的也是这种情况,网页的大小通常比浏览器的窗口要大,这时候浏览器就是这个网页的观察孔了。
我们通过设置 <svg> 标签的 width 和 height 属性来确定这张 SVG 的观察孔大小,对于上面的心形来说,观察孔是 100x100 的正方形:
<!-- the viewport will be 100px by 100px --> <svg width="100" height="100"> <!-- SVG content drawn onto the SVG canvas --> </svg>
在 SVG 里,数值的单位是可选的。在我们不主动提供的时候,默认会以 px 为单位。可选的单位有 em 、 ex 、 px 、 pt 、 pc 、 cm 、 mm 、 in 和百分比。
坐标系统
在观察孔的大小确定下来之后,SVG 就会建立一套初始的坐标系统:以最左上角为 (0, 0) 点,x 轴和 y 轴分别向右和向下延伸(就像移动客户端和网页显示里那样)。在这个基础上,我们刚刚创建的观察孔也就有了属于自己的一套位置标识: (x: 0, y: 0, width: 100, height: 100) 。
The viewbox
在了解了上述知识之后,我们就可以来说说 viewbox 这个属性了。
我们可以把 viewbox 理解为“真正的坐标系统”,因为它决定了 SVG 图形是怎么绘制到画布上的。一个 SVG 图形的大小可以与观察孔不一样,它可能会完整地显示出来,也可能会被观察孔裁减掉一部分。
就像一张普通图片一样,当你需要把图形完整地放进一个视图里面时,可以调节图片的拉伸模式,一边让图片的大小更为合理。SVG 里对应的属性是 preserveAspectRatio 。
viewbox 会一次性设置4个参数:
<svg viewbox="<min-x> <min-y> <width> <height>"></svg>
其中, <min-x> 和 <min-y> 不能设置为负数, <width> 和 <height> 设置为 0 的话,元素就压根不会绘制了。
所以说, viewbox="0 0 100 100" 就做了下面几件事情:
- 在画布上划分出来一个 100x100 大小的区域,放在 (0, 0) 点上
- 把 SVG 图形缩放成合适这个区域的样子
- 将整个区域(包括里面的图形)放大到铺满整个观察孔
- 将这个坐标系统 按比例 映射到到初始坐标系统上
那对于上面的爱心图片来说,我们尝试调整一下 viewbox 的原点,将它设置为 viewbox="50 50 100 100" 试试:
可以看到,就像地图软件一样,镜头往画面的右下方移动了一段。这也相当于把整个画面往左上方推了过去一点,我们可以通过设置画布的 transform 属性来实现相同的效果: transform="translate(-50 -50)" 。
当设计师给你一张 SVG 图片的时候,其中的图案路径可能是按照一定的大小和位移来绘制的,比如从(10, 10) 点开始画的一张 40x40 的图,这时候你的 viewbox 就应该设置为 viewbox="10 10 40 40" ,让图片放到最合适的坐标系统上。
小结
上面的例子演示了一张 SVG 图的常规操作,限于篇幅原因,还有一些有意思的情况没有展示到,比如当 viewbox 里设置的宽高比与我们在 <svg> 标签里设置的宽高比不一样会发生什么呢?这种情况下,就需要我们去了解一下 preserveAspectRatio 属性了。
在参考文章 Understanding SVG Coordinate Systems and Transformations (Part 1) 里,有对这方面更详细的解释,而且作者还提供了非常直观的在线预览工具,相信会对偏向于使用图像思维的同学们更有帮助。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 入门GitHub,这一个开源项目足够了!
- 更好就足够了吗?| 驱动变革
- Python文件操作,看这篇就足够
- 想读懂Linux内核,这一篇就足够!
- 强大美观的通用弹窗XPopup,一个就足够!
- 谷歌大脑:只要网络足够宽,激活函数皆可抛
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Web Data Mining
Bing Liu / Springer / 2011-6-26 / CAD 61.50
Web mining aims to discover useful information and knowledge from Web hyperlinks, page contents, and usage data. Although Web mining uses many conventional data mining techniques, it is not purely an ......一起来看看 《Web Data Mining》 这本书的介绍吧!