什么是 Google Material Design ?
Ripple Click Effect in Web
Material Design 确实很不错。风格清新动画流畅,很吸引人。其中最吸引我的是它的 Ripple Click Effect。自己在想,是否可以通过 CSS 和 JavaScript 来实现这种效果呢?答案当然是可以的!
HOW ?
从上面的视频可以看出,当用户点击一个按钮的时候,按钮上方会有一段短暂的波纹动画,波纹从用户点击的那个地方开始,半径从零开始扩散变大,而且波纹的颜色也在渐渐的变淡,最后消失。
把这个需求放在 Web 设计中,要如何设计呢?
点击时的坐标
要得到用户点击时的坐标并不难。我们可以使用 JavasScript 直接调用
event.pageX
和 event.pageY
来得到当前鼠标的位置。波纹
实现波纹效果就比较麻烦一点。但是,其实波纹效果也可以简化成两个部分:
- 大小逐渐变大
- 是圆形的
我们把它分解成两部分,再使用 CSS 分别实现这两部分的效果,最后叠加起来,就实现了这个波纹效果了!
大小变大,我们可以利用 CSS3 动画里面的
transform: scale(2)
来实现。至于圆形的话,很简单,我们可以使用一个块级元素来实现,将它的宽度和高度设置成一致,然后使用 border-radius: 100%
就可以实现圆形的效果了。两者结合在一起
我们所需要实现的效果是点击后在该坐标上产生一个波纹动画,动画可以使用
transform
来实现,而对于动画的位置的话,我们可以灵活使用绝对定位和相对定位来实现。具体思路如下:- 一开始的时候,隐藏或者移除波纹动画的元素。
- 当用户点击时,将波纹动画的元素插进点击的元素的上方。
- 计算波纹动画元素的宽度和高度应该为多少。
- 计算出鼠标此时的坐标。
- 计算出波纹动画元素的位置,相对于被点击的元素应该偏移多少。
- 为波纹动画元素添加动画效果。
SHOW ME THE CODE
废话说了那么多,还是代码来得实在:
<div class="demo">
<h1>Ripple Click Effect</h1>
<ul>
<li><a>Dashboard</a></li>
<li><a>My Account</a></li>
<li><a>Direct Messages</a></li>
<li><a>Chat Rooms</a></li>
<li><a>Settings</a></li>
<li><a>Logout</a></li>
</ul>
</div>
以上是 HTML 的代码,没什么特别的,就是很普通的一个无序列表。
.demo {
margin: 0;
padding: 20px 0;
background: #789;
}
.demo h1 {
text-align: center;
color: #FFF;
text-shadow: 1px 2px 0 rgba(0,0,0,0.5);
}
.demo ul {
margin: 0 auto;
padding: 0;
width: 250px;
border-top: 5px solid #678;
background: #FFF;
box-shadow: 0 0 10px rgba(0,0,0,0.5);
}
.demo ul li {
list-style-type: none;
/* 使用相对定位,目的是为了给波纹元素作为偏移参考。 */
position: relative;
/* 溢出部分隐藏起来,这样才能保证波纹元素无论如何变化都始终在该 li 元素里面。 */
overflow: hidden;
}
.demo ul li a {
/* 使用相对定位,目的是为了给波纹元素作为偏移参考。 */
position: relative;
/* 将按钮设置成块级元素。 */
display: block;
padding: 10px 30px;
color: #789;
/* 由于在HTML中我们没有设置 href 属性,故不会显示可点击的鼠标。设置该 CSS 规则使得强制显示可点击鼠标手势。 */
cursor: pointer;
/* 避免多次点击按钮之后浏览器自动选中按钮中的文字。 */
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
}
.demo .ink {
/* 使用绝对定位,使得波纹元素位于点击时的鼠标坐标。 */
position: absolute;
/* 设置成块级元素才能正确设置高度 */
display: block;
/* 设置成100%以实现圆形效果 */
border-radius: 100%;
/* 默认状态下缩小为0,相当于不显示出来。 */
transform: scale(0);
-ms-transform: scale(0);
-webkit-transform: scale(0);
background: rgba(100,100,100,0.4);
}
.demo .animate {
/* 使用CSS3的动画效果来实现波纹动画 */
-webkit-animation: ripple 0.4s linear;
-moz-animation: ripple 0.4s linear;
}
@-webkit-keyframes ripple {
/* 动画执行过程的一些变化。此处是将波纹元素的大小变为 250%,透明度变为0 */
100% {
transform: scale(2.5);
-ms-transform: scale(2.5);
-webkit-transform: scale(2.5);
opacity: 0;
}
}
以上是 CSS 代码。里面有相应的注释。
$('a', $('.demo')).on('click', function (event) {
var parent = $(this).parent();
if (parent.find('.ink').length === 0) {
// 当 li 元素里面尚没有波纹元素时,则插入一个新的波纹元素进去。
parent.prepend($('<span>').addClass('ink'));
}
var ink = parent.find('.ink');
// 每次点击之后先移除上一次的动画。即移除 animate 类。
ink.removeClass('animate');
if (!ink.width() && !ink.height()) {
// 当波纹元素尚未设置大小时,为波纹元素设置长度和宽度。其值大小为 li 元素高和宽的最大值。这样才能保证波纹动画执行的过程中能够覆盖整个按钮元素。
var d = Math.max(parent.width(), parent.height());
ink.css({
width: d + 'px',
height: d + 'px'
});
}
// 计算波纹元素的位置
var x = event.pageX - parent.offset().left - ink.width() / 2;
var y = event.pageY - parent.offset().top - ink.height() / 2;
// 设置波纹元素的位置,并且添加类,开始执行动画。
ink.css({
top: y + 'px',
left: x + 'px'
}).addClass('animate');
});
以上则是 JavaScript 代码。整个项目的代码非常少,而且很容易移植到其他项目中。
最后几句话
Materail Design 里面的动画都非常棒,目前也有一些 Web 开发者开发出了类似的库了,比如:
这几个库实现的效果都非常棒,相信不久以后 Material Design 会在互联网上开始蔓延开来的!