CSS3实现四叶草、水母与玻璃瓶

以下为纯CSS制作,闲话不说,上个效果图先:

四叶草、水母与玻璃瓶

玻璃瓶质感、四叶草漂浮于水面,荡起涟漪、摇摆上升的气泡…很美的意境,然而你也许会说你喜欢瓶子不喜欢四叶草,那可以把四叶草给none掉,不喜欢植物的话,那你喜不喜欢动物呢:

四叶草、水母与玻璃瓶

应该看得懂这只萌物是什么生物吧..没错,水母 一只…众生皆平等,不能只有植物没有动物哈…

然而你也许不喜欢蓝色的水,那我写几套多彩的玻璃瓶:

四叶草、水母与玻璃瓶

如果你感兴趣的话,可以通过这个链接,下载我的源代码:《四叶草、水母与玻璃瓶

为方便下载,提供本人网盘帐号密码,请不要弄乱里面的页面,以方便其它人下载,谢谢。

帐号:287019674@qq.com

密码:123456

下面是对代码的分析:

一、四叶草

四叶草的代码结构如下:

一个leaves挂着叶子,叶瓣用四个I标签表示,一个branch代表叶茎

1) 叶瓣

每 个叶瓣都是一个leave,然后用angle控制它们的旋转,然而一个leave的话是画不出一个心形的,所以我用多了一个leave:after画另 外一半,两个表现出来的形状是一样的,一个头圆下方的形状,圆可以用border-radius圆角来做,然后通过以左下角为原点,旋转90度,来让它们 错开重叠成一个心形,如果你觉得抽象的话,可以参考下图:

四叶草、水母与玻璃瓶

我把leave:after的颜色调深一些,就可以看出它们是怎么一个重叠关系了…因为叶瓣与叶瓣之间存在之间隙,所以我旋转的原点有稍作偏移,而且在心形的底部如果太尖感觉有点怪,所以也做了一个小圆角处理,到此叶瓣主体就绘制完成。

2)叶茎

叶茎的话就是一个border做了一个大弧度圆角跟小弧度圆角的处理,如图:

四叶草、水母与玻璃瓶

如果border处于圆角状态,并且临近的border不显示,那么该border会向不显示的border拉一条锥形弧线, 这形状恰巧符合叶茎的形状,大弧度何以勾勒叶茎的基本形状,小弧度可以用来收尾,这样会比直角收尾柔和很多,到此四叶草制作完毕。

二、玻璃瓶

玻璃瓶的代码结构如下:

一 个bottle,分为瓶顶bottletop、瓶颈bottleneck、瓶身bottlemain三部分,每个都包含有一个挂高光的无意义的标 签,而bottletop里面有一个瓶口bottlemouth,bottlemain里面有一个玻璃瓶内部bottle_inner。

1)瓶子bottle

bottle 作为最外的容器,其实并无多大意义,用来只是定位。bottle:after用来画瓶子底部黑色的阴影,bottle:before用来画瓶子底部由于水的颜色产生的彩色阴影,两者分开,这样如果里面不装水了,那么只要隐藏bottle:before即可。下图是一个空瓶子的效果:

四叶草、水母与玻璃瓶

2)瓶顶bottletop、瓶颈bottleneck、瓶身bottle_main

其实瓶顶、瓶颈、瓶身三者的基本结构一致,所以这里合并在一起,后面细节的时候再分开。
bottletop我设定了宽高之后,取了它的左右边框,然后对它的bottletop:after、bottle_top:before进行操作,after做顶部向上的面,before做底部向下的面,然后border做边框轮廓:

border:2px solid rgba(255,255,255,0.5); border-bottom:2px solid rgba(255,255,255,0.6); border-top:1px solid rgba(255,255,255,0.4);

一个总的border,然后底部,也就是向前的border-bottom我把透明度设置为0.6比正常的深,然后后面的我把它的宽度调成了1px,从而增强透视效果,因为同样的物体,靠近眼睛的会比远离眼睛的大些清晰些。瓶颈瓶身同理,做了同样的设置,然而对于bottle_neck的伪类的 border-top我不是设置它的宽度为1px,而是直接border-top:none; 因为它被前面的玻璃实体挡住了,理应是存在的但显得,但是该部位的交叉线条比较多,所以直接隐藏掉,让线条清爽明朗些。最后将三个主体的元素通过定位,玻璃瓶框架基本就打好了。

