play css3 Animation
关于CSS3动画
transform? translation?
转换(transform)
顾名思义,就是一些转换动作,如放大缩小( scale
),平移( translate
),旋转( rotate
),翻转( skew
)等。 就是关于二维图形与三维模型的转换动作(矩阵变换,图形学中的东西,这里不深究)。 关于,三维空间的基本转换和少许组合转换,我做过类似的Demo (请使用最新版的主流浏览器查看)
过渡(translation)
在CSS中的属性改变后,为了使用户体验更加良好,需要使用到过渡效果,使得属性变换更加平滑。
参考资料
Animation?
动画(Animation)
可以将一系列复杂的css属性变化活动定义为一个动画,并且规定触发动画的次数或其他相关设定。
参考资料
关于示例动画
第一个「活跃」的蓝色方块
首先定义动画
@keyframes animated_div
{
0% {transform: rotate(0deg);left:0px;}
25% {transform: rotate(20deg);left:0px;}
50% {transform: rotate(0deg);left:500px;}
55% {transform: rotate(0deg);left:500px;}
70% {transform: rotate(0deg);left:500px;background:#1ec7e6;}
100% {transform: rotate(-360deg);left:0px;}
}
@keyframes animated_div
定义了一个名为 animated_div
的动画,这样我们就可以直接在后面使用这个动画了。 xx%
表示的是动画的进度,即最开始对应 0%
。 因为各公司浏览器都想自己搞垄断,所以为了兼容主流浏览器不得不重复一段代码了
@-webkit-keyframes animated_div{/*同样定义*/}
@-moz-keyframes animated_div{/*同样定义*/}
@-o-keyframes animated_div{/*同样定义*/}
使用动画
<div style='margin:30px;position:relative;animation: animated_div 2s infinite;padding:10px;display:inline-block;'>
CSS3 Animation
</div>
margin
padding
是用来美化距离的, display:inline-block;
将该元素变为行内块,不然 div
默认为块元素,将独占一整行。 position:relative;
是为了让 left
right
bottom
top
凑效。 animation: animated_div 2s infinite;
使用刚刚我们定义的动画,动画的周期为2s,infinite
表示无限制的进行动画!
这样你就能看到第一个动画啦!
关于两个小黑块
首先是定义样式
- CSS
.magic-div{
width: 56px;
height: 50px;
padding: 10px;
line-height:0;/* * */
background-color:black;
cursor:pointer;
}
.magic-div>span{
background-color:white;
margin-top:20px;
vertical-align: top;
width:100%;
height:2px;
display: inline-block;
transition:all .6s; // 所有属性都有过渡效果
}
.magic-div>span:first-child{
margin-top:3px;
}
- HTML
<div style='display:inline-block;' class='magic-div magic-div-right'>
<span></span>
<span></span>
<span></span>
</div>
这样你就能看到一个黑块中含有三条水平横线啦
动画控制
- 第一个黑块
var div = document.querySelector('.magic-div-right');
function bind(elem,type,fn){
elem[type]=fn;
elem.addEventListener(type,elem[type]);
}
bind(div,'mouseenter',function(e){
var first = this.firstElementChild,last = this.lastElementChild, mid = first.nextElementSibling;
first.style.transform='scale(.5) translate(35px,25px) rotate(45deg)'
last.style.transform='scale(.5) translate(35px,-25px) rotate(-45deg)'
mid.style.opacity='1';
});
bind(div,'mouseleave',function(e){
var first = this.firstElementChild,last = this.lastElementChild, mid = first.nextElementSibling;
first.style.transform=last.style.transform='';
mid.style.opacity='1';
})
bind(div,'click',function(e){
var first = this.firstElementChild,last = this.lastElementChild, mid = first.nextElementSibling;
first.style.transform= 'rotate(45deg) translate(15px,15px)';
mid.style.opacity='0';
last.style.transform = 'rotate(-45deg) translate(15px,-15px)';
});
至于为什么需要定义一个 bind
函数,应该聪明的读者已经知道我要干什么了, bind
函数中 elem[type]=fn;
将事件处理函数绑定到元素中了, 在原生js中,元素有 click()
,focus()
,blur()
...,这样的方法,可以直接调用对应的事件函数, 但是却没有类似 jQuery
中的 mouseenter()
,mouseleave()
方法。 我这样做,能达到类似 jQuery
中的效果。
然后是函数中,一大堆的 transform
,scale(xx)
,translate(xx,xx)
,rotate(xx)
,也不难理解,只要上过初中平面几何就能明白了。 至于为什么会出现动态的效果,那都是多亏了样式中的 transition:all .6s;
- 第二个黑块 第二个黑块完全就是第一个黑块的孪生兄弟,可能有人会说了,这还不简单吗?直接copy第一份的代码,然后修改一下元素不就行了吗? 这样的确可以,但是我是用的是另一种方法,使得代码缩减了许多。
var otherdiv = document.querySelector('.magic-div-copy');
bind(otherdiv,'mouseenter',function(){
div.mouseenter.call(this);
})
bind(otherdiv,'mouseleave',function(e){
div.mouseleave.call(this);
});
bind(otherdiv,'click',function(){
div.click.call(this);
})
div.mouseenter.call(this);
意思是将div.mouseenter
方法调用,但是不是被div调用,而是被 this
(即otherdiv)调用。 call
属于 Function原型中的方法,第一个参数是调用该函数的对象,后面还可以跟上函数的参数。 apply
对比 call
,也是换汤不换药,不过函数的参数是以数组方式传入的。