云破月来花弄影-SVG多种技术组合实现

天仙子·水调数声持酒听css

【宋】张先git

水调数声持酒听,午醉醒来愁未醒。送春春去几时回?临晚镜,伤流景,往过后期空记省。
沙上并禽池上暝,云破月来花弄影。重重帘幕密遮灯,风不定,人初静,明日落红应满径。github

昨天七夕,下班在地铁里面看到了各类恩爱撒狗粮的,不由想起当年情窦初开的时候,很是喜欢宋词。而张先,由于“影”字用的好,被称为“张三影”,这首词就是三影之一(不是火影)。回到家,小孩和老婆都睡了(996害死人啊),但心中的火却旺的很,右手也不安份。我想到今天多少对情侣在那啥,我却只能一我的,心中躁动不已,艺术之魂熊熊燃烧,我控制住右手,强行挪开了点击某hub网站的冲动,点开了另外一个某hub网站,开始了个人艺术创做。bash

一、月来

用svg作个月亮仍是很简单的,只要画一个发光的大圆饼就行了,上代码。svg

<circle id="whitemoon" cx="420" cy="160" r="60" fill="white" />复制代码

上帝说,要有光,那就来个光wordpress

<filter id="blur-moon">
                <feGaussianBlur in="SourceGraphic" stdDeviation="3" />
</filter>复制代码

用feGaussianBlur模糊后的做为月亮的光,和大圆饼合起来,就是一个发光的月亮了网站

<use xlink:href="#whitemoon" />
<use xlink:href="#whitemoon" filter="url(#blur-moon)" />复制代码

这个月亮圆也很圆,亮也很亮,可是做为一个现代人,我知道月亮上是有环形山的,这么洁白无暇的月亮太假了,因此还要加点黑影。ui

<circle id="greymoon" cx="420" cy="170" r="45" fill="grey" fill-opacity="0.15"
                filter="url(#filter-greymoon)" />
<filter id="filter-greymoon" >
                <feTurbulence type="fractalNoise" baseFrequency="0.03" numOctaves="9" seed="3" />
                <feDisplacementMap in="SourceGraphic" scale="120" />
            </filter>复制代码

看过前面作云文章的朋友都知道,feTurbulence和feDisplacementMap的组合用来作纹理和腐蚀效果是很好的,这里也用来作月亮的黑影,这里须要说明一个知识点,这个问题以前其实困扰了我好久。url

咱们使用filter特效的时候,若是效果超出了图形自己的矩形框范围,那么效果会在矩形框范围直接切断,好比上面这个greymoon,显示出来是这样的spa

明显能够看出左边切掉了一块,很是影响效果,去掉边界的限制在哪呢?就在filter的属性,这个例子里面,我改为这样就行了

<filter id="filter-greymoon" height="250%" width="250%" x="-100%" y="-100%">复制代码

把filter的width,hegith加宽加高,单这样还不行,由于width,height只能影响图形的右边和下边,结果效果只是这样

能够看到,左边和上边仍然被无情的截取了,因此必须把x,y参数加上去,由于是向左和向上,在坐标原点前,因此是负数,最终的效果以下

最后把阴影加到大月亮上去,就能看到最终效果了

<circle id="whitemoon" cx="420" cy="160" r="60" fill="white" />
            <circle id="greymoon" cx="420" cy="170" r="30" fill="grey" fill-opacity="0.25"
                filter="url(#filter-greymoon)" />
<filter id="filter-greymoon" width="350%" height="250%" x="-100%" y="-100%">
                <feTurbulence type="fractalNoise" baseFrequency="0.03" numOctaves="9" seed="3" />
                <feDisplacementMap in="SourceGraphic" scale="120" />
            </filter>
<g id="moon">
                <use xlink:href="#whitemoon" />
                <use xlink:href="#whitemoon" filter="url(#blur-moon)" />
                <use xlink:href="#greymoon" filter="url(#blur-greymoon)" />
</g>
<use xlink:href="#moon" />复制代码

一个比较真实的月亮就作好了(不要和我提阴影和真实的月面状况不同,我又不是华为手机的AI拍摄,能自动把真实月面给P出来)。

二、云破

月亮作出来了,咱们开始作云。以前在作云的文章里面其实已经很详细的讲了作云的方法,因此我这边就不详细讲了。不过此次咱们搞点新花样,不用css的box-shadow来作,直接使用svg来作,代码会更简洁。

<defs>
<ellipse id="cloudback" cx="260" cy="230" rx="280" ry="70" fill="white" fill-opacity="0.9"
                filter="url(#blur-cloud)" />
            <ellipse id="cloudmid" cx="260" cy="240" rx="220" ry="55" fill="#9EA8B3" fill-opacity="0.5"
                filter="url(#blur-cloud)" />
            <ellipse id="cloudfront" cx="260" cy="260" rx="170" ry="30" fill="black" fill-opacity="0.2"
                filter="url(#blur-cloud)" />
<filter id="blur-cloud" width="350%" height="250%" x="-100%" y="-100%">
                <feGaussianBlur in="SourceGraphic" stdDeviation="15" />
            </filter>
<filter id="filter-back" width="350%" height="250%" x="-100%" y="-100%">
                <feTurbulence type="fractalNoise" baseFrequency="0.012" numOctaves="4" seed="0" />
                <feDisplacementMap in="SourceGraphic" scale="170" />
            </filter>
            <filter id="filter-mid" width="350%" height="250%" x="-100%" y="-100%">
                <feTurbulence type="fractalNoise" baseFrequency="0.012" numOctaves="4" seed="0" />
                <feDisplacementMap in="SourceGraphic" scale="150" />
            </filter>
            <filter id="filter-front" width="350%" height="250%" x="-100%" y="-100%">
                <feTurbulence type="fractalNoise" baseFrequency="0.012" numOctaves="4" seed="0" />
                <feDisplacementMap in="SourceGraphic" scale="100" />
            </filter>
<g id="cloud">
                <use xlink:href="#cloudback" filter="url(#filter-back)" />
                <use xlink:href="#cloudmid" filter="url(#filter-mid)" />
                <use xlink:href="#cloudfront" filter="url(#filter-front)" />
            </g>
</defs>
<use xlink:href="#cloud" />复制代码

最后的效果以下

三、花弄影

在这里咱们先须要一堵墙,不然影子在哪显示呢,因此我就上花瓣网找了一堵墙过来。图片地址在这里

针对原图我作了一点处理,主要是把墙面搞暗了一些,把图片的天空部分变成了透明,方便显示月亮和云,使用的一样是svg的图片显示

<image xlink:href="yuanqiang1.png" x="0" y="300" width="400"/>复制代码

而后是花影,要有花影,首先得有花,一样的,我又从花瓣网弄来了一束花。图片地址忘了存,找不到了┐(゚~゚)┌

<image xlink:href="huazhi1.png" x="200"y="690" width="170"></image>复制代码

如今关键来了,花弄影主要是影,咱们开始光影的魔法。

<filter id="huazhishadow" x="0" y="0" width="200%" height="200%">
                <feOffset result="offOut" in="SourceAlpha" dx="210" dy="0" />
                <feGaussianBlur result="blurOut" in="offOut" stdDeviation="1" />
                <feBlend in="SourceGraphic" in2="blurOut" mode="darken" />
            </filter>复制代码

先介绍下这几个filter:

feoffset:该输入图像做为一个总体,在属性dx和属性dy的值指定了它的偏移量。说白了就是把原图在离开dx和dy的距离外复制一个同样的图像,活脱脱的拷贝魔法,这就是filter界的旗木卡卡西啊。

feGaussianBlur:老朋友,干模糊化的,略

feBlend:把两个对象组合在一块儿,使它们受特定的混合模式控制。这相似于图像编辑软件中混合两个图层。它是个粘合剂,把上面两个filter的效果合在一块儿,而且用mode来控制最后的效果。mode的效果有不少种,咱们这边须要的是影子,因此选择了darken,具体的mode说明,请看这里

<image xlink:href="huazhi1.png" x="0" y="600" width="170" filter="url(#huazhishadow)" />复制代码

最后看到的是这样

对话录:

画外音:是否是这样就算作好了

我:固然没有,你没发现我选的这个墙不是平面的吗

画外音:那又怎样

我:这样影子打上去应该是斜的,不是这样平平的影子

画外音:为啥你不选个正平墙的图呢

我:花瓣上没找到啊...

画外音:你为啥要执着于这个影子效果呢,用如今这个就好了

我:不行,我是个严谨的艺术家,个人影子要真实,真实,再真实

画外音:那刚才月亮的阴影你咋不追求真实的月面阴影呢

我:.....,警察叔叔,就是这个声音给我打的诈骗电话,立刻抓他去坐牢。

我:让你和我抬杠

画外音:算你狠...

-------------------------------------------------------我是分割线----------------------------------------------

咱们须要把花的图片和花的影子分开处理,如今咱们把生成影子的花弄出屏幕外

<image xlink:href="huazhi1.png" x="-630" y="720" width="170" filter="url(#huazhishadow)">复制代码

经过x的设置,把花的图像移到 屏幕外,只留下影子

<image xlink:href="huazhi1.png" x="-630" y="720" width="170" filter="url(#huazhishadow)" transform="skewX(29)"/>复制代码

这里要讲下transform:

transform和上面这些filter不一样,是SVG元素的属性。做用是设置svg元素的变形,包括位移translate, 旋转rotate, 缩放scale, 斜切skew。今天咱们用到的就是斜切(skew)。具体的你们能够去看这篇文章,讲的很详细。最后的花影的效果以下:

四、成品

当咱们把月亮,云、院墙和花影组合起来,就能够看到最终的效果了

<image xlink:href="yuanqiang1.png" x="0" y="300" width="400"/>
        <use xlink:href="#moon" />
        <use xlink:href="#cloud" />
        <image xlink:href="huazhi1.png" x="200"y="690" width="170"></image>
        <image xlink:href="huazhi1.png" x="-630" y="720" width="170" filter="url(#huazhishadow)" transform="skewX(29)"/>复制代码

源码地址

在线围观

相关文章
相关标签/搜索