@Gizmosir
2016-03-19T04:31:44.000000Z
字数 12660
阅读 773
date: 2016-03-
categories: Computer graphics
tag: [SVG, 矢量图]
博客
这是矢量图像的第四篇,如果你没有看过之前的文章,可以点击:
在这一篇中我们将来通过学习制作个性名片的方式来实战练习之前介绍过的SVG知识。首先来欣赏一些很棒的SVG个性名片。
实际上个性名片可以天马行空的随意运用之前介绍过的任意一种滤镜或少数几种。但是为了能够更好地综合运用SVG知识,这里对我们最后的名片效果有几个要求:
首先我们来做比较简单的部分:名片背景以及阴影。首先生成一个1000*600的黑色矩形:
<!--这里我使用黑色填充是因为名片的基色调为黑色。-->
<rect x="0" y="0"
width="1000" height="600"
style="fill:black" />
接着用feGaussianBlur
滤镜来生成名片的阴影:
<!--首先生成一个高斯模糊滤镜,并模糊黑色的矩形输入,将其偏
移到后下角,接着调整其颜色使阴影变成灰色。-->
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" >
<defs>
<filter id="shadow"
color-interpolation-filters = "sRGB">
<feGaussianBlur in = "SourceGraphic" stdDeviation = "10"/>
<feOffset dx = "20" dy = "20" /> <!-- result = "blur" in = "blur" -->
<feColorMatrix type="matrix" result = "offsetBlur"
values="0 0 0 0 0.5
0 0 0 0 0.5
0 0 0 0 0.5
0 0 0 1 0" />
</filter>
</defs>
<rect x="100" y="100"
width="1000" height="600"
style="filter:url(#shadow); " transform = "translate(500, 200) scale(0.8, 0.8) skewX(-20)"/>
<rect x="100" y="100"
width="1000" height="600"
style="fill:black;"/>
</svg>
名片当然最好能够加上所在公司的logo,可是一般的方法又直接降低了我们名片的逼格。一个很好的方法就是用feConvolveMatrix
滤镜来提取logo的边缘,然后使用高斯滤镜模糊一点,最后设置合适的透明度并添加到背景矩形上。
<filter id="logo"
color-interpolation-filters="sRGB">
<feImage xlink:href="http://7xjz11.com1.z0.glb.clouddn.com/logo.png?imageView/2/w/200/h/147" width="200" height="147" />
<feConvolveMatrix
kernelMatrix="1 1 1 1 -8 1 1 1 1"
order="3 3"
divisor="1"
bias="0"
preserveAlpha="true"/>
<feGaussianBlur stdDeviation="3"/>
<feColorMatrix type="luminanceToAlpha"/>
<feTile x="100" y="100" width="1000" height="600"/>
</filter>
接下来我们来添加文本信息到名片上。为了延续我们名片高大上的格调,我们使用渐变字体并且给名字加上阴影。
<filter id="text"
color-interpolation-filters="sRGB">
<feGaussianBlur in="SourceAlpha" stdDeviation="2"/>
<feOffset dx="5" dy="5" result="text_2"/>
<feBlend mode="normal" in="SourceGraphic" in2="text_2"/>
</filter>
<g fill="url(#lineargradient2)">
<text id="nameText" x="540" y="260" style="font-size:60;font-family:verdana;font-weight:bold;filter:url(#text)">Zheng Jiongbin</text>
<text x="600" y="380" style="font-size:32;font-family:arial;font-style:italic;" >
<tspan x="600" >Nephovision Co.,Ltd</tspan>
<tspan x="600" dy="60">iOS/Algorithm Engineer</tspan>
<tspan x="600" dy="40">Gizmosir@Nephovision.com</tspan>
</text>
</g>
首先把个人头像从照片上“扣”下来。主要有三种不同的做法,第一种是用裁剪路径。
如果你不想手动一个一个算裁剪路径点的话,这里推荐使用一款叫SVGEdit的能够轻松在网页上编辑SVG的工具。只需将你的图片插入到网页上,然后点点点就能轻松生成裁剪路径,然后再把路径粘贴到你的代码中。
<!--首先定义我在网页上生成的剪裁路径,接着读取图片,并声明一个色彩矩阵用于将头像外的背景透明化,然后将色彩矩阵与头像复合并应用到一个黑色矩形上。-->
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="800"
height="800" >
<defs>
<path fill="white" id="path_area" d="m332,176l-118.66667,85.33333l20,92l-18.66667,6.66667l20,89.33333l20,1.33333l22.66667,69.33333l56,44l49.33333,2.66667l66.66667,-56l16,-56l21.33333,-5.33333l20,-73.33333l-13.33333,-16l17.33333,-82.66667l-52,-77.33333l-126.66667,-24z"/>
<filter id="photo_with_background"
color-interpolation-filters="sRGB">
<feImage x="-2%" y="7%" width="70%" height="70%" xlink:href="me.jpg" result="photo"/>
<feImage xlink:href="#path_area" result="gradient"/>
<feColorMatrix type="luminanceToAlpha" in="gradient" result="alpha"/>
<feComposite in="photo" in2="alpha" operator="in" result="face_circle"/>
<feFlood x="0" y="0" width="800" height="800" flood-color="black" result="black_area"/>
<feMerge>
<feMergeNode in="black_area"/>
<feMergeNode in="face_circle"/>
</feMerge>
</filter>
</defs>
<rect x="0" y="0" width="1000" height="600"
style="filter:url(#photo_with_background)"/>
</svg>
第二种是使用径向渐变滤镜。
<!--首先定义了一个矩形的径向渐变,接着将其作为图像进行色彩矩阵将渐变圈外的背景变透明,然后再跟头像进行复合并生成最后的效果。-->
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="800"
height="800" >
<defs>
<radialGradient id="face_gradient">
<stop offset="0" style= "stop-color:white"/>
<stop offset=".55" style= "stop-color:white"/>
<stop offset=".60" style= "stop-color:grey"/>
<stop offset=".63" style= "stop-color:black"/>
</radialGradient>
<rect width="800" height="800" fill="url(#face_gradient)" id="gradient_area" transform="translate(-40, -120) scale(1.4, 1.6)"/>
<filter id="photo_with_background"
color-interpolation-filters="sRGB">
<feFlood x="0" y="0" width="800" height="800" flood-color="black" result="black_area"/>
<feImage x="1.0%" y="0%" width="80%" height="80%" xlink:href="me.jpg" result="photo"/>
<feImage xlink:href="#gradient_area" result="gradient"/>
<feColorMatrix type="luminanceToAlpha" in="gradient" result="alpha"/>
<feComposite in="photo" in2="alpha" operator="in" result="face_circle"/>
<feMerge>
<feMergeNode in="black_area"/>
<feMergeNode in="face_circle"/>
</feMerge>
</filter>
</defs>
<rect x="0" y="0" width="800" height="800"
filter="url(#photo_with_background)"/>
</svg>
不难发现这种方法比第一种效果好很多,但是由于我这里使用的头像背景是白色,名片是黑色,直接使用这种方法效果可能也不是特别好。
接下来对头像进行一定的处理,首先来试试看模糊效果的卷积矩阵滤镜。
<feConvolveMatrix
result="face"
kernelMatrix=".11 .11 .11 .11 .11 .11 .11 .11 .11"
order="3 3"
divisor="1"
bias="0"
preserveAlpha="true" />
效果不太好,由于模糊了看上去就跟丢了神一样。边缘效果肯定是不可行的,毕竟还是要看到头像的嘛,那来试下锐化好了。
<feConvolveMatrix
result="face"
kernelMatrix="-1 -1 -1 -1 9 -1 -1 -1 -1"
order="3 3"
divisor="1"
bias="0"
preserveAlpha="true" />
不错不错,看上去很精神!有点名片应该有点样子。接下来用色彩矩阵滤镜调整颜色,降低饱和度让头像看上去“冷峻”一点。
<feColorMatrix type="saturate" values="0.4" result="face" />
接下来用渐变滤镜来给脸部添加一些阴影。
<linearGradient id="face_gradient1">
<stop offset= "0.4" style= "stop-color:white"/>
<stop offset="0.9" style= "stop-color:black"/>
</linearGradient>
<rect width="350" height="450" fill="url(#face_gradient1)" id="gradient_area1" opacity="0.95"/>
<feImage xlink:href="#gradient_area1" result="gradient1"/>
<feBlend mode="multiply" in="face" in2="gradient1" result="faceOut" />
不错有点好莱坞大片即视感。
接下来给我头像添加光照。首先尝试SpecularLighting
+PointLight
的组合。
<feSpecularLighting result="specular_light" in="faceMid" specularExponent="200" lighting-color="lightgrey">
<fePointLight x="250" y="200" z="200"/>
</feSpecularLighting>
效果不是特别好,原因可能是PhotoLigh
光源太集中。再尝试下DiffuseLighting
+SpotLight
的组合。
<feDiffuseLighting result="diffuse_light" in="SourceGraphic"
diffuseConstant="100" lighting-color="white" specularExponent="100" >
<feSpotLight x = "-100" y = "-100" z = "400" pointsAtX = "250" pointsAtY = "250" pointsAtZ = "0" limitingConeAngle = "7"/>
</feDiffuseLighting>
发现效果更差!主要原因是spotlight
需要调整六个参数来改变灯光的效果,非常考验经验与耐心。所以我们还是试下DiffuseLighting
+Distanctlight
的组合吧。
<feDiffuseLighting result="diffuse_light" in="faceMid"
diffuseConstant="100" lighting-color="lightgrey" specularExponent="100">
<feDistantLight azimuth = "45" elevation = "135"/>
</feDiffuseLighting>
效果同样不是特别好,看来Lighting
不是个特别好的滤镜效果。那我们来试下渐变滤镜好了。
<feImage xlink:href="#face_gradient2" />
<feColorMatrix type="luminanceToAlpha" result="face_4"/>
<feFlood width="300" height="300" flood-color="white" result="face_5"/>
<feComposite in="face_5" in2="face_4" result="face_6" operator="in" />
好像稍微好点,最后来尝试下比较复杂的方法:首先生成一个渐变滤镜,然后转换成透明度,再基于透明度来修改原图像的色彩值,最后在还原透明度。
<feImage xlink:href="#face_gradient2" />
<feColorMatrix type="luminanceToAlpha" result="face_4"/>
<feComposite in="face_1" in2="face_4" result="face_6" operator="in" />
<feColorMatrix type="matrix" in="face_7" result="face_17"
values="1 0 0 1 0
0 1 0 1 0
0 0 1 1 0
0 0 0 1 0 " />
<feMerge result="face_27">
<feMergeNode in="face_3"/>
<feMergeNode in="face_17"/>
</feMerge>
效果看上去是不是很棒?恩恩,因为不是添加的光源,而是基于图像本身进行的亮度调整,所以看上去更加真实,那就决定使用这种方法吧。
本来名片设计到这里就全部完成了,但是由于我们是使用SVG生成的名片。也就是说大多数情况下别人都会在网页上打开你的名片,那么为何不尝试在名片上添加个链接让对你感兴趣的人可以进一步了解你呢?
这里为了增加别人点击链接的欲望,我往在链接的文本上添加了一个动画。
<linearGradient id="lineargradient3">
<stop offset= "0" style= "stop-color:black"/>
<stop offset=".5" style= "stop-color:white"/>
<stop offset="1.0" style= "stop-color:black"/>
</linearGradient>
<filter id="link"
color-interpolation-filters="sRGB">
<feImage xlink:href="#link_gradient" result="link_1"/>
<feComposite in="SourceGraphic" in2="link_1" operator="in"/>
</filter>
<a xlink:href="http://gizmosir.com" >
<text x="800" y="650" style="font-size:40;font-family:courier;font-style:oblique;font-weight:bold;filter:url(#link)">Visit More</text>
</a>
在几乎把所有的滤镜都尝试了也应用之后,我们的名片终于生成了,其最终效果如下。
或者你可以点击这里。
另外需要注意的是,SVG在不同的浏览器以及不同的版本上效果大相径庭。我是就要Chrome 49.0.2623.87版本生成的这张名片,所以建议你复制链接到chrome浏览器上查看。
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" >
<defs>
<!--Gradient definition-->
<radialGradient id="radialGradient1">
<stop offset="0" style= "stop-color:white"/>
<stop offset=".55" style= "stop-color:white"/>
<stop offset=".60" style= "stop-color:grey"/>
<stop offset=".63" style= "stop-color:black"/>
</radialGradient>
<radialGradient id="radialGradient2">
<stop offset="0" style= "stop-color:#999999"/>
<stop offset=".1" style= "stop-color:#888888"/>
<stop offset=".3" style= "stop-color:#666666"/>
<stop offset=".5" style= "stop-color:#444444"/>
<stop offset=".7" style= "stop-color:#222222"/>
<stop offset=".9" style= "stop-color:#111111"/>
<stop offset="1" style= "stop-color:black"/>
</radialGradient>
<linearGradient id="lineargradient1">
<stop offset= "0.4" style= "stop-color:white"/>
<stop offset="0.9" style= "stop-color:black"/>
</linearGradient>
<linearGradient id="lineargradient2" x1="100%" y1="0%" x2="100%" y2="100%">
<stop offset= "0.4" style= "stop-color:#cccccc"/>
<stop offset="0.8" style= "stop-color:gray"/>
</linearGradient>
<linearGradient id="lineargradient3">
<stop offset= "0" style= "stop-color:black"/>
<stop offset=".5" style= "stop-color:white"/>
<stop offset="1.0" style= "stop-color:black"/>
</linearGradient>
<!--Rectangle definition-->
<rect id="face_area" width="350" height="450" fill="url(#radialGradient1)"
transform="translate(-40, -120) scale(1.4, 1.6)"/>
<rect id="link_gradient" width="400" height="400" fill="url(#lineargradient3)">
<!--Text animation definition-->
<animate attributeName="x"
begin="0s" dur="2s"
values="-400;0" repeatCount="indefinite"/>
</rect>
<rect id="face_gradient" width="400" height="500" fill="url(#lineargradient1)" opacity="0.95"/>
<rect id="face_gradient2" width="350" height="350" fill="url(#radialGradient2)" opacity="0.5" transform="translate(-30, -40) scale(1.1, 1.1)"/>
<!--Shadow filter definition-->
<filter id="shadow"
color-interpolation-filters="sRGB">
<feGaussianBlur in="SourceGraphic" stdDeviation="10"/>
<feOffset dx="20" dy="20" />
<feColorMatrix type="matrix"
values="0 0 0 0 0.5
0 0 0 0 0.5
0 0 0 0 0.5
0 0 0 1 0" />
</filter>
<!--Company logo filter definition-->
<filter id="logo"
color-interpolation-filters="sRGB">
<feImage xlink:href="http://7xjz11.com1.z0.glb.clouddn.com/logo.png?imageView/2/w/200/h/147" width="200" height="147" />
<feConvolveMatrix
kernelMatrix="1 1 1 1 -8 1 1 1 1"
order="3 3"
divisor="1"
bias="0"
preserveAlpha="true"/>
<feGaussianBlur stdDeviation="3"/>
<feColorMatrix type="luminanceToAlpha"/>
<feTile x="100" y="100" width="1000" height="600"/>
</filter>
<!--Text filter definition-->
<filter id="text"
color-interpolation-filters="sRGB">
<feGaussianBlur in="SourceAlpha" stdDeviation="2"/>
<feOffset dx="5" dy="5" result="text_2"/>
<feBlend mode="normal" in="SourceGraphic" in2="text_2"/>
</filter>
<!--Link animition definition-->
<filter id="link"
color-interpolation-filters="sRGB">
<feImage xlink:href="#link_gradient" result="link_1"/>
<feComposite in="SourceGraphic" in2="link_1" operator="in"/>
</filter>
<!--Face filter definition-->
<filter id="face"
color-interpolation-filters="sRGB">
<feImage xlink:href="http://7xjz11.com1.z0.glb.clouddn.com/me1.jpg" />
<!--Sharpen and desaturate the face to make it look smarter-->
<feConvolveMatrix
kernelMatrix="-1 -1 -1 -1 9 -1 -1 -1 -1 "
order="3 3"
divisor="1"
bias="0"
preserveAlpha="true" />
<feColorMatrix type="saturate" values="0.4" result="face_1"/>
<!--Using a linear gradient to increase face layered-->
<feImage xlink:href="#face_gradient" result="face_2"/>
<feBlend mode="multiply" in="face_1" in2="face_2" result="face_3" />
<feImage xlink:href="#face_gradient2" />
<feColorMatrix type="luminanceToAlpha" result="face_4"/>
<feComposite in="face_1" in2="face_4" result="face_6" operator="in" />
<feColorMatrix type="matrix" in="face_7" result="face_17"
values="1 0 0 1 0
0 1 0 1 0
0 0 1 1 0
0 0 0 1 0 " />
<feMerge result="face_27">
<feMergeNode in="face_3"/>
<feMergeNode in="face_17"/>
</feMerge>
<!--Using an ellipse gradient to extract the face out-->
<feImage xlink:href="#face_area" />
<feColorMatrix type="luminanceToAlpha" result="face_8"/>
<feComposite in="face_27" in2="face_8" operator="in"/>
</filter>
</defs>
<rect x="100" y="100"
width="1000" height="600"
style="filter:url(#shadow); " transform="translate(500, 200) scale(0.8, 0.8) skewX(-20)"/>
<rect x="100" y="100"
width="1000" height="600"
style="fill:#222222;"/> <!--Not pure black will look more actual-->
<rect x="100" y="100"
width="1000" height="600"
style="filter:url(#logo);"/>
<rect x="127" y="177" width="350" height="450"
style="filter:url(#face);" transform="translate(80, 100) scale(0.8, 0.8)"/>
<g fill="url(#lineargradient2)">
<text id="nameText" x="540" y="260" style="font-size:60;font-family:verdana;font-weight:bold;filter:url(#text)">Zheng Jiongbin</text>
<text x="600" y="380" style="font-size:32;font-family:arial;font-style:italic;" >
<tspan x="600" >Nephovision Co.,Ltd</tspan>
<tspan x="600" dy="60">iOS/Algorithm Engineer</tspan>
<tspan x="600" dy="40">Gizmosir@Nephovision.com</tspan>
</text>
<a xlink:href="http://gizmosir.com" >
<text x="800" y="650" style="font-size:40;font-family:courier;font-style:oblique;font-weight:bold;filter:url(#link)">Visit More</text>
</a>
</g>
</svg>