一、往事
几年前,我有幸出差到东莞,在市中心一个85元一晚的小旅馆里面,我很激动。我像个没见过世面的孩子,看着窗外闪亮的霓虹灯招牌,心情久久不能平复。那灯红酒绿的景色,像那神秘的漩涡,把我吸进去了。我舔了舔嘴唇,从门缝下拾起一张名片,拨打了一个从未打过的电话......
--------------------------------强行分割线--------------------------
二、搞下字
在开始前,我们要先想下,霓虹灯的特点是什么。我在东莞的时候由于上面供血不足,只想到了两条,一是要有字,二是要发光。我们先把字弄出来。
body {
background: #000000;
margin: 0;
font-family: Helvetica, sans-serif;
overflow: hidden;
}
.texta-front {
font-family: YouYuan;
font-size: 64px;
font-weight: normal;
text-transform: uppercase;
fill: #db94f7;
}
<svg width="600" height="250">
<text text-anchor="middle" x="30%" y="50%" class="texta-front">
巴黎の玫瑰
</text>
</svg>为了体现霓虹灯的光芒,我特地把背景改成黑色,字使用的是svg的text,用到属性如下:
- text-anchor:文本锚点属性,被用来描述该文本与所给点的对齐方式 (开头、中间、末尾对齐) 。
- x,y:表示当前元素针对svg的相对位置的X,Y坐标,可以用百分比表示。
- class:可以直接在css里面设置属性,然后用class方式引进到svg里面,非常方便
我们再看css,我为了体现霓虹灯的效果,特地选了细长的字体,这里为了能让大多数人看到,选了装了office就有的幼圆字体。弄完后的效果是这样的
显然,这样是不行的,不发光,这就是个普通的文字而已,开始发光吧。
.texta-front {
font-family: YouYuan;
font-size: 64px;
font-weight: normal;
text-transform: uppercase;
stroke: #db94f7;
stroke-width: 2px;
text-shadow: 0px 0px 10px #e2b2f5;
}这里我把text-shadow的阴影特效加上去了,为了强化霓虹灯的效果,我把文字的填充(fill)换成了stroke。关于stroke,这里说明一下:
- stroke:设置绘制对象的线条的颜色。这里我用来做描边。
- stroke-width:描边的线条粗细。
其实stroke还有其他作用,待会我们会用到。最后的效果是这样的。
三、搞个框
为了不显得单调,我决定给字加个框。
.rect-front {
stroke: #07eb93;
stroke-width: 5;
box-shadow: 0px 0px 10px #07eb93;/*无效,text-shadow也无效 */
}
<svg width="600" height="250" >
<rect x="7%" y="25%" rx="30" ry="30" width="340" height="90" fill-opacity="1" class="rect-front" />
<text text-anchor="middle" x="35%" y="50%" fill-opacity="1" class="texta-front">
巴黎の玫瑰
</text>
</svg>因为我们只需要框,不需要填充,所以还是用了stroke,结果如下:
很不幸,这个翠绿的框竟然没有光,看了无论是text-shadow还是box-shadow对rect都毫无效果,看来简单的配置就能搞定的时代已经过去了,我只能另想办法了,徒手把光给发出来!
.rect-front {
stroke: #07eb93;
stroke-width: 2;
}
.rect-back {
stroke-width: 4;
filter:url(#filter-blur);
}
<svg width="600" height="250" >
<filter id="filter-blur">
<feGaussianBlur in="SourceGraphic" stdDeviation="4" />
</filter>
<rect x="7%" y="25%" rx="30" ry="30" width="340" height="90" fill-opacity="1" class="rect-front rect-back" />
<rect x="7%" y="25%" rx="30" ry="30" width="340" height="90" fill-opacity="0" class="rect-front" />
......
</svg>之前看过我做云的朋友知道,svg的filter是个好东西,这里我用的就是高斯模糊滤镜(feGaussianBlur ),把模糊后的效果作为底部,上面再铺一层清晰的框,这样,一个发出翠绿光芒的框就出来了,另外,我把前面框的fill-opacity设置成0,是为了让上面的这层rect透明(stroke是不受fill-opacity影响的,不会透明化),方便底下的模糊光可以看的到。最后看到的效果就是这样的
这样看起来有点靠谱了,但看相貌也是平平无奇啊,何必费这功夫写这么多字呢。但这种完美的霓虹灯怎么能入我的法眼,在那神奇的霓虹灯中,总有那损坏的部分更吸引人,比如这种:
是的,没有残缺的霓虹灯是不完整的(本篇金句),所以我决定把霓虹灯颓废的一面表现出来。
四、残缺美
在一个漆黑的巷子里面,一间破旧的酒吧,门口的招牌因为年久失修,招牌已经破损,灯也变的有的亮有的不亮了,里面的老板是一个胡子拉碴的中年男人,他一开口,就用沧桑的口气说:“当年我出差到东莞的时候,一时没忍住..."
--------------------------------再次强行分割线--------------------------
为了达到残缺破损的效果,我用了两样东西,一是旋转,二是破损。先看简单的,旋转效果。
<text text-anchor="middle" x="39%" y="50%" fill-opacity="1" rotate="0 0 0 0 40"class="texta-front">
巴黎の玫瑰
</text>这里用上了rotate,它的规则如下:
rotate参数值是一个数列,用来规定旋转的度数,单位可以省略,默认是deg。
字符应用角度规则:
(1).如果只有一个参数,所有文本都旋转同一个角度。
(2).如果规定多个参数,第一个参数用于第一个字符,第二个参数用于第二个字符,以此类推。
效果如下:
下面我们还需要搞定破损,既然瑰字都歪斜了,自然电源的接触也不好,那就让它继续破损吧。顺便把这个绿框也搞搞破坏。
.textb-front {
font-family: YouYuan;
font-size: 64px;
font-weight: normal;
text-transform: uppercase;
stroke: #723c88;
stroke-width: 2px;
stroke-dasharray: 180 280;
text-shadow: 0px 0px 3px #332638;
}
.rect-front {
stroke: #07eb93;
stroke-width: 2;
stroke-dasharray: 180 100;
}
......
<text text-anchor="middle" x="35%" y="50%" fill-opacity="1" class="texta-front">
巴黎の玫
</text>
<text text-anchor="middle" x="62%" y="50%" fill-opacity="1" rotate="40" class="textb-front">
瑰
</text>这里的关键是stroke-dasharray,它可控制用来描边的点划线的图案范式。它的值是一个数列,一般成对出现,第一个值表示线的长度,第二个值表示缺口的长度,反正我是谁便试,看着合适就行。另外把“瑰”的颜色调深,看着比较像供电不足,最后的效果如下
五、来个图吧
到目前为止,我们都试围绕着字和规则图形来的,但霓虹灯的世界难道只有呆板的文字和形状吗,不,我拒绝。既然试巴黎的玫瑰,没有巴黎也就算了,连玫瑰也没有就太寒酸了,我决定把玫瑰加上去。但普通的图片肯定不行,既然是svg的文章,自然要来张svg的图片。SVG的图片,我想到了马云。
阿里巴巴矢量图标库,你值得拥有,有大量的图标,都可以用多种格式下载,我选了一朵玫瑰,下载成svg的格式
什么是svg图,我抄一段吧,详细的请自行查阅
- SVG 指可伸缩矢量图形 (Scalable Vector Graphics)
- SVG 用来定义用于网络的基于矢量的图形
- SVG 使用 XML 格式定义图形
- SVG 图像在放大或改变尺寸的情况下其图形质量不会有所损失
- SVG 是万维网联盟的标准
- SVG 与诸如 DOM 和 XSL 之类的 W3C 标准是一个整体
它在内容是这样子的
全部的代码太长,我就截个图意思一下吧。我同样通过X,Y的参数挪到合适的位置,效果是这个样子。
但这个玫瑰不发光,算什么霓虹灯,我又开始了发光了。
.svg-font1 {
fill:none;
stroke: red;
stroke-width: 10;
stroke-dasharray: 880 330;
}
.svg-font2 {
fill:none;
stroke: yellow;
stroke-width: 10;
stroke-dasharray: 700 1030;
}
.svg-font3 {
fill:none;
stroke: gold;
stroke-width: 10;
}
.svg-font4 {
fill:none;
stroke: rgb(243, 40, 165);
stroke-width: 10;
}
.svg-font5 {
fill:none;
stroke: rgb(7, 252, 117);
stroke-width: 10;
}
.svg-back {
filter: url(#filter-blur-svg);
}
...
<filter id="filter-blur-svg">
<feGaussianBlur in="SourceGraphic" stdDeviation="15" />
</filter>
...
<svg x="60%" y="0%" t="1562754342698" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
p-id="1277" width="128" height="128" fill="1">
<path class="svg-font1 svg-back" ...
<path class="svg-font3 svg-back" ...
<path class="svg-font2 svg-back" ...
<path class="svg-font4 svg-back" ...
<path class="svg-font5 svg-back" ...
<path class="svg-font5 svg-back" ...
<path class="svg-font5 svg-back" ...
<path class="svg-font5 svg-back" ...
</svg>
<svg x="60%" y="0%" t="1562754342698" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
p-id="1277" width="128" height="128" fill="1">
<path class="svg-font1" ...
<path class="svg-font3" ...
<path class="svg-font2" ...
<path class="svg-font4" ...
<path class="svg-font5" ...
<path class="svg-font5" ...
<path class="svg-font5 ...
<path class="svg-font5 svg-back" ...
</svg>需要说明的是,svg标签里面可以使用filter="url(#filter_id)"这种方式,直接使用filter,但class="classname"是无效的,但path标签是可以使用的。我就是用一层svg的path使用高斯模糊(feGaussianBlur )作为发光的效果,在上面铺上一层图作为灯光本体,再把颜色改变一下,效果就出来了。然后再次请出stroke-dasharray,给玫瑰花也做出一些缺陷美,就完成了。最后的效果如下:
六、往事-续篇
正在我如痴如醉的撸代码的时候,一阵敲门声传来,一个娇滴滴的声音在旅馆房间的门外传来,“靓仔,是你要的客房服务吗?”。我赶忙开门,急促的说道:“快,快进来,关门”。把人拉进来后,我急忙关上灯,继续拉着人往里走,“来,上床”。在床上,我深吸一口气,迅速打开我的thinkpad,指着屏幕说:“我做的霓虹灯和窗外的比,是不是一模一样...”