3)瓶口bottle_mouth

因为瓶子是透明的,所以瓶口这个地方需要显示出来,它串连着瓶顶跟瓶颈两个部份,瓶口顶部需要重点刻画,而瓶口底部刚好在瓶颈底部交汇,由于厚度折射什么 的一大堆元素影响,看不是很清楚,所以我给次要化删了。如果你看了我的代码,会发现bottle_mouth我是没有用box-shadow来做‘面’, 而是用背景色,这里需要注意的是,投影形成的是一个圈的颜色,当然可以用偏移等方式让他变成一个弧形,但是如果我仅仅需要左右方向的投影,上下为透明的 话,就不行了,如图:

四叶草、水母与玻璃瓶

我现在需要的是拉一个水平方向自左向右的白色-透明-透明-白色的渐变,如果用box-shadow的话,在箭头方向会产生一块很明显的白色-透明的区域,如果采用投影向上偏移的话,那么下面就会出现同样的不符合要求的区域,所以这个点上,应该采用背景色渐变比较合理。

4)瓶内bottle_inner

bottleinner没有像bottletop那样一个圆柱形的设计,只是通过与瓶身bottle_main间隔一段距离产生厚度感,还有圆角:

-moz-border-radius:10px 10px 20px 20px/10px;

这样做出来的圆角底部会扁些逼真些,而与前面制作最大的不同在于这里:

四叶草、水母与玻璃瓶

边框不是白色的,而是

border:1px solid rgba(0,0,0,0.01);

再配合投影

-moz-box-shadow:0px 0px 2px rgba(255,255,255,0.5) inset,0px 0px 8px rgba(255,255,255,0.6) inset,0px 0px 5px rgba(255,255,255,0.5);

因为最边缘的玻璃切面跟视线成90度,透明度很高,而 弧度与视线大的区域,透明度会很低,所以白色会重一些,再慢慢过渡到透明。这个我是搜一些玻璃瓶资料 分析出来的,做出来的效果也比白色边框再渐变要真实些,然而不单要对内投影,还要对外,因为玻璃身有一定厚度,不可能完全透明,所以写了 5个像素的向外投影作为瓶身的渲染色…

5)投影

这里所说的投影,是对伪类进行box-shadow inset内投影,产生一个渐变面,让圆柱体的‘面’效果突出出来,这里我不用背景色而采用投影,是因为很难调整到符合透视的一个角度,而投影可以很轻松的做到,而且色彩融合得很好。比较特殊投影处理的有:

1> 瓶顶bottletop的一个向下偏移的投影,如上面瓶口bottlemouth图片,具体代码:

0px 3px 3px -1px rgba(255,255,255,0.3);

向下偏移3像素,羽化3像素,然后缩小1个比例,颜色为0.3的白色。这里是作为瓶顶圆柱形面的小高亮处理。

2> 瓶颈bottle_neck:after,如图:

四叶草、水母与玻璃瓶

具体代码:

-moz-box-shadow:0px 5px 3px -2px rgba(0,0,0,0.05);

向下偏移5像素,羽化3像素,然后缩小2个比例,颜色为0.05的黑色。这里是作为瓶顶向瓶颈投影处理,增强立体感。

3> 瓶身bottle_main:before,如图:

四叶草、水母与玻璃瓶

具体代码:

-moz-box-shadow:0px 0px 6px rgba(255,255,255,0.7) inset,0px 0px 3px rgba(0,0,0,0.15) inset;

不偏移,羽化6像素,颜色为0.7的白色内投影,不偏移,羽化3像素,颜色为0.15的黑色内投影。这里是作为瓶底底色设置跟边缘泛光,增强立体感。

6)高光

挂上高光,立体感强烈了许多,如图:

四叶草、水母与玻璃瓶

分别对瓶顶、瓶颈、瓶身做高光,一条浅点细点的,一条宽点由左到右由白到透明的渐变,瓶颈只有宽没有细,瓶身细线由上至下做一个到80%的时候为透明的渐变…值得注意的是,高光需要贴着瓶壁,高度斜度保持一致,所以需要对高光进行一个斜切的变换:

-webkit-transform:skew(0deg,6deg);

要不然左侧对应了,那么右侧高光必然会高出瓶壁几个像素,到此,玻璃瓶制作完成。

三、水

1)水主体

