在HTML中显示文本的案例
我们可以从成千上万的Web字体中挑选,还可以为它们添加CSS效果,一些具有广泛浏览器支持(如投影和三维变换),一些可能是更试验性的(如 background-clip 背景裁剪和 text-stroke 文本描边),但这都是基本的。如果我们希望能够在我们的网站上显示真正优秀的字体,我们通常会选择把它作为图像嵌入。
在Web上使用图像的缺点是显而易见的:文件的大小,对于经常改变的或用户生成的内容缺乏可行性,可访问性,以及时间损耗等等。
所以如果我们能够为字母编辑样式,就像我们经常使用CSS修饰文本那样,岂不是很棒吗?为多个边界应用不同的颜色?添加内斜面、外斜面?添加图案、纹理和3D效果?给它一个通用的样式?使用多种颜色还有扭曲样式?给它一个繁琐的样式?
复杂的SVG滤镜:CSS
这其中的大部分都是已经可以实现的:关键是要释放SVG滤镜的魔力。SVG滤镜(包括CSS滤镜)通常被认为是一种通过模糊效果或颜色处理来处理位图的方式。但它们其实不只是这样。像CSS规则,SVG滤镜可以是一组添加在传统文本顶部的可视化图层。有了CSS的 filter 属性,这些效果可以在SVG之外使用,然后直接应用到HTML内容上。
说到CSS和SVG中的滤镜可能有一点疑问:SVG滤镜可用一个SVG filter 元素定义,而且可以在SVG文件中应用。CSS滤镜可以通过 filter 属性应用于任何HTML元素上。CSS滤镜如 blur , contrast 和 hue-rotate ,都是预定义的快捷方式,也是常用的SVG滤镜效果。除此之外, 规范 还允许我们引用SVG文件中用户自定义的滤镜。还有一点困惑的是专有的 -ms- filter 标签,在IE9中已经被废弃,在IE10发布时就已经被删除。
本文主要涉及的是第一种情况:嵌入在HTML页面中的SVG文件中使用的滤镜,但后面我们会试着把SVG滤镜应用于HTML内容。
这篇文章中的插图都是SVG滤镜效果应用于文本的示例。点击图片可查看原文(在现代支持SVG的浏览器中查看)。我把他们称为“复杂的”SVG过滤器,因为实际上这些滤镜是多种效果的组合,然后结合到一个输出的。尽管字母的外观已经有了显著的改变,实际上文本仍然是可抓取并且可获得的,可以选中并复制。因为SVG滤镜在所有的现代浏览器中都是支持的,这些效果可以在IE10以上的浏览器中显示。
理解SVG滤镜是有一定挑战性的。即使是像投影这样简单的效果都需要复杂并且详细的语法。一些滤镜,如 feColorMatrix 和 feComposite ,没有对数学和色彩理论有一个透彻的理解的话是很难掌握的。本文不是一篇学习SVG滤镜的教程。相反,我将介绍一组标准 构建模块 ,来完成一些效果,我会用尽量少的解释,重点在于记录完成这些效果的各个步骤。你看到的主要是关于如何完成,对于那些想要了解为什么的人,我在这篇文章的结尾处放了一个阅读列表。
构建滤镜
下面是一张复杂的SVG滤镜的构建图。滤镜输出的是风化的文本效果,我们将使用它作为示例,一步一步演练:
让我们把这个效果分解成几个部分:
绿色文字
红色投影
文字和投影使用一个透明间隙隔开
文字带有grungy和风化效果
我们的SVG滤镜是通过组合多个小模块构建而成的,也称为“滤镜原语”。每个模块都是由一组或更多原语构建而成的,然后再组合成统一的输出结果。下边的图片可以帮助你理解:
构建复杂滤镜的处理步骤,最好的说明图
添加滤镜
我们从一个包含空滤镜和文本的模板SVG文件开始:
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<style type="text/css">
<![CDATA[
.filtered{
filter: url(#myfilter)
…
}
]]>
</style>
<filter id="myfilter">
<!-- filter stuff happening here -->
</filter>
</defs>
<g class="filtered">
<text x="0" y="200" transform="rotate(-12)">Petrol</text>
</g>
</svg>
滤镜元素
我们从 filter 标签元素开始,在其开始和结束标签中间,我们可以放置变换、颜色、位图 *** 作等等所有规则。滤镜可以作为目标元素的属性应用,也可以通过CSS应用。目标元素通常是SVG中的元素,但是后边我们将了解另一个有趣的选择:把SVG滤镜应用于HTML元素。
几个用来控制 filter 元素的属性:
x 和 y 位置(默认 -10% );
width 和 height (默认 120% );
id 属性,对于后边的引用是必需的;
filterRes ,预定义解决方案(在“Filter Effects Module Level 1”规范中不建议使用);
相对单位(默认 objectBoundingBox )或绝对单位(默认 userSpaceOnUse) filterUnits 。
关于滤镜原语
正如我们已经知道的,滤镜原语是SVG滤镜的组成部分。任何一种效果,都至少包含一个原语。一个原语通常包含一个或两个输入( in , in2 ),以及一个输出(result )。原语输入包括模糊、移动、填充、结合或扭曲等等。
该规范允许我们采用滤镜元素的几个属性作为输入源。因为大多数的属性都不能跨浏览器运行,在这篇文章中我们会采用 SourceGraphic (未添加滤镜的元素,有颜色、描边、图案填充等等)和 SourceAlpha (alpha通道的不透明区域——即原图中填充黑色的部分),这两者都有非常好的浏览器支持。
如何加厚输入文本
我们要了解的第一个滤镜原语是 feMorphology ,一个用于把输入加厚(operator="dilate" )或变薄( operator="erode" )的原语——因此,非常适合用来创建轮廓和边界。
这是我们如何将 SourceAlpha 增粗4个像素:
增粗了4个像素的图
<feMorphology operator="dilate" radius="4" in="SourceAlpha" result="BEVEL_10" />
创建投影
下一步骤是在上一个原语的基础上创建一个3D的投影,结合 feConvolveMatrix。这个滤镜原语是最强大也最难以掌握的一个。它主要是帮助你创建自己的滤镜。总之,你会定义一个会根据其相邻像素的值变化的像素栅格(一个内核矩阵)。这样一来,你就可以创建自己的滤镜效果,如模糊、锐化滤镜,或投影。
这是 feConvolveMatrix 创建的一个 45deg 、 3px 的深度投影。 order 属性定义 width 和 height ,这样原语才知道是应用 3x3 的矩阵,还是 9x1 的矩阵:
使用 feConvolveMatrix 创建增粗的投影输入
<feConvolveMatrix order="3,3" kernelMatrix=
"1 0 0
0 1 0
0 0 1" in="BEVEL_10" result="BEVEL_20" />
考虑到IE11和Microsoft Edge无法处理大于 8x8 的矩阵,它们也无法很好地处理复杂矩阵,所以在部署这段代码之前先删除所有回车最好。
该原语同样可以应用于左、上、右、下各个方向。因为我们希望投影是往右下方的,我们需要修改结果。 targetX 和 targetY 这两个属性定义了效果的起点。可惜,IE对它们的解析不同于其它的浏览器。因此,要保持跨浏览器的兼容性,我们将使用另一个滤镜原语 feOffset 来处理。
OFFSETTING
顾名思义, feOffset 需要一个输入值,如下:
<feOffset dx="4" dy="4" in="BEVEL_20" result="BEVEL_30"/>
裁剪投影部分
feComposite 是为数不多的几个需要两个输入的滤镜原语之一。它运用了Porter-Duff合成来组合两张图像。 feComposite 可以用于掩蔽或裁剪元素。这是如何从feConvolveMatrix 输出的结果中减去 feMorphology 的输出。
从投影中裁剪掉第一个加粗的原语
<feComposite operator="out" in="BEVEL_20" in2="BEVEL_10" result="BEVEL_30"/>
为投影着色
这个过程包括两个步骤:
首先,我们使用 feFlood 创建一个着色区域。这个原语将会简单地在滤镜区域输出根据我们定义的颜色的矩形。
<feFlood flood-color="#582D1B" result="COLOR-red" />
然后我们再用一个 feComposite 裁剪掉 BEVEL_30 的透明部分:
为投影着色
<feComposite in="COLOR-red" in2="BEVEL_30" operator="in" result="BEVEL_40" />
将斜面和原图结合成一个输出
feMerge 可以把斜面和源一起输出:
斜面和原图混合成一个输出
<feMerge result="BEVEL_50">
<feMergeNode in="BEVEL_40" />
<feMergeNode in="SourceGraphic" />
</feMerge>
看起来像是我们期待的结果。让我们给它加一个风化的效果,看起来更逼真一些。
添加分形纹理
feTurbulence 是最好玩的原语之一。但是,它可能融化你的多核CPU,让你的风扇像波音747的涡轮喷气发动机那样旋转。所以,谨慎使用,尤其是在移动设备上,因为这个原语对渲染性能有非常坏的影响。
像 feFlood , feTurbulence 输出填充矩形,但使用的是杂乱的非结构化的纹理。
我们手头有几个值可用来改变纹理的质感和节奏。通过这种方式,我们可以创建像木头、沙子、水彩或破裂混凝土效果的表面。这些设置对滤镜的性能有直接的影响,所以测试要足够彻底。以下是如何创建一个类似描边画笔的纹理的代码:
<feTurbulence baseFrequency=".05,.004" width="200%" height="200%" top="-50%" type="fractalNoise" numOctaves="4" seed="0" result="FRACTAL-TEXTURE_10" />
默认情况下, feTurbulence 输出的是彩色纹理——不是我们想要的那个。我们需要一个灰度alpha图;多一点对比的话会更好。通过 feColorMatrix 来增加对比度,同时将它转换为灰度图:
最后,加上分形纹理的效果
<feColorMatrix type="matrix" values=
"0 0 0 0 0,
0 0 0 0 0,
0 0 0 0 0,
0 0 0 -1.2 1.1"
in="FRACTAL-TEXTURE_10" result="FRACTAL-TEXTURE_20" />
最后要做的就是将纹理alpha和文字组合,依然是使用我们的老朋友 feComposite:
<feComposite in="BEVEL_50" in2="FRACTAL-TEXTURE_20" operator="in"/>
终于完成啦O(∩_∩)O~
如何将SVG滤镜应用到SVG
以下是两种将SVG滤镜应用到SVG text 元素的方法:
通过CSS
.filtered {
filter: url(#filter)
}
通过属性
<text filter="url(#filter)">Some text</text>
将SVG滤镜应用到HTML内容
滤镜最鸡冻人心的特性之一是,它可以嵌入SVG,在SVG中定义滤镜,并使用CSS把它应用到任何HTML元素中:
filter: url(#mySVGfilter)
在写这篇文章的时候,Blink和WebKit都需要添加前缀,如下:
-webkit-filter: url(#mySVGfilter)
这在理论上听起来很容易,但实际中却是一种黑暗艺术orz:
WebKit、Firefox和Blink目前都支持SVG滤镜应用于HTML内容。IE和Microsoft Edge却会显示未添加滤镜的元素,所以要确保默认样式看起来也非常OK~
包含滤镜的SVG可能不会被设置为 display: none 。但是你可以自己设置visibility: hidden 。
有时候SVG的大小会直接影响应用的目标元素的多少。
我说过WebKit,Blink和Firefox理解这种语法吗?好吧,Safari(和它的小伙伴,Mobile Safari)是一个特例。你可以在Safari中跑一下这些demo,但是你很可能会抓狂。在写这篇文章的时候,我不建议在当前版本的Safari(8.0.6)中对HTML内容使用SVG滤镜。因为结果是不可预测的,技术并非刀q不入。更糟糕的是,如果Safari因为某些原因无法渲染你的滤镜,它也不会显示目标HTML元素,噢噢噢噢噩梦:-(。基于经验法则,你增加你让Safari显示你的滤镜的机会,通过绝对定位和固定目标元素的大小。作为一个概念证明,我已经设置了一个 “流行的”滤镜效果,针对桌面版Safari 进行了优化。在Safari中,将 feImage 应用于HTML元素似乎是不可能的。
之前的DEMO,应用于HTML内容
在这些demo中,包裹元素都被设置为 contenteditable = "true" ,方便进行文本编辑。(请注意,这些demo都是实验,在Safari、IE或Edge中都是不能运行的。)
Image filled text
用图像填充文本
Extruded and filled with pattern
使用图案填充和投影
Extruded and illuminated
投影和发光
Grungy look with the help of fractal filters
分形滤镜帮助完成的grungy效果
feTurbulence to achieve spilled water effect
feTurbulence 完成溅水效果
Some pop-arty color effects
凸出的颜色效果
Sketchy style
手绘风格
自定义滤镜
根据其复杂程度,滤镜也可以是一个很复杂的东西。在制作滤镜的时候,你可以添加或移除规则、改变他们的顺序和值,但很快你就会变得混乱。这里有一些我自己写的规则,可以帮助我追踪发生的问题。因为人员和项目不同,在我看来逻辑和结构化的东西,在你看来可能是混乱和不知所云,所以采用并保留一下这些建议吧。
分组
我把滤镜原语根据它们自身的功能分成了几组——如:“border”、“fill”、“bevel”等等。在模块的开始和结束的地方,我会根据组名备注。
命名
良好的命名规则可以帮助你更好地组织滤镜,并且方便对原语内部和外部情况进行追踪。经过对 BEM-like schemas 的实验,我最终确定了一个非常简单的命名结构:
NAME-OF-GROUP_order-number
比如说,你可能使用像 BEVEL_10 , BEVEL_20 , OUTLINE_10 等等这样的命名。我从 10 开始,并使用 10 作为增量,方便调整原语的顺序,也方便在一组原语中间或开始的地方添加原语。我比较喜欢整块内容一起使用,因为它们能够帮我更快地扫描原内容。
保持声明输入和结果
尽管不是必要的,我通常都会声明一个“ in ”和“ result ”。(如果省略,原语的输出就默认是其继承者的输入)
一些构建模块
我们先看看单个技术能达到的效果。然后通过组合这些构建模块,我们可以创建新的复杂的滤镜效果。
文本描边
Outlined
<!-- 1. Thicken the input with feMorphology: -->
<feMorphology operator="dilate" radius="2"
in="SourceAlpha" result="thickened" />
<!-- 2. Cut off the SourceAlpha -->
<feComposite operator="out" in="SourceAlpha" in2="thickened" />
这个方法并不能保证结果是好看的。尤其是你将 dilate 与较大的 radius 值结合的时候,结果可能比通过 stroke-width 创建的几何体糟糕一些。根据不同的情况,比较好的选择是将文本存储在一个符号元素中,然后在需要的时候通过 use 插入,再通过CSS的 stroke-width 属性将其加厚。注意, stroke-width 不能应用于HTML内容。
撕裂效果
Torn Out
<!-- 1. create an feTurbulence fractal fill -->
<feTurbulence result="TURBULENCE" baseFrequency="0.08"
numOctaves="1" seed="1" />
<!-- 2. create a displacement map that takes the fractal fill as an input to distort the target: -->
<feDisplacementMap in="SourceGraphic" in2="TURBULENCE" scale="9" />
颜色填充
Colored
<!-- 1. Create a colored filled area -->
<feFlood flood-color="#F79308" result="COLOR" />
<!-- 2. Cut off the SourceAlpha -->
<feComposite operator="in" in="COLOR" in2="SourceAlpha" />
有一点需要提到的是,除了 feFlood , feColorMatrix 是另一种能够改变原输入颜色的方法,尽管它本身的概念比较难以理解。
OFFSETTING
Off Set.
<!-- Offset the input graphic by the amount defined in its "dx" and "dy" attributes: -->
<feOffset in="SourceGraphic" dx="10" dy="10" />
投影
Extruded
<!-- Define a convolve matrix that applies a bevel. -->
<!-- Order defines the depth of the extrusionangle is defined by the position of "1" in the matrix. Here we see a 45-degree, 4-pixel deep extrusion: -->
<feConvolveMatrix order="4,4"
kernelMatrix="
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1" in="SourceAlpha" result="BEVEL" />
<!-- offset extrusion: -->
<feOffset dx="2" dy ="2" in="BEVEL" result="OFFSET" />
<!-- merge offset with Source: -->
<feMerge>
<feMergeNode in="OFFSET" />
<feMergeNode in="SourceGraphic" />
</feMerge>
注意:Internet Explorer和Safari不支持SVG滤镜
<defs>、<filter>
所有互联网的SVG滤镜定义在<defs>元素中,<filter>标签用来定义SVG滤镜,<filter>标签使用必须的ID属性来定义向图形应用到那个滤镜中
SVG模糊效果
<feGaussianBlur>
feGaunssianBlur元素是用于创建模糊效果
SVG代码:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<filter id="f1" x="0" y="0">
<feGaussianBlur in="SourceGraphic" stdDeviation="15" />
</filter>
</defs>
<rect width="90" height="90" stroke="green" stroke-width="3"
fill="yellow" filter="url(#f1)" />
</svg>
代码解析:
<filter>元素id属性定义一个滤镜的唯一名称
<feCaussianBlur>元素定义模糊效果
in="SourceGraphic"这个部分定义了由整个图像创建效果
stdDeviation属性定义模糊量
<rect>元素的滤镜属性用来把元素链接到“f1”滤镜
SVG阴影
<feOffset>
feOffset元素用于创建阴影效果
实例1
偏移一个矩形(带<feOffset>),然后混合偏移图像顶部(含<feBlend>)
SVG代码:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<filter id="f1" x="0" y="0" width="200%" height="200%">
<feOffset result="offOut" in="SourceGraphic" dx="20" dy="20" />
<feBlend in="SourceGraphic" in2="offOut" mode="normal" />
</filter>
</defs>
<rect width="90" height="90" stroke="green" stroke-width="3"
fill="yellow" filter="url(#f1)" />
</svg>
实例2
偏移图像可以变的模糊(含<feGaussianBlur>)
SVG代码:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<filter id="f1" x="0" y="0" width="200%" height="200%">
<feOffset result="offOut" in="SourceGraphic" dx="20" dy="20" />
<feGaussianBlur result="blurOut" in="offOut" stdDeviation="10" />
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
</filter>
</defs>
<rect width="90" height="90" stroke="green" stroke-width="3"
fill="yellow" filter="url(#f1)" />
</svg>
代码解析
元素的stdDeviation属性定义了模糊量
实例3
制作一个黑色的阴影
SVG代码:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<filter id="f1" x="0" y="0" width="200%" height="200%">
<feOffset result="offOut" in="SourceAlpha" dx="20" dy="20" />
<feGaussianBlur result="blurOut" in="offOut" stdDeviation="10" />
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
</filter>
</defs>
<rect width="90" height="90" stroke="green" stroke-width="3"
fill="yellow" filter="url(#f1)" />
</svg>
代码解析:
feOffset元素的属性改为"SourceAlpha"在Alpha通道使用残影,而不是整个RGBA像素
实例4
为阴影涂上一层颜色
SVG代码:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<filter id="f1" x="0" y="0" width="200%" height="200%">
<feOffset result="offOut" in="SourceGraphic" dx="20" dy="20" />
<feColorMatrix result="matrixOut" in="offOut" type="matrix"
values="0.2 0 0 0 0 0 0.2 0 0 0 0 0 0.2 0 0 0 0 0 1 0" />
<feGaussianBlur result="blurOut" in="matrixOut" stdDeviation="10" />
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
</filter>
</defs>
<rect width="90" height="90" stroke="green" stroke-width="3"
fill="yellow" filter="url(#f1)" />
</svg>
分类: 【06】SVG
可以任意放大图形显示,但绝不会以牺牲图像质量为代价;可在SVG图像中保留可编辑和可搜寻的状态;平均来讲,SVG文件比JPEG和PNG格式的文件要小很多,因而下载也很快。可以相信,SVG的开发将会为Web提供新的图像标准。
1、 SVG 可被非常多的工具读取和修改(比如记事本)
2、 SVG 与 JPEG 和 GIF 图像比起来,尺寸更小,且可压缩性更强。
3、 SVG 是可伸缩的
4、 SVG 图像可在任何的分辨率下被高质量地打印
5、 SVG 可在图像质量不下降的情况下被放大
6、 SVG 图像中的文本是可选的,同时也是可搜索的(很适合制作地图)
7、 SVG 可以与 JavaScript 技术一起运行
8、 SVG 是开放的标准
9、 SVG 文件是纯粹的 XML
工作原理
它是基于XML(Extensible Markup Language),由World Wide Web Consortium(W3C)联盟进行开发的。严格来说应该是一种开放标准的矢量图形语言,可让你设计激动人心的、高分辨率的Web图形页面。
用户可以直接用代码来描绘图像,可以用任何文字处理工具打开SVG图像,通过改变部分代码来使图像具有交互功能,并可以随时插入到HTML中通过浏览器来观看。
SVG图像及其行为在XML文本文件中定义。这意味着可以对其进行搜索,建立索引,编写脚本和进行压缩。
作为XML文件,可以使用任何文本编辑器以及绘图软件来创建和编辑SVG图像。在阿拉伯语Unicode的 程序员和书法家,托马斯·米洛维基百科归功于采用SVG作为为什么小型成像技术得到普及的原因。
对象类型
SVG允许3种图形对象类型:
矢量图形、栅格图像以及文本。图形对象——包括PNG、JPEG这些栅格图像——能够被编组、设计、转换及集成进先前的渲染对象中。文本可以在任何适用于应用程序的XML名字空间之内,从而提高SVG图形的搜索能力和无障碍性。
SVG提供的功能集涵盖了嵌套转换、裁剪路径、Alpha通道、滤镜效果、模板对象以及可扩展性。
SVG严格遵从XML语法,并用文本格式的描述性语言来描述图像内容,因此是一种和图像分辨率无关的矢量图形格式。
以上内容参考 百度百科-SVG格式
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)