关于前端:巧用-SVG-滤镜还能制作表情包

43次阅读

共计 5345 个字符,预计需要花费 14 分钟才能阅读完成。

本文将介绍一些应用 SVG feTurbulence 滤镜实现的一些乏味、大胆的的动效。

系列另外两篇:

  • 有意思!弱小的 SVG 滤镜
  • 有意思!不规则边框的生成计划

背景

明天在群外面聊天,看到有人发这个表情包:

刚好最近始终在学习 SVG,脑海中就把这个表情包的成果和 feTurbulence 滤镜关联了起来。

如果咱们有一张相似上图表情包的动态图,利用 feTurbulence 生成的噪声函数,使用在动态的表情包之上,再增加些许动画,是不是也能制作一张相似的动图成果呢?

什么是 SVG feTurbulence 滤镜?

如果你对 SVG 滤镜还不算太理解,能够简略看看我的这篇文章入门:有意思!弱小的 SVG 滤镜

这里咱们会用到 SVG 中的 feTurbulence 滤镜。再简略介绍下。

feTurbulence 滤镜

turbulence 意为湍流,不稳固气流,而 SVG <feTurbulence> 滤镜可能实现半透明的烟熏或波状图像。通常用于实现一些非凡的纹理。滤镜利用 Perlin 噪声函数创立了一个图像。噪声在模仿云雾成果时十分有用,能产生非常复杂的质感,利用它能够实现了人造纹理比如说云纹、大理石纹的合成。

简略看个 DEMO:

<div>Coco</div>
<div class="turbulence">Coco</div>

<svg>
    <filter id="fractal" filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">
        <feTurbulence id="turbulence" type="fractalNoise" baseFrequency="0.03" numOctaves="1" />
        <feDisplacementMap in="SourceGraphic" scale="50"></feDisplacementMap>
    </filter>