因为水是装在玻璃瓶里面的,所以展现出来是一个圆柱形,结构跟瓶身bottle_main一致,区别主要表现在渲染颜色,投影方面。以蓝色的水为例:

.water{ background:-moz-linear-gradient(-85deg,rgba(0,204,255,0.35),rgba(0,173,216,0.55) 70%,rgba(0,173,216,0.4)); -moz-border-radius:50px 50px 20px 20px/8px 8px 10px 10px; -moz-box-shadow:0px 0px 6px rgba(0,204,255,0.5) inset,0px 0.2px 3px -1px rgba(0,0,0,0.3) inset,0px 2px 6px -1px rgba(0,0,0,0.1) inset,0px 2px 5px rgba(0,204,255,0.3),0px 1px 3px rgba(0,204,255,0.2); }

水元素边角需要做一个椭圆化处理,因为这次需要用到背景色打底,上圆润一点圆角过渡自然下扁在两角有一个小拐点,因为上面的是水平面透视的,而下面是玻璃底座,需要有一定的硬度,与上面产生区别;
背景色拉一个左上右下,斜度平缓倾向于垂直的渐变,颜色由深到浅;
投影所产生的效果跟瓶身的效果差不多,颜色在左右侧深中间浅;

2)水平面

.water:after{ background:-moz-linear-gradient(left,rgba(255,255,255,0.4),rgba(0,204,255,0.05) 50%,rgba(0,204,255,0.1) 80%,rgba(255,255,255,0.3)); -moz-border-radius:50px/8px; border:1px solid rgba(255,255,255,0.2); border-bottom-color:rgba(255,255,255,0.4); -moz-box-shadow:0px 1px 2px -1px rgba(0,204,255,0.35); }

背景色拉一个由左到右 白-蓝-蓝-白的渐变,因为已经有水主体的蓝色打底色,所以上水平面颜色不用太重,边框用0.2白色,而在前面的border-bottom则用0.4白 色,远模糊近清晰,让立体感更强些…这里值得注意的是投影,我写了一个向下偏移1像素,羽化2像素,然后缩小1个比例,颜色为0.35的蓝色投影,这 个是为了跟上面的水主体呼应写的,我们知道,在中学上化学课目测试管中溶液体积的时候,视线要要跟溶液凹面相平,否则会产生误差,可以看这张图:

四叶草、水母与玻璃瓶
内径比较小的仪器,当里面装有水时,因为水有表面张力,所以在小内径仪器里不会是平的,呈现周围高中间低的凹形,而中间的凹形状才是真正水的标准位置,周围的只是因为表面张力往上高了。

所以我刚才做的那个投影,配合背景色的头尾白色,就形成了这个凹面的效果,放大200%后,效果如下:

四叶草、水母与玻璃瓶

after做的是下面箭头指向的稍微深色的投影区域,而上面箭头指向的,其实就是水water本体所做的内投影,现在明白为什么这次主体要做圆角伸到最上面了吧…

3)水底部

其实原理跟水平面一致,背景色拉一个由左到右 深蓝-蓝-蓝-深蓝的渐变,然后在用投影加深底部渐变颜色,需要注意的是,底部跟玻璃需要保持一定的间隙,以突出玻璃的厚度和玻璃凹面。

四、水母

本来想画条鱼,不过鱼如果游到边缘要拐弯的话难度太高了,就换成一个比较容易实现的水母同志,如图:

四叶草、水母与玻璃瓶

代码结构为:

一只水母jellyfish,分为头部jellyfishhead、尾部jellyfishtail,其实里面那个jellyfishtailin没多大意义,就为了加一条触须…

1)水母头部jellyfish_head

水母头部是一个椭圆形,顶部的又大又圆,底部需要一个拐角,不能太圆,感觉就像是一个‘倒着的钵’,具体圆角代码:

-moz-border-radius:20px 20px 10px 10px/20px 20px 16px 16px;

而重点的代码是内投影:

-moz-box-shadow:0px 0px 4px rgba(255,255,255,0.5) inset,1px 1px 2px rgba(255,255,255,0.2) inset,3px 3px 1px rgba(255,255,255,0.2) inset,-1px -1px 1px rgba(255,255,255,0.1) inset;

