前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一步步教你用CSS添加SVG过滤器[每日前端夜话0x47]

一步步教你用CSS添加SVG过滤器[每日前端夜话0x47]

作者头像
疯狂的技术宅
发布2019-04-23 14:36:59
2.8K0
发布2019-04-23 14:36:59
举报
文章被收录于专栏:京程一灯京程一灯

翻译:疯狂的技术宅 原文:https://www.creativebloq.com/how-to/add-svg-filters-with-css

自21世纪初以来,SVG就存在了,但仍有一些有趣的方法去用它。在本教程中,重点将放在 SVG 的过滤器上 —— 但不只是将它们应用于 SVG 图像,我将向你展示如何将它们应用于任何常规页面的内容上。

实际上我们是通过告诉 CSS 过滤器所拥有的 ID,然后再把过滤器应用于 SVG 的方式来实现。使用同样的方法,过滤器也可以用于常规文本。关于这一点的好处在于,你可以轻松的为文本添加一些出彩的特效,以前只能通过使用 Photoshop 滤镜并保存为图像来实现。使用SVG过滤器,文本仍然是可访问并可选的,因为它只是页面上的常规文本元素。

这里的代码将为文本创建一个置换贴图,这个贴图还包含一个 alpha 贴图,使其看起来像水一样,并符合我们页面的主题。然后创建另一个过滤器,使菜单显示为水斑点,它们会稍微粘在一起,但会随着它们向远处移动而分开。这也是为了和特定页面的主题保持一致,并展示了将 SVG 过滤器用于其他内容的两种创造性方法。

  • 从FileSilo下载本教程的源码【https://www.filesilo.co.uk/download/70874/?post_id=70872】

01. 开始

首先,你需要从上面的链接下载项目文件。之后将项目文件夹 **start ** 拖到代码 IDE 上,然后打开 index.html 页面。你将会看到一些已经写好的页面内容。接下来创建标题部分,这里将包含受 SVG 过滤器影响的标题。在 body 标签内添加代码。

代码语言:javascript
复制
1<div class="bg">
2        <div class="middle">
3            <h2 class="headline">Underwater 
4            Adventure Park</h2>
5            <div class="intro_block">

02. 完成标题

现在标题已完成,所有文本都已就绪。如果你此刻在浏览器中查看页面,将看到一个带有一些文本的图像。当前标题仍然是没有样式的,接下来为它设置样式并应用 SVG 过滤器。

代码语言:javascript
复制
 1<h3 class="subhead">Experience the Ocean 
 2<br>Like Never Before</h3>
 3                <p class="intro">Underwater 
 4                Adventure Park is an experience 
 5                unlinke anything you have ever 
 6                had. Travel to the depths of 
 7                the Ocean and walk among the 
 8                Sea Life!</p>
 9            </div>
10        </div>
11    </div>

03. 创建一个 SVG 过滤器

SVG 代码可以添加到页面的任何位置,但是因为它不会被用户直接看到,所以最好将它放在闭合 body 标签之前的最底部。 SVG 过滤器产生一些波纹效果。请注意,过滤器具有 ID —— 这使 CSS 能够把它应用到页面上的另一个元素。

代码语言:javascript
复制
1<svg xmlns="http://www.w3.org/2000/svg">
2        <filter id="displacementFilter">
3            <feTurbulence type="turbulence" 
4            baseFrequency="0.004" numOctaves=
5            "2" result="turbulence" />
6        </filter>
7</svg>

04. 隐藏 SVG

现在转到 page.css 文件,我们的新 CSS 会添加到所有其它CSS代码的顶部。这里的 SVG 被设置为根本不显示在页面上。为 h2 标记设置相对应的字体的字体。

代码语言:javascript
复制
1svg {
2    display: none;
3}
4h2 {
5    font-size: 5.5vw;
6    font-family: 'Crete Round', serif;
7}

05. 加入 headline

line-height 设置为零,因为稍后标题将被加上动画效果,所以控制页面上的缩放很重要。它设定了 padding 值,使其周围能够有适量的空间,颜色也会改变。

代码语言:javascript
复制
1.headline {
2    line-height: 0;
3    display: inline-block;
4    padding: 70px;
5    color: #ccffff;

06. 完成 headline

SVG 将用于替换标题文本

在完成 headline 类后,下一行将 SVG 中的 displacementFilter ID应用于文本。 translate3d 确保用硬件加速去处理文本。把 scale 稍微改变一点,以确保当发生位移时看起来是正确的。

代码语言:javascript
复制
1    filter: url(#displacementFilter);
2    transform: translate3d(0, 0, 0);
3    transform: scaleY(1.8) rotateY(-2deg);
4}

07. 替换它

现在文本被替换了

如果在此阶段测试过滤器,则波纹效果会完全取代文本。这很容易解决。回到 index.html 页面中的过滤器代码。这样将应用波纹和源图形(即文本),并将其应用为位移过滤器。尝试改变波纹的频率和振幅。

代码语言:javascript
复制
1<feDisplacementMap in2="turbulence" in="
2SourceGraphic" scale="30" xChannelSelector="R" 
3yChannelSelector="G" result="disp" />

08. 柔化边缘

使用高斯模糊来柔化文本

水边效果的边缘看起来有点扎眼。这可以用高斯模糊来解决。在置换贴图后面添加代码。当你刷新页面时,它确实模糊了文本,但位移也消失了。同样这些问题可以在实现效果的过程中被修复。

代码语言:javascript
复制
1<feGaussianBlur in="SourceGraphic" 
2stdDeviation="15" result="blr" />

09. 组合两者

把模糊和位移进行组合,可以获得更令人愉悦的效果

在之前的高斯模糊下面添加复合线。你将看到会把模糊和位移效果结合在一起,并且还为文本创建了水润的半透明效果。它的边缘已经在某种程度上变得柔和了,但是这还不够。如果能把最初的模糊效果加入到这里效果会很好。

代码语言:javascript
复制
1<feComposite in="blr" in2="disp" operator="in" result="comp" />

10. 合并模糊

通过合并操作,它看起来会更好

合并操作使前面的效果与模糊效果合并。现在看上去与背景图像很搭,就好像光线穿过了水面一样。对于文本来说它仍然是可选择的,并且是页面的一部分,这点和在 Photoshop 中作出的效果完全不一样。

代码语言:javascript
复制
1<feMerge result="final">
2                <feMergeNode in="blr" />
3                <feMergeNode in="comp" />
4            </feMerge>

11. 创建动画

回到 page.css 文件并添加关键帧,如下所示。这将会把字体大小从零垂直宽度扩展到 5.5 垂直宽度。把它应用于标题后,文本会在屏幕上放大并被放置到位。随着文本的移动,位移也会随着长度的变化而变化,产生水纹效果。

代码语言:javascript
复制
1@keyframes scaler {
2    from {
3        font-size: 0vw;
4    }
5    to {
6        font-size: 5.5vw;
7    }
8}

12. 更改 h2 样式

替换 h2 以引入一些动画

之前在步骤 4 中添加了 h2 样式。使用下面这段新代码替换旧代码,这段代码将为标题添加四秒的 CSS 动画。动画停止会停留在最后一个关键帧上。保存文件并在浏览器中测试,检查文本是否到位。

代码语言:javascript
复制
1h2 {
2    line-height: 0;
3    font-size: 0vw;
4    animation-name: scaler;
5    animation-duration: 4s;
6    animation-fill-mode: forwards;
7    font-family: 'Crete Round', serif;
8}

13. 添加导航

接下来让我们用另外一个 SVG 滤镜创建一个水斑动画。将以下导航内容添加到正文代码的最顶部,也就是本教程第一步中开始的标题之前。这将在一个圆内创建一个看上去像汉堡?的菜单图标。

代码语言:javascript
复制
 1<nav class="menu">
 2        <input type="checkbox" href="#" class=
 3        "menu-open" name="menu-open" id="menu-
 4        open" />
 5        <label class="menu-open-button" 
 6        for="menu-open">
 7            <span class="hamburger 
 8            hamburger-1"></span>
 9            <span class="hamburger 
10            hamburger-2"></span>
11            <span class="hamburger 
12            hamburger-3"></span>
13        </label>

14. 完成导航

现在添加其余的导航元素。我们使用 Font Awesome 开源图标库,该库已被添加到 head 部分,以便使用该库的CDN链接。每个菜单圆形元素都有一个图标。

代码语言:javascript
复制
1<a href="#" class="menu-item"> <i class="fa 
2fa-car"></i> </a>
3        <a href="#" class="menu-item"> <i 
4        class="fa fa-ship"></i> </a>
5        <a href="#" class="menu-item"> <i 
6        class="fa fa-map"></i> </a>
7        <a href="#" class="menu-item"> <i 
8        class="fa fa-suitcase"></i> </a>
9    </nav>

15. 添加新过滤器

接着为这个效果添加另一个过滤器。在SVG中,在先前添加的过滤器标记代码的后面添加以下代码。这里的效果用和前面非常相似的方式建立起来。这将使菜单看起来像粘稠的液体一样分开。

代码语言:javascript
复制
 1<filter id="shadowed-blob">
 2            <feGaussianBlur in="SourceGraphic" 
 3            result="blur" stdDeviation="20" />
 4            <feColorMatrix in="blur" mode=
 5            "matrix" values="1 0 0 0 0  0 1 0 0 
 6            0  0 0 1 0 0  0 0 0 18 -7" 
 7            result="blob" />
 8            <feGaussianBlur in="blob" 
 9            stdDeviation="3" result="shadow" />
10            <feColorMatrix in="shadow" mode=
11            "matrix" values="0 0 0 0 0  0 0 0 0 
12            0  0 0 0 0 0  0 0 0 1 -0.2" 
13            result="shadow" />

16. 完成过滤器

此处添加了过滤器的剩余部分,这将完成菜单项上的效果。并添加液体斑点效果。添加完代码后保存文件,然后切换到 'design.css' 文件。

代码语言:javascript
复制
1<feOffset in="shadow" dx="0" dy="2" 
2            result="shadow" />
3            <feComposite in2="shadow" in="blob" 
4            result="blob" />
5            <feComposite in2="blob" 
6            in="SourceGraphic" result="mix" />
7        </filter>

17.应用过滤器

CSS 代码也可以添加到其它文件中,但是为了将所有导航 CSS 放在同一个地方,我们还是把下面的代码写到 design.css 中。这里的过滤器会被用于菜单,这是一个固定的菜单,会始终显示在屏幕上。

代码语言:javascript
复制
 1.menu {
 2    filter: url(“#shadowed-blob");
 3    position: fixed;
 4    padding-top: 20px;
 5    padding-left: 80px;
 6    width: 650px;
 7    height: 150px;
 8    box-sizing: border-box;
 9    font-size: 20px;
10    text-align: left;
11}
12

18. 使菜单工作

当菜单打开时,菜单图标被设置为不可见。然后创建每个菜单项的悬停元素,以便当用户将鼠标悬停在上面时进行更改。当菜单项返回其原始位置时,菜单的每个子项都会有 0.4 秒的变换时间。

代码语言:javascript
复制
 1.menu-open {
 2    display: none;
 3}
 4.menu-item:hover {
 5    background: #47959f;
 6    color: #b2f0f8;
 7}
 8.menu-item:nth-child(3), .menu-item:nth-
 9child(4), .menu-item:nth-child(5), .menu-
10item:nth-child(6) {
11    transition-duration: 400ms;
12}

19. 添加菜单图标

更改菜单图标的 z-index 以将其置于顶部

通过更改其 z-index,菜单图标高于其他元素。当用户将鼠标悬停在菜单上时,菜单会滑出,单击菜单后其上的三条横线会变为 “X”,表示收起菜单。

代码语言:javascript
复制
 1.menu-open-button {
 2    z-index: 2;
 3    transition-timing-function: cubic-
 4    bezier(0.175, 0.885, 0.32, 1.275);
 5    transition-duration: 400ms;
 6    transform: scale(1.1, 1.1) translate3d
 7    (0, 0, 0);
 8    cursor: pointer;
 9}
10.menu-open-button:hover {
11    transform: scale(1.2, 1.2) translate3d
12    (0, 0, 0);
13}

20.移动元素

第一个菜单项实际上是菜单的第三个子项,因为它前面还有一个复选框和汉堡包样式的图标。添加这一项可使第一个菜单元素在用户单击菜单后移动到位。每个菜单元素都会以稍长的时间移出。

代码语言:javascript
复制
 1.menu-open:checked + .menu-open-button {
 2    transition-timing-function: linear;
 3    transition-duration: 400ms;
 4    transform: scale(0.8, 0.8) translate3d
 5    (0, 0, 0);
 6}
 7.menu-open:checked ~ .menu-item {
 8    transition-timing-function: cubic-
 9    bezier(0.165, 0.84, 0.44, 1);
10}
11.menu-open:checked ~ .menu-item:nth-child(3) {
12    transition-duration: 390ms;
13    transform: translate3d(110px, 0, 0);
14}

21.解决剩下的动作

以不同的速度移动菜单元素以获得更加流畅的效果

剩余的菜单元素以不同的速度移出来。这使得菜单元素能够在动画的早期阶段粘在一起,在这里用了 SVG 滤镜提供的斑点液体外观。添加下列代码后保存文件并在浏览器中查看完成的结果。

代码语言:javascript
复制
 1.menu-open:checked ~ .menu-item:nth-child(4) {
 2    transition-duration: 490ms;
 3    transform: translate3d(220px, 0, 0);
 4}
 5.menu-open:checked ~ .menu-item:nth-child(5) {
 6    transition-duration: 590ms;
 7    transform: translate3d(330px, 0, 0);
 8}
 9.menu-open:checked ~ .menu-item:nth-child(6) {
10    transition-duration: 690ms;
11    transform: translate3d(440px, 0, 0);
12}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-03-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端先锋 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 01. 开始
  • 02. 完成标题
  • 03. 创建一个 SVG 过滤器
  • 04. 隐藏 SVG
  • 05. 加入 headline
  • 06. 完成 headline
  • 07. 替换它
  • 08. 柔化边缘
  • 09. 组合两者
  • 10. 合并模糊
  • 11. 创建动画
  • 12. 更改 h2 样式
  • 13. 添加导航
  • 14. 完成导航
  • 15. 添加新过滤器
  • 16. 完成过滤器
  • 17.应用过滤器
  • 18. 使菜单工作
  • 19. 添加菜单图标
  • 20.移动元素
  • 21.解决剩下的动作
相关产品与服务
内容分发网络 CDN
内容分发网络(Content Delivery Network,CDN)通过将站点内容发布至遍布全球的海量加速节点,使其用户可就近获取所需内容,避免因网络拥堵、跨运营商、跨地域、跨境等因素带来的网络不稳定、访问延迟高等问题,有效提升下载速度、降低响应时间,提供流畅的用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档