时间:2019-08-13
编辑:网站制作公司
949
0
上海网站建设我喜欢手工编写SVG代码。情况并非总是如此,但对于那些不喜欢偏好的人来说,这似乎是特别的。能够手工编写SVG有很多好处,例如以工具无法实现的方式优化SVG(将路径转换为更简单的路径或形状),或者简单地理解像D3或Greensock这样的库如何工作。
话虽如此,我想更仔细地观察SVG中的圆形形状以及当我们移过基本圆形时我们可以用它们做的事情。为何圈?好吧,我喜欢圈子。他们是我最喜欢的形状。
首先(希望你以前在SVG中看过一个基本的圆圈),这里有一支笔,显示一个:
圆圈可以做很多事情:它可以是动画的,可以应用不同的颜色。仍然有两个非常好的东西,你不能在SVG 1.1中做一个圆圈:你不能让另一个图形元素沿着圆的路径移动(使用animateMotion元素),你不能沿着圆的路径形成文本(这只会在SVG 2.0发布后被允许)。
有一个小的在线工具,可以帮助你创建圈外路径(你可以在这里尝试),但我们将从头开始创建所有内容,以便我们可以找到幕后真正发生的事情。
为了形成一个圆形路径,我们将实际制作两个弧,即在一条路径中完成圆的半圆。正如您在上面的SVG中可能已经注意到的那样,属性CX,CY和R分别定义了沿X和Y轴绘制圆的位置,同时R定义了圆的半径。在CX与CY创建圆心,因此圆围绕该点绘制。
该圆圈可能如下所示:
<path d=" M (CX - R), CY a R,R 0 1,0 (R * 2),0 a R,R 0 1,0 -(R * 2),0 "/>
注意,CX这与cx圆的属性相同; 这同样适用CY与cy圆的属性,以及R与r圆的属性。小a字符用于定义椭圆弧的一段。您可以使用可选Z(或z)来关闭路径。
小写字母a表示相对于当前位置绘制的椭圆弧的开始 - 或者在我们的特定情况下:
<path d=" M 25, 50 a 25,25 0 1,1 50,0 a 25,25 0 1,1 -50,0 "/>
你可以看到这支笔中发生的魔力:
隐藏在路径下方的是一个带有红色填充的圆圈。当您使用路径的值时,只要路径完全覆盖圆圈(路径本身就是一个相同大小的圆圈),您就会看到该圆圈,我们知道我们正在做正确的事情。
您还应该知道的一件事是,只要您绘制相对圆弧,就不需要为a绘制的每个圆弧重复该命令。当您为弧完成前7个输入时,第二个7输入将用于下一个弧。
您可以通过删除a路径中的第二个来使用上面的笔尝试此操作:
a 25,25 0 1,1 50,025,25 0 1,1 -50,0
这可能看起来一样,但我更喜欢把它放进去,直到我准备好完成绘图,这也有助于我跟踪我的位置。
首先,我们移动到X,Y图像中绝对定位的坐标。它没有在那里画任何东西 - 它只是移动到那里。请记住,对于圆形元素CX,CY表示圆的中心; 但是当它发生在椭圆弧中时,真实CX和CY弧将根据该弧的其他属性计算。
换句话说,如果我们希望我们CX处于50和我们的半径是25,那么我们需要移动到50 - 25(如果我们从左到右绘制,当然)。这意味着我们的第一个弧被绘制25 X, 50 Y成我们的第一个弧25,25 0 1,0 50,0。
让我们分解25,25 0 1,0 50,0我们的弧的价值实际意味着什么:
25:弧的相对X半径;
25:弧的相对Y半径;
0 1,0:我不打算讨论三个中间值(rotation,large-arc-flag和sweep-flag属性),因为它们在当前示例的上下文中不是很重要,只要它们是相同的两个弧线;
50:弧的结束X坐标(相对);
0:弧的结束Y坐标(相对)。
第二个弧是一个25,25 0 1,0 -50,0。请记住,此弧将从最后一个弧停止绘制的任何地方开始绘制。当然,X和Y半径是相同的(25),但结束X坐标是-50当前的坐标。
显然,这个圈子可以用许多不同的方式绘制。将圆圈转换为路径的过程称为分解。在SVG 2规范中,圆的分解将使用4个弧进行,但是,它推荐的方法还不能使用,因为它当前依赖于一个名为segment-completed close path的特征,该特征尚未指定。
为了向您展示我们可以通过多种方式绘制圆圈,我准备了一些带有各种示例的小笔:
如果仔细观察,您会看到我们的原始圆圈以及如何在该圆圈顶部绘制路径的五个不同示例。每个路径都有一个desc描述使用的子元素CX,CY以及R构建圆的值。第一个例子是我们在这里讨论的例子,而另外三个例子是使用通过阅读代码可以理解的变体; 最后的例子使用了四个半圆弧而不是两个,了上面链接的SVG 2规范中描述的过程。
使用SVG的自然z-indexing将这些圆形层叠在彼此之上,这些z-indexing放置了稍后在标记之上的元素。
如果单击笔中的圆形路径,第一次单击将打印出路径如何构造到控制台并向元素添加一个类,以便您可以看到绘制圆的方式的笔触颜色(您可以看到第一个圆圈是用笔划的起始楔形绘制的。第二次点击将移除圆圈,以便您可以与下面的圆圈进行互动。
每个圆圈都有不同的填充颜色; 实际的圆形元素是黄色的,只要点击它就会向控制台说“你点击圆圈”。当然,您也可以简单地阅读代码,因为desc元素非常简单。
我想你已经注意到虽然绘制圆圈的方法有很多种,但使用的路径看起来仍然非常相似。通常 - 特别是在绘图程序输出的SVG中 - 圆圈将由路径表示。这可能是由于图形程序代码的优化; 一旦你有了绘制路径的代码就可以绘制任何东西,所以就这样使用它。这可能导致有些臃肿的SVG很难推理。
推荐阅读:Sara Soueidan撰写的“ 为Web创建和导出更好的 SVG的提示”
我们以维基百科的以下SVG为例。当你查看该文件的代码时,一旦你通过Jake Archibald的SVGOMG运行它,你会发现它有很多编辑器!(您可以在这里阅读更多信息),您最终会得到类似以下文件的内容,该文件已经过优化,但文档中的圆圈仍然呈现为路径:
所以,让我们看看如果我们知道路径如何工作,我们是否可以弄清楚这些圈子应该是什么,如果它们是实际的圈子元素。文档中的第一条路径显然不是圆形,而接下来的两条路径(仅显示d属性):
M39 20a19 19 0 1 1-38 0 19 19 0 1 1 38 0z
M25 20a5 5 0 1 1-10 0 5 5 0 1 1 10 0z
所以记住第二个a可以省略,让我们重写一下以使其更有意义。(第一条路是大圆圈。)
M39 20a19 19 0 1 1-38 0a19 19 0 1 1 38 0z
那些弧线显然如下:
aR R 0 1 1 - (R * 2) 0aR R 0 1 1 (R * 2) 0
这意味着,我们的圆半径为19,但什么是我们CX和CY价值观?我认为我们M39实际上是CX + R,这意味着CX是20和CY是20太。
假设您在所有路径之后添加一个圆圈,如下所示:
<circle fill="none" stroke-width="1.99975" stroke="red" r="19" cx="20" cy="20"/>
您将看到这是正确的,并且红色描边圆圈恰好覆盖了大圆圈。重新制定的第二个循环路径如下所示:
M25 20a5 5 0 1 1-10 0 5 5 0 1 1 10 0z
显然,半径是5,我打赌我们的CX和CY以前的价值相同:- 20。
注意:如果 CX = 20,那么 CX + R = 25。圆圈位于中心较大的圆圈内,显然它应该具有相同的值CX和CY 值。
在路径末尾添加以下圈子:
<circle fill="yellow" r="5" cx="20" cy="20"/>
现在,您可以通过查看以下笔来了解这是正确的:
现在我们知道圈子应该是什么,我们可以删除那些不需要的路径并实际创建圈子 - 正如您在此处所见:
所以现在我们在路径中有了圈子,我们可以在这些路径上包装文本。下面是一支笔,其路径与我们之前的“All Circles”笔相同,但文字包含在路径上。每当您单击路径时,该路径将被删除,文本将被包装在下一个可用路径上,如下所示:
看一下不同的路径,你会看到每个路径之间的细微差别(稍微多一点),但首先有一点点跨浏览器不兼容 - 在第一条路径中尤为明显:
![]() | Firefox开发者 |
![]() | 铬 |
![]() | Microsoft Edge |
在“解决方案”中,“Smashing”的起始“S”坐在那个有趣的角度是因为它是我们实际开始绘制路径的地方(由于我们使用的vR命令)。这在Chrome版本中更为明显,您可以清楚地看到我们绘制的圆形的第一个饼形楔形:
![]() | Chrome不会跟随所有楔形,因此当您将文本更改为“Smashing Magazine”时,这就是结果。 |
原因是Chrome有关于继承textLength父text元素上声明的属性的错误。如果您希望它们看起来都相同,请将该textLength属性放在textPath元素和文本上。为什么?因为事实证明,如果textLength没有在text元素上指定属性,Firefox Developer会有相同的错误(现在已经存在了几年)。
Microsoft Edge有一个完全不同的错误; 它无法处理Text子TextPath元素和子元素之间的空格。一旦你删除了空格,并将textLength属性放在text和textPath元素上,它们看起来都相对相同(由于默认字体的差异等,变化很小)。因此,在三种不同的浏览器上有三个不同的错误 - 这就是人们经常喜欢使用库的原因!
以下笔显示了如何解决问题:
我还删除了各种填充颜色,因为它可以更容易地看到文本包装。删除填充颜色意味着我的小功能允许您循环遍历路径并查看它们的外观不起作用,除非我添加pointer-events="all"属性,所以我也添加了这些。
注意:您可以在Tiffany B. Brown解释的“ 管理SVG与指针事件属性的交互 ”中阅读更多有关其原因的信息。
我们已经讨论了multiarc路径的包装,现在让我们看看其他路径。由于我们有一条路径,因此文本将始终朝同一方向移动。
图片 | 路径 | 说明 |
---|---|---|
![]() | M CX, CY a R, R 0 1,0 -(R * 2), 0 a R, R 0 1,0 R * 2,0 并使用该translate功能+R在X轴上移动。 | 我们的起始位置textPath(因为我们没有以任何方式指定它)由我们的第一个结束弧确定-(R * 2),给定弧本身具有的半径。 |
![]() | M (CX + R), CY a R,R 0 1,0 -(R * 2),0 a R,R 0 1,0 (R * 2),0 | 与前一个路径相同。 |
![]() | M CX CY m -R, 0 a R,R 0 1,0 (R * 2),0 a R,R 0 1,0 -(R * 2),0 | 由于我们在第一个弧线结束,我们显然将从相反的位置开始。换句话说,这个从我们前两个路径结束的地方开始。(R * 2 ) |
![]() | M (CX - R), CY a R,R 0 1,1(R * 2),0 a R,R 0 1,1-(R * 2),0 | 这开始于与最后一个相同的位置,但由于我们已将sweep-flag属性(标记为黄色)设置为,因此顺时针运行。(R * 2)1 |
我们已经看到了如何在一个圆圈中的单个路径上包装文本。现在让我们来看看我们如何将这条路径分解为两条路径以及您可以从中获得的好处。
您可以对路径中的文本执行许多操作,即使用tspan元素实现样式效果,设置文本的偏移量或为文本设置动画。基本上,无论你做什么都会受到路径本身的限制。但是通过将我们的多弧路径分解为单个弧路径,我们可以使用文本的方向,文本不同部分的z索引以及实现更复杂的动画。
首先,我们将要使用另一个SVG图像来显示一些效果。我将使用前面提到的关于指针事件的文章中的钻石。首先,让我们展示它上面放置单个路径圆形文本的样子。
我们假设我们的圈子是CX 295, CY 200, R 175。现在,遵循循环路径方法,我们现在看到以下内容:
M (CX - R), CYa R,R 0 1,1 (R * 2),0a R,R 0 1,1 -(R * 2),0
我不打算谈论路径或文字大小,填充或描边颜色。到目前为止,我们都应该明白,并且能够使它成为我们想要的任何东西。但通过查看文本,我们可以立即看到一些缺点或限制:
全文都朝着一个方向运行;
将一些文字放在紫水晶后面可能会很好,尤其是它说杂志的地方。为了使圆圈上的'M'和'E'排列,'A'必须位于紫水晶的侧面下方,这在另一种方式感觉有点不平衡。(我觉得'A'应该精确定位并指向那一点。)
如果我们想解决这些问题,我们需要将单一路径分成两部分。在下面的笔中,我将路径分成两个路径,(并将它们放入defsSVG 的区域以供我们textPath参考):
再次,假设我们CX是295, CY 200, R 175,那么这两条路径的格式如下(对于顶部的半圆形路径):
M (CX - R), CYa R,R 0 1,1 (R * 2),0
以下是底部:
M (CX + R), CYa R,R 0 1,1 -(R * 2),0
但是,我们仍然有圆形文本,它们都朝着同一个方向移动。要解决除Edge之外的所有问题,您所要做的就是将side="right"属性添加到text包含'MAGAZINE' 的元素中textPath。
如果我们想尽可能多地支持浏览器,我们必须改变路径而不依赖于side不完全支持的属性。我们可以做的是我们的顶部半圆路径,但将扫描更改1为0:
之前:
M 120, 200a 175,175 0 1,1 350,0
后:
M 120, 200a 175,175 0 1,0 350,0
但是我们的文本现在绘制在扫描定义的内圈上,在不同的浏览器中看起来不太好看。这意味着我们将不得不移动路径的位置以与'Smashing'的'S'对齐,使路径的结尾X更大,并为文本设置一些偏移。正如您所看到的,Firefox和其他文件之间也存在一些文本差异,我们可以通过增加元素的textLength属性来改进text,以及从中删除空格textPath(因为Firefox显然认为空白是有意义的)。
解决方案:
最后,我们想让我们的文字在紫水晶的前面和后面。嗯,这很容易。请记住,SVG的元素z索引是基于它们在标记中的位置吗?因此,如果我们有两个元素,则元素1将被绘制在元素后面2。接下来,我们所要做的就是text在SVG标记中移动一个元素,以便在紫水晶之前绘制它。
你可以看到下面的结果,“紫胶”这个词的哪些部分隐藏在紫水晶的低点。
如果您查看标记,可以看到文本的下半圆已移动到绘制紫水晶的路径之前。
因此,现在我们可以通过将文本分成两个半圆来完全控制文本部分的方向性来制作圆形文本。当然,这也可以用来制作文本的动画。制作跨浏览器SVG动画实际上是另一篇文章(或更多文章)的主题。这些示例仅适用于Chrome和Firefox,因为使用了SMIL-animations语法而不是CSS关键帧或Greensock等工具。但它给出了通过动画分解的圆圈可以实现的效果的良好指标。
拿下面的笔:
请按下编码器上的“重新运行”按钮以查看动画。我们的圆形文本的两个部分同时开始动画,但具有不同的持续时间,因此它们在不同的时间结束。因为我们正在为该textLength属性设置动画,所以我们animate在每个文本下放置了两个指令 - 一个用于text元素(因此Firefox将起作用),一个用于textpath元素(因此Chrome将起作用)。
在本文中,我们已经了解了如何将一个圆圈转换为一个路径并再次返回,以便更好地了解何时需要优化路径,何时不需要。我们已经看到如何将圆圈转换为路径将我们释放到将文本放置在圆形路径上,以及如何进一步将圆形路径分割成半圆并更加全面地控制圆形文本的组成部分的方向性和动画。
上海网站建设
3
s后返回登录3
s后返回登录