采用四次内投影产生立体感,具体怎么产生的,我解释下,第一个是最基本的打底 色,第二第四是做向右下偏移跟向左上偏移的阴影,增加深度,第三个向右下偏移 了三个像素做一个高光效果,再用jellyfish_head:after,画了一个椭圆旋转rotate(-15deg),调整透明度位置后作为最亮的 高光展现,这样水母的头部就制作完成。

2)水母尾部jellyfish_tail

尾部jellyfishtail取 左右边框,上下隐藏,然后做一个淡淡的内投影,调整位置,圆角的曲率,再通过 jellyfishtail:after、jellyfish_tail:before制作多几条触须,调整好触须间的间隔,这个根据个人爱好而定,因 为我制作后发现尾部稍微大了点,就用scale缩小了一些…

五、气泡

气泡bubble的制作相对比较简单,所以放在下面,次要处理,基本也就是border、box-shadow这些主要还是体现在动画那里。

六、四叶草浮在水面

我 们知道,图层之间只有上下之分,没有穿过的,四叶草下部分需要泡在水里,而上部分需要浮出水面,我不可能把水切成两段,所以我把四叶草分成了上下两部分 cloverTop和cloverBottom,类似于一个模板操作,固定宽高后hidden掉不要的那部分,再拼接起来,从而实现漂浮,穿过水面的效 果,实现效果如下:

四叶草、水母与玻璃瓶

既然说穿过了,还要摇曳,那么必然有涟漪,总共有两个涟漪,用cloverBottom:after、cloverBottom:before实现,具体重点代码如下:

.cloverBottom:after{ border:0.5px solid rgba(255,255,255,0.3); -moz-border-radius:19px/2px; border-top:none; border-right:none; border-bottom-color: rgba(255,255,255,0.2); -moz-box-shadow:0px 0px 3px -1px rgba(0,0,0,0.2) inset; }

设置好边框样式,但是由于太小了,四条都显示的话画面太复杂了,所以隐藏掉后面跟右边的两条,下面的调整边框颜色,在设置一个0.2黑色的内投影,调整好 圆角的曲率,做出一个涟漪的大致效果,after做一个小涟漪,before做一个大涟漪,基本制作方式一致,这里就不分析了。

七、动画

1)摇曳的四叶草

如你刚打开我源代码页面所看到的,有一株四叶草在玻璃瓶里面摇曳,荡起一个个涟漪(如果你没看到,说明你用的是IE..哈哈..)…

那么,涟漪的节奏应该与四叶草摇曳的节奏一致,具体的代码如下:

@-moz-keyframes cloverMove{    0%{-moz-transform:translate(0px,0px);}    25%{-moz-transform:translate(-3px,1px);}    50%{-moz-transform:translate(0px,-1px);}    75%{-moz-transform:translate(4px,1px);}    100%{-moz-transform:translate(0px,0px);} }

四叶草从原位置,向左移动-3px向下移动1px,接着向右移动3px向上移动2px,接着向右移动4px向下移动2px,然后回归原位置。这样整体感觉就是浮浮沉沉,左摇右摆的样子。

而我在给元素设定动画的时候是这样写的:

-moz-animation: cloverMove 4s linear infinite alternate;

它动画的名字叫cloverMove,动画时间4秒,线性运动,不停止的,反向进行。

那就这样而已吗?不止的,这个是四叶草整体的摇曳,那叶茎也可以摇的,具体实现代码:

.branch{-moz-animation:branchMove 4s linear infinite alternate; -moz-transform-origin:0% 0%;} @-moz-keyframes branchMove{    0%{-moz-transform:rotate(0deg);}    25%{-moz-transform:rotate(3deg);}    50%{-moz-transform:rotate(-2deg);}    75%{-moz-transform:rotate(4deg);}    100%{-moz-transform:rotate(0deg);} }

通过以左上角为中心,配合整体旋转,这样看起来更动感…

2)摇曳上升的气泡

单单是四叶草在摇,感觉怪怪的,因为气泡不能死气沉沉的,也要跟节奏才行,所以:

@-moz-keyframes bubbleMove{    0%{-moz-transform:translate(0px,0px) skew(0deg,2deg);}    25%{-moz-transform:translate(-2px,0.5px) skew(0deg,5deg);}    50%{-moz-transform:translate(0px,-0.5px) skew(0deg,2deg);}    75%{-moz-transform:translate(2px,0.5px) skew(0deg,0deg);}    100%{-moz-transform:translate(0px,0px) skew(0deg,2deg);} }