</svg>
.turbulence {filter: url(#fractal);
}

右边是失常的成果,后边是利用了 <feTurbulence> 的成果,你能够试着点进 Demo,更改 baseFrequencynumOctaves 参数的大小,能够看到不同的成果:

CodePen Demo — feTurbulence text demo

feTurbulence 滤镜利用于图片

咱们尝试把上述 DEMO 中的文字转换成图片。我找到了一张动态的哭的表情包:

简略革新下代码:

<div></div>
<svg>
    <filter id="fractal" filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">
        <feTurbulence id="turbulence" type="fractalNoise" baseFrequency="0.09" numOctaves="1" ></feTurbulence>
        <feDisplacementMap in="SourceGraphic" scale="15"></feDisplacementMap>
    </filter>
</svg>
div {background: url(image.jpg);
    filter: url(#fractal);
}

成果如下:

有点那个意思了,咱们通过 feTurbulence 滤镜失去了噪声图形,而后通过 feDisplacementMap 滤镜依据 feTurbulence 所产生的噪声图形进行形变,扭曲,液化,失去最终的成果。

通过调整 feTurbulence 中的 baseFrequencynumOctaves 以及 feDisplacementMap 中的 scale 参数,咱们能够调试失去不同的成果。

接下来,咱们再给上述滤镜增加一个动画,利用 SVG 的 animate 标签,动静的扭转 baseFrequency 参数:

<svg>
    <filter id="fractal" filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">
        <feTurbulence id="turbulence" type="fractalNoise" baseFrequency="0.1 0.1" numOctaves="1" >
            <animate
                    attributeName="baseFrequency"
                    from="0.1 0.1"
                    to="0.08 0.01"
                    dur="3.5s"
                    repeatCount="indefinite"/>
        </feTurbulence>
        <feDisplacementMap in="SourceGraphic" scale="15"></feDisplacementMap>
    </filter>
</svg>

增加了动画之后,同样作用于图片之上,咱们就能够失去如下的成果:

因为截图软件的帧率问题,看着有点慢,你能够戳进 DEMO 看看实际效果,还是挺有意思的,至此咱们就简略的利用 CSS 配合 SVG 的形式,通过一张动态图失去了一个动静的表情包啦。

CodePen Demo — 应用 SVG 滤镜 feTurbulence 让图片动起来

巧用 feTurbulence 滤镜实现各种动效

嘿,feTurbulence 当然不是仅能实现这个而已,上面咱们再摸索一些有意思的场景。

首先,再明确下咱们次要应用到的两个滤镜 feTurbulencefeDisplacementMap,它们的外围代码:

<svg>
    <filter id="feDisplacementMap" filterUnits="userSpaceOnUse" x="0" y="0" width="200" height="64">
        <feTurbulence type="fractalNoise" baseFrequency="0.0995" numOctaves="1" result="img" />
        <feDisplacementMap id="feDis" in="SourceGraphic" in2="img" scale="600" />
    </filter>
</svg>

其中滤镜中的几个参数 — baseFrequencynumOctavesscale 的扭转其实都会失去不一样的成果。咱们动静的变动其中的一个或多个也都能够失去不同的动画成果。

动静扭转 feDisplacementMapscale 的参数

feDisplacementMap 滤镜是用于扭转元素和图形的像素地位的。该滤镜通过遍历原图形的所有像素点,通过 feTurbulence 滤镜产生的噪声函数将原图像的每个像素点从新映射到一个新的地位,造成一个新的图形。

scale 示意新失去的图像的扭曲水平,这个值越大,图像越加扭曲不可辨认。

通过设置一个十分大初始值,咱们能够齐全将输出的任何源图像粒子化,看看这个 Demo:

<div></div>
<div class="fractal"></div>

<svg viewBox="0 0 200 200" width="200px" height="200px">
    <defs>
        <filter id="fractal" filterUnits="userSpaceOnUse" x="0" y="0" width="200" height="200">
            <feTurbulence type="fractalNoise" baseFrequency="0.995" numOctaves="10" seed="1" stitchTiles="noStitch" result="img" />
            <feDisplacementMap in="SourceGraphic" in2="img" xChannelSelector="R" yChannelSelector="G" scale="600" />
        </filter>
    </defs>
</svg>
div {
    width: 200px;
    height: 200px;
    background: url(image.jpeg)
}

.fractal {filter: url(#fractal);
}

右边为失常的图像,左边为作用了设置了 SVG 滤镜成果的图像,并且设置了 scale="600",齐全将图片粒子化了:

这个时候,让滤镜的 scale="600" 动态变化回 scale="1"(当此参数为 1 时,图像示意为失常状态),也就能实现一个图形从粒子化到正常化的转变:

<svg viewBox="0 0 200 200" width="200px" height="200px">
    <filter id="fractal" filterUnits="userSpaceOnUse" x="0" y="0" width="200" height="200">
        <feTurbulence type="fractalNoise" baseFrequency="0.995" numOctaves="10" seed="1" result="img" />
        <feDisplacementMap in="SourceGraphic" in2="img" xChannelSelector="R" yChannelSelector="G" scale="600">
            <animate attributeName="scale" values="600;0;0" keyTimes="0;0.75;1" begin="0s" dur="2s" repeatCount="indefinite" />
        </feDisplacementMap>
    </filter>
</svg>

成果如下:

CodePen — SVG Filter feTurbulence & feDisplacementMap 实现图片粒子化还原动画

动静扭转 feDisplacementMapscale 的参数实现一些开奖动效

基于上述的成果,咱们能够实现这样一类成果,譬如一些开奖后果,一开始它是含糊的,然而用户点击之后,含糊的后果逐步从含糊到实在。

然而点击事件,因为 SVG Animate 标签的一些限度,须要借助一些 Javascript 代码,这里借用 JQuery 简略做个示意。

咱们有一串开奖数组 745846,实现点击之后从含糊到实在:

<div id="fe1" class="fe1">745846</div>
<svg>
    <filter id="feDisplacementMap" filterUnits="userSpaceOnUse" x="0" y="0" width="200" height="64">
        <feTurbulence type="fractalNoise" baseFrequency="0.0995" numOctaves="1" result="img" />
        <feDisplacementMap id="feDis" in="SourceGraphic" in2="img" scale="200" />
    </filter>
</svg>
$("#fe1").click((e) => {const filter = $("#feDis");
    const startTime = Date.now();
    const duration = 1000;
    const target = 200;
    
    requestAnimationFrame(function aniMove() {const t = Math.min(1, (Date.now() - startTime) / duration);
        const nextTarget = target - (t * target) + 1;
        
        filter.attr('scale', nextTarget);

        if (t < 1.0) {requestAnimationFrame(aniMove);
        }
    });
});

点击之前的状态如下:

点击之后:

上述成果,你能够套用到任何中央,残缺的 Demo 地址:

CodePen Demo — SVG Filter Button Effects

动静扭转 feDisplacementMapscale 的参数实现一些 fadeOut 动画

当然,上述的成果也是能够反着来的,就是一张图(或者任何元素),点击之后粒子化,而后突变的隐没,进阶版的 fadeOut 成果。

通过动静的扭转滤镜的参数和图片的透明度,当然,也须要借助一些 JavaScript 代码,残缺的代码就不贴了,间接上效果图:

是不是十分相似灭霸把人物隐没的成果?之前看过这样一篇文章 – 谷歌灭霸彩蛋的成果实现,其中介绍了一种应用 Canvas 实现相似成果的形式,本文这里应用 SVG 滤镜达成了近似的成果。

对源码感兴趣的能够猛戳上面的 Demo,成果也是能够不便的移植到其余元素之上:

CodePen Demo — 应用 SVG 滤镜实现任意元素粒子化 FadeOut 成果

不要吹灭你的灵感和你的想象力; 不要成为你的模型的奴隶。——文森特・梵高

最初

好了,本文到此结束,心愿对你有帮忙 :)

更多精彩 CSS 技术文章汇总在我的 Github — iCSS,继续更新,欢送点个 star 订阅珍藏。

想 Get 到最有意思的 CSS 资讯,千万不要错过我的公众号 — iCSS 前端趣闻 😄

如果还有什么疑难或者倡议,能够多多交换,原创文章,文笔无限,满腹经纶,文中若有不正之处,万望告知。

正文完
 0