svg filter|画朵云

·  阅读 311
svg filter|画朵云

「行到水穷处,坐看云起时」,是我很喜欢的一句诗,越是山穷水尽,越是无能为力,越应释怀。

扯远了,今天来讨论运用CSS+SVG画朵云

一些基础知识

box-shadow属性

box-shadow允许添加一个或多个阴影。

box-shadow: <offsetX> <offsetY> <blurRadius> <spreadRadius> <color>;
复制代码

offsetXoffsetY分别指定阴影在横轴和纵轴上的位置。

blurRadius 指定模糊量,并描述阴影的锐度或模糊程度。

spreadRadius处理两个值。正值会增加阴影的大小,而负值会减小阴影的大小。

.cloud {
    width: 250px; height: 250px;
    margin:20px auto;
    background:#fff;
    box-shadow: 200px 200px 50px 0px #000;
}
复制代码

image.png

filter属性和<filter>元素

  • filter(滤镜):CSS属性将模糊或颜色偏移等图形效果应用于元素。滤镜通常用于调整图像,背景和边框的渲染,具体参数可参考-filter

我们用到的是url():获取指向SVG过滤器的URI,该 SVG filter 可以嵌入到外部XML文件中。

  • <filter>元素

为了定义过滤器,SVG 使用了<filter>元素。该<filter>元素使用id属性来唯一标识,没有调用时不会渲染。

<feDisplacementMap><feTurbulence>

  1. <feDisplacementMap>:映射置换滤镜,通俗来讲就是改变元素和图形的像素位置的,使用feDisplacementMap重新映射替换一个新的位置,形成一个新的图形。

因此,feDisplacementMap滤镜在业界的主流应用是对图形进行形变,扭曲,液化。

映射原理: 引自MDN文档

P'(x,y) ← P( x + scale * (XC(x,y) - 0.5), y + scale * (YC(x,y) - 0.5))

  • P'(x,y)指的是转换之后的x, y坐标
  • x + scale * (XC(x,y) - 0.5), y + scale * (YC(x,y) - 0.5)指的是具体的转换规则。
  • XC(x,y)表示当前x,y坐标像素点其X轴方向上设置的对应通道的计算值,范围是0~1。
  • YC(x,y)表示当前x,y坐标像素点其Y轴方向上设置的对应通道的计算值,范围是0~1。
  • -0.5是偏移值,因此XC(x,y) - 0.5范围是-0.5~0.5, YC(x,y)-0.5范围也是-0.5~0.5。
  • scale表示计算后的偏移值相乘的比例,scale越大,则偏移越大。

用法

<feDisplacementMap in2="" in="" scale="" xChannelSelector="" yChannelSelector="" ```
color-interpolation-filters=""
```/>
复制代码
  • in -原始图形
  • in2 -用来映射的图形。它的工作原理与in属性相同。

inin2都表示输入,支持的属性值也都是一样的,固定的属性值关键字SourceGraphicSourceAlphaBackgroundImageBackgroundAlphaFillPaintStrokePaint;以及自定义的滤镜的原始引用(取值含义可参考MDN

in一般取SourceGraphic就好了,表示使用该filter元素的图形作为原始图像

  • scale -就是公式里面的缩放比例,可正可负,默认是0。通常使用正数值处理,值越大,偏移越大。
  • xChannelSelector -表示X轴坐标使用的是哪个颜色通道进行位置偏移。(R\G\B\A四个通道)
  • yChannelSelector -表示Y轴坐标使用的是哪个颜色通道进行位置偏移。
  • color-interpolation-filters 表示滤镜对颜色进行计算时候采用的颜色模式类型。分为linearRGB(默认值)和sRGBsRGB是我们平常用的RGB颜色。

2.<feTurbulence>该滤镜利用Perlin噪声函数创建了一个图像。它实现了人造纹理比如说云纹、大理石纹的合成。

<feTurbulence  baseFrequency="0.01" numOctaves="1" stitchTiles="stitch" seed="53" type="turbulence"/>
复制代码

属性:

  • baseFrequency 表示噪声的基本频率参数,默认值是0,频率越高,噪声越密集
  • numOctaves 倍频的数量,默认值是1,不能是小数,只能是整数,如果是小数会当作默认值1处理。倍频的数量越多,噪声看起来越自然,但是也会带来更多的计算,对性能会产生负面影响
  • seed 伪随机数生成的起始值,改变的是噪声的形状和位置
  • stitchTiles 定义了Perlin噪声在边框处的行为表现,noStitch(默认值,不平滑)|stitch(平滑)
  • type 滤镜类型 turbulence(默认值。表示湍流、混乱)|fractalNoise(分形噪声)

结合这两个属性,我们可以得到这样的效果

<div class="cloud"></div>
<svg width="0" height="0">
    <filter id="cloud">
      <feTurbulence type="fractalNoise" baseFrequency="0.012" numOctaves="4" seed="0" /> 
      <feDisplacementMap in="SourceGraphic" scale="170" />
    </filter>
</svg>
复制代码
.cloud {
    width: 250px; height: 250px;
    margin:20px auto;
    background:#fff;
    filter: url(#cloud);
}
复制代码

image.png

PS:这些属性着实晦涩难懂,如果你和我一样初学的话,可以实践一下,分别改变这些属性的参数来理解分别影响了什么,如果想要详细深入了解,推荐大佬博客feDisplacementMapfeTurbulence

经实践: <feDisplacementMap>scale越大,云会越“碎”,即偏离的越多; <feTurbulence>baseFrequency越大,噪点越多;numOctaves越大细节越丰富

真实的云

给云加个圆角,此时云的形状已经出来了

.cloud {
    width: 250px; height: 250px;
    margin:20px auto;
    background:#fff;
    filter: url(#cloud);
    border-radius: 50%;
}
复制代码

image.png

为了增加模糊的效果,我们把背景颜色去掉而改用阴影实现,云的效果实现

.cloud {
    width: 250px; height: 250px;
    margin:20px auto;
    /*background:#fff;*/
    box-shadow: 400px 400px 60px 0px #fff;
    filter: url(#cloud);
    border-radius: 50%;
    position: absolute;
    top: -320px;
    left: -320px;
}
复制代码

image.png

此时的云缺乏层次,为了更真实一点,我们需要给它增添一点阴影

<div class="bg">
<div class="cloud">
    <i class="cloud-basic"></i>
    <i class="cloud-mid"></i>
    <i class="cloud-shadow"></i>
</div>
<svg width="0" height="0" style="position:absolute;">
     <filter id="filter-basic">
      <feTurbulence type="fractalNoise" baseFrequency="0.012" numOctaves="4" seed="0" />     
      <feDisplacementMap  in="SourceGraphic" scale="170" />
    </filter>
       <filter id="filter-mid">
        <feTurbulence type="fractalNoise"  baseFrequency="0.012" numOctaves="2" seed="0"/>
      <feDisplacementMap  in="SourceGraphic" scale="150" />
    </filter>
    <filter id="filter-shadow">
        <feTurbulence type="fractalNoise" baseFrequency="0.012" numOctaves="2" seed="0"/>
      <feDisplacementMap  in="SourceGraphic" scale="100" />
    </filter>
</svg>
</div>

复制代码
.bg{
    width:900px;
    height:600px;
    background-color: #203f64;
    overflow: hidden;
    position: relative;
}
.cloud {
    width: 500px; height: 250px;
    margin: 3rem auto;
}
.cloud > i {
    position: absolute;
    width: inherit; height: inherit;
    border-radius: 50%;
    top: -280px;
    left: -320px;
    position: absolute;
}
.cloud-basic {
    filter: url(#filter-basic);
    box-shadow: 300px 300px 30px -20px #fff;
}
.cloud-mid {
    filter: url(#filter-mid);
    box-shadow: 300px 340px 70px -60px rgba(158, 168, 179, 0.5);
    left: -25vw;
}
.cloud-shadow {
    filter: url(#filter-shadow);
    box-shadow: 300px 370px 60px -100px rgba(0, 0, 0, 0.3);
    left: -25vw;
}
复制代码

image.png

换个颜色

image.png

~手动分割~
附一张前段时间油画棒涂的云

WechatIMG316.jpeg

分类:
前端
标签:
分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改