在轻微移动的同时进行斜切操作,因为气泡会“晃”…

那你会说这样也只是实现了“摇曳的气泡”,没有上升啊,其实有的,我总共做了三个气泡,第三个是在水底从下往上升的:

四叶草、水母与玻璃瓶

总共有三个气泡,第三个气泡的动画代码如下:

@-moz-keyframes bubbleRise{    0%{-moz-transform:translate(0px,0px); opacity:0; border-color:rgba(255,255,255,0.1);}    10%{-moz-transform:translate(0px,0px); opacity:1;}    30%{-moz-transform:translate(-1px,-15px);}    50%{-moz-transform:translate(1px,-30px);}    75%{-moz-transform:translate(-1px,-50px) scale(1.2);}    98%{opacity:1; border-color:rgba(255,255,255,0.25);}    100%{-moz-transform:translate(0px,-67px) scale(1.4); opacity:0; border-color:rgba(255,255,255,0.1);} }

气泡先从透明到完全不透明,10%出现的出现时间,然后摇晃着上升变大,到75%的时候面积为原来的1.2倍,边框颜色会随着变大而模糊,所以加深一点,到100%的时候面积为原来的1.4倍,完全不透明,即消失。

3)超萌水母

静态的水母已经很萌了,然而会游泳的,超萌那 q( >3< )p…以下是水母游水的动画代码:

@-moz-keyframes jellyfishSwimming{    0%{-moz-transform:translate(0px,0px) rotate(-4deg) scale(0.8);}    20%{-moz-transform:translate(-1px,-3px) rotate(-6deg) scale(0.8);}    50%{-moz-transform:translate(-2px,-1px) rotate(-3deg) scale(0.8);}    70%{-moz-transform:translate(-1px,-3px) rotate(-6deg) scale(0.8);}    100%{-moz-transform:translate(0px,0px) rotate(-4deg) scale(0.8);} } @-moz-keyframes jellyfishheadChange{    0%{-moz-transform:scale(1);}    5%{-moz-transform:scale(1.1,0.95);}    20%{-moz-transform:scale(0.95,1.1);}    50%{-moz-transform:scale(1);}    55%{-moz-transform:scale(1.1,0.95);}    70%{-moz-transform:scale(0.95,1.1);}    100%{-moz-transform:scale(1);} } @-moz-keyframes jellyfishtailChange{    0%{-moz-transform:scale(0.8);}    5%{-moz-transform:scale(0.9,0.75);}    20%{-moz-transform:scale(0.7,1);}    50%{-moz-transform:scale(0.8);}    55%{-moz-transform:scale(0.9,0.75);}    70%{-moz-transform:scale(0.7,1);}    100%{-moz-transform:scale(0.8);} }

jellyfishSwimming为整体的游水,变换侧移位置,同时水母是圆的,会摇晃;
jellyfishheadChange为水母头部的变化,个人觉得水母是要吸一口水,然后吐出来,利用反作用力才游的,所以0-5的时候是吸水变宽变 扁,然后5-20吐水变瘦变长,20-50变为正常,然后50-55再吸水变宽变扁,55-70吐水变瘦变长,70-100变为正常。
jellyfish
tailChange同jellyfish_headChange,其实可以用同一个,只不过我觉得尾巴相对于头部有点大了,就再缩小些,而且吐水的时候,尾巴可以吐得长些。

七、换色

这里针对水的颜色替换,其实已经没有多大技巧了,只不过利用类名样式权重,覆盖原本的初始样式,我制作了蓝色(默认)、粉红色pink、黄色yellow、绿色green,只要在bottle后面写下你想要变更的颜色就可以了,如下:

本来这个应该写在水元素上比较恰当,如下:

因为我们变更的是水的颜色,而不是瓶子的颜色,但是水颜色对整体瓶底投影有影响,而bottle:before之前没有用到,我也不想加多个标签,就套上了…

八、后记

由于我做的时候是用firefox做的,兼容只写moz,webkit是临时批量修改的,在修改的时候发现,webkit居然不支持 border:0.5px 最小只能1px,修改了气泡那些,可能有些地方没修…

对于源代码页面,我隐藏了小水母,因为太多元素的话,页面显得很杂,如果你想看水母的话,就隐藏了四叶草再删叼水母对于的display:none样式,这样效果会好一些…