编码花
首发于编码花
天边一朵云-书画双绝

天边一朵云-书画双绝

上一篇文章,我撸出了一片云。作为一个程序员,弄出一片以假乱真的云虽然很有成就感,但是怎么证明这朵云是写出来的而不是拍照的却很有些困难。而且这种技能树好像点的有些歪,毕竟从天上拍一张也不难,为啥要手工写呢?我作为一个有远见(推眼镜)的程序员,自然不是为了一朵无规则的云而大费周章,这次,我要让云做到书画(seyi)双绝,请称呼我为云工程师。

1、老方法做云

按照上次做云的方法,我们先把div搞出来

 <div class="cloud" id="cloud-back">天边一片云</div>

再把两个css弄出来

.cloud {
	font-size:150px;
	font-style:oblique;
	font-weight: 900;
  position: absolute;
  top: -42vh;
  left: -31vw;
}


#cloud-back {
  filter: url(#filter-back);
  text-shadow:420px 240px 10px #fff; 
}


和上一章的box-shadow不同,文字需要用到的是text-shadow,但参数类似

再用svg把云的样子弄出来

<svg width="0" height="0"> 
  <!--Top Layer-->
    <filter id="filter-back">
      <feTurbulence type="fractalNoise" baseFrequency="0.012" numOctaves="4" 
seed="0" />     
      <feDisplacementMap  in="SourceGraphic" scale="40" />
    </filter>
</svg>

这样单层的云就出来了。

但这种云没有层次感,所以方法也是一样,用三层从白到黑的来覆盖,造成明暗的光影效果。

<div class="cloud" id="cloud-back">天边一片云</div>
<div class="cloud" id="cloud-mid">天边一片云</div>
<div class="cloud" id="cloud-front">天边一片云</div>


.cloud {
	font-size:150px;
	font-style:oblique;
	font-weight: 900;
  position: absolute;
  top: -42vh;
  left: -31vw;
}

#cloud-back {
  filter: url(#filter-back);
  text-shadow:420px 240px 10px #fff; 
}

#cloud-mid {
  filter: url(#filter-mid);
  text-shadow:410px 250px 12px rgba(158, 168, 179, 0.3);
 }

#cloud-front {
  filter: url(#filter-front);
  text-shadow:410px 250px 14px rgba(0, 0, 0, 0.2);
}

其中主要调整text-shadow的color属性调整文字阴影的颜色(color),做到云的层次感,然后再调整svg

<svg width="0" height="0"> 
  <!--Top Layer-->
    <filter id="filter-back">
      <feTurbulence type="fractalNoise" baseFrequency="0.012" numOctaves="4" 
seed="0" />     
      <feDisplacementMap  in="SourceGraphic" scale="40" />
    </filter>
    <filter id="filter-mid">
        <feTurbulence type="fractalNoise"  baseFrequency="0.012" numOctaves="2" 
seed="0"/>
      <feDisplacementMap  in="SourceGraphic" scale="45" />
    </filter>
    <filter id="filter-front">
        <feTurbulence type="fractalNoise" baseFrequency="0.012" numOctaves="2" 
seed="0"/>
      <feDisplacementMap  in="SourceGraphic" scale="50" />
    </filter>
</svg>

调整svg的参数和上一章一样,主要是SourceGraphic的值,文字是有固定形状的,所以这个值不能太大,否则形状腐蚀的太厉害,那就看不清楚字了,三层叠加,就成了这个样子。

这样看起来就比较真实了。

2、我要来张图

刚才那种方法其实和上一章画云的方法没啥区别,只是把box-shadow换成了text-shadow而已,我觉得字都做了,不妨来个云图试试。

《云图》是由华纳兄弟影片公司制作的剧情片,由沃卓斯基姐弟(他们不是兄弟吗?)与汤姆·提克威联合执导,是一部到现在都算毁誉参半的科幻电影,我当年是冲着《黑客帝国》导演沃卓斯基兄弟(但为什么她们现在是姐妹,好莱坞真乱)看的,看完后完全一副不明觉厉的感觉,反正就是没看懂,所以我们开始画云图(本句上下文没有任何关联,只是都叫云图)。

我仍然打算按照老套路来,搞个图片先,我用的是透明底的剪影图片,这种样子的


当然,我原图用的是白颜色的,只是为了让大家看到,用了photoshop的截图,上了黑颜色。html的代码仍然用box-shadow,一切轻车熟路。

<img src="girl1.png" class="cloud" id="cloud-blur-back" />


.cloud {
  position: absolute;
}

#cloud-blur-back {
	box-shadow:5px 2px 6px #000
}

还没等我用上svg,就发现效果是这样子的。

阴影是针对图片这个方框的,和我想象的有很大出路啊。看来此路不通。难道我只能放弃?

----------------------------一个漫长搜索谷歌的分割线--------------------

终于让我找了一个更好的办法,那就是直接用svg,抛弃掉目前所有的shadow样式。仍然是图片。

<img src="girl1.png" class="cloud" id="cloud-blur-back" />


#cloud-blur-back {
  filter: url(#filter-blur-back);
}

我使用svg的feGaussianBlur filter

<svg width="0" height="0"> 
    <filter id="filter-blur-back">
      <feGaussianBlur in="SourceGraphic" stdDeviation="4" />
    </filter>
</svg>

feGaussianBlur其实和我们之前用的feTurbulence和feDisplacementMap师出同门,都是svg的filter,看名字中有blur,就知道是做模糊化的。而且参数也很简单,就是in和stdDeviation。

  • in这个参数我们目前只用到SourceGraphic就可以了,具体的内容,请自行查看这里
  • stdDeviation这个参数就更简单了,就是模糊化,数字越大越模糊。

我们看下效果如何:

效果不错哦。而且不像之前用shadow的方法,还要把原体移除窗口外,只显示阴影,这个方便多了。我继续轻车熟路的把feTurbulence加上,想看下云化的效果。

<svg width="0" height="0"> 
    <filter id="filter-blur-back">
      <feGaussianBlur in="SourceGraphic" stdDeviation="4" />
      <feTurbulence type="fractalNoise" baseFrequency="0.02" numOctaves="5" seed="0"/>     
      <feDisplacementMap  in="SourceGraphic" scale="30" />
    </filter>
</svg>
毫无效果,场面一度很尴尬

结果只有feGaussianBlur 的模糊化效果,feTurbulence的效果一点都没有,看来前路有坑啊。

--------------------------一个漫长的各种尝试的分割线--------------------

终于,我找到了解决办法,把feGaussianBlur 和feTurbulence分拆成两个filter,代码是这样的。

<svg width="0" height="0"> 
    <filter id="filter-blur-back">
      <feGaussianBlur in="SourceGraphic" stdDeviation="4" />
    </filter>
    <filter id="filter-div-back">
      <feTurbulence type="fractalNoise" baseFrequency="0.02" numOctaves="5" seed="0"/>     
      <feDisplacementMap  in="SourceGraphic" scale="30" />
    </filter>
</svg>

filter-blur-back和filter-div-back的顺序不同,效果也会有不同:

#cloud-blur-back {
	filter: url(#filter-blur-back) url(#filter-div-back);
}


filter-blur-back在前,filter-div-back在后
#cloud-blur-back {
	filter: url(#filter-div-back) url(#filter-blur-back) ;
}
filter-blur-back在后,filter-div-back在前

上面那种看起来更象云一些,我们就用这种啦。我继续我的云图创作,把三层效果加上,完整的代码是这样的

<html>
<head>
<style type="text/css">
	body {
  width: 100vw;
  height: 100vw;
  background: linear-gradient(165deg, #527785 0%, #7FB4C7 100%);
  padding: 1%;
}

.cloud {
  position: absolute;
}

#cloud-blur-back {
  filter: url(#filter-blur-back) url(#filter-div-back);
}

#cloud-blur-mid {
	transform:scale(0.95);
  filter: brightness(90%) url(#filter-blur-mid) url(#filter-div-back);
  left: 1vw;
  top: 1vw;
}

#cloud-blur-front {
	transform:scale(0.9);
  filter: brightness(80%) url(#filter-blur-front) url(#filter-div-back);
left: 1vw;
  top: 1vw;
}

</style>
</head>
<body>
	<img src="girl1.png" class="cloud" id="cloud-blur-back" />

	<img src="girl1.png" class="cloud" id="cloud-blur-mid" />

	<img src="girl1.png" class="cloud" id="cloud-blur-front" />


<svg width="0" height="0"> 
    <filter id="filter-blur-back">
      <feGaussianBlur in="SourceGraphic" stdDeviation="3" />
    </filter>
    <filter id="filter-div-back">
      <feTurbulence type="fractalNoise" baseFrequency="0.02" numOctaves="5" seed="0"/>     
      <feDisplacementMap  in="SourceGraphic" scale="30" />
    </filter>
    
    <filter id="filter-blur-mid">
      <feGaussianBlur in="SourceGraphic" stdDeviation="4" />
    </filter>
    <filter id="filter-div-mid">
      <feTurbulence type="fractalNoise" baseFrequency="0.012" numOctaves="3" seed="0" />     
      <feDisplacementMap  in="SourceGraphic" scale="25" />
    </filter>
    
    <filter id="filter-blur-front">
      <feGaussianBlur in="SourceGraphic" stdDeviation="5" />
    </filter>
    <filter id="filter-div-front">
      <feTurbulence type="fractalNoise" baseFrequency="0.012" numOctaves="2" seed="0" />     
      <feDisplacementMap  in="SourceGraphic" scale="20" />
    </filter>
</svg>
</body>
</html>

最后看到的效果如下:

为了调节层次感,我加上了缩放的调节,transform:scale()。

为了调节三层的明暗,我加上了filter: brightness()来调节图片使其变暗。

请大家欣赏下我搞的几张图(就这破玩意我能换图玩一下午)。

这些图片需要白色透明底的png图片,我都是从阿里巴巴的矢量图标库找的,里面有很多这种图,大家可以自己试试,也可以去调调参数,会有不同的效果。

源代码地址

编辑于 2019-06-24

文章被以下专栏收录