HTML CSS动画笔记
CSS3动画是个强大的功能,对比以前的setTimeout
更丝滑.无需使用JQuery,利用事件监听,可以准确的在动画结束时执行后续动作.
HTML CSS动画接口主要有两个,先做个基础了解
事件
transition
常见的悬浮操作:run(新)->start->cancel->run(旧)->start->end
事件驱动:run->start->end
sequenceDiagram 原始状态->>过渡过程: run 过渡过程->>最后状态: start 过渡过程->>最后状态: end 原始状态->>过渡过程: cancel
1.display:none
2.transition-property属性变化animation
悬停间隔短循环播放:start->iteration->start->iteration....->cancel
悬停时间短于动画播放start->cancel
循环一次的完整事件start->end
sequenceDiagram 动画开始->>动画结束: start 动画结束->>最后状态: end
终止动画,停止后续 动画开始->>动画结束: cancel
意外终止,停止后续,常见悬停 动画结束->>最后状态: iteration
动画循环下一个start
样式
- transition
transition:transition-property(属性) transition-duration(持续时间) | transition-timing-function(速率变化函数) | transition-delay(延时执行)
多个属性变化逗号隔开.
transition: margin-right 4s ease-in-out 1s;
margin-right变化需要4s延迟1s执行.
transition: margin-right 4s, color 1s;
margin-right变化需要4s,颜色1s完成变化. -
animation
animation
js API控制动画
function animateScroll(size){
let eH = document.documentElement,
st = eH.scrollTop,sh = eH.scrollHeight-window.innerHeight,sy=st+size>=sh?sh-st:size;;
let keyframes = [
{ transform: "translateY("+(0-sy)+"px)" },//from
{ transform: "translateY("+sy+"px)" },//to
];
let options = {
//delay 延迟开始动画多少ms 默认值0
//endDelay 动画结束后延时多少ms
easing:"ease-out",//速率 linear,ease-in
duration: 300,//动画所需ms
iterations: 1,//循环次数
};
document.documentElement.scrollTo(0,st+sy);
let _Animation = document.body.animate(keyframes,options);
["cancel","finish","remove"].forEach(v=>_Animation.addEventListener(v,e=>console.log(e.type)));
//let _Animation = new Animation(new KeyframeEffect(document.body,keyframes, options));
_Animation.addEventListener('finish',e=>{ });
//_Animation.play();
//_Animation.cancel();
//_Animation.pause();
//_Animation.finish();
}
animateScroll(500); //向下滚动500px
小结
如果子容器在发生动画事件,主容器监听也会触发的.好比点击子元素会冒泡到document.body.避免这种情况,用this==event.target判断是否当前对象.
这些事件可用实现动画之间套娃,比起使用setTimeout()
好用多了.例如A碰到B时,B才打C,是不是有点人机检测内味?
let on = (o,...a)=>o && Reflect.apply(addEventListener, o, a),
$ = s=>document.querySelector(s);
var A,B,C;
on($(A),'animationend',e=>{
let A=e.target,size = A.getBoundingClientRect();
let B = document.elementFromPoint(size.x,size.y);
if(B){
A.classList.remove('active');
A.hidden = true;//A消失了
B.classList.add('active');//抓到B了 给B上眼药
}
else console.log('打跑A抓不到B');
});
on($(B),'animationend',e=>{
let A=e.target,size = A.getBoundingClientRect();
let B = document.elementFromPoint(size.x,size.y);
if(B==$(C)){
A.classList.remove('active');
A.hidden = true;//B消失了
B.classList.add('active');//抓到C了
console.log('恭喜你拳打A,脚踢B,一巴打在C身上');
}else console.log('功亏一篑!');
});
animation事件例子1
animation事件例子2 滚动顶部
transition交互例子
简单结构实现bootstrap菜单效果,transition实践自适应导航菜单
- html
<button id="nav-btn">
<span id="nav-icon"></span>
</button>
<nav id="nav-body">
<div class="nav-item"><a class="nav-item-a" href="/">首页</a></div>
<div class="nav-item"><a class="nav-item-a" href="/emulator/helppage/">手机模拟器下载</a></div>
<div class="nav-item"><a class="nav-item-a" href="/emulator/app/emujs/">模拟器讨论</a></div>
<div class="nav-item"><a class="nav-item-a" href="Jekyll.html">Jekyll安装</a></div>
</nav>
- javascript
!(function(){
let on = (o,...a)=>o && Reflect.apply(addEventListener, o, a),
$ = s=>document.querySelector(s),
setStyle = (a,b)=>Object.entries(b).forEach(v=>a.style[(v[1]===false?'remove':'set')+'Property'](v[0],v[1]));
on(//绑定按钮事件
$('#nav-btn'),
'click',
function(){
let nb = $('#nav-body');
setStyle(nb,{'--nav-height':nb.scrollHeight+'px'});
//设置#nav-body原始高度,否则动画不知到高度
// --nav-height 把高度存进CSS变量中调用,避免直接用height覆盖属性
this.classList.toggle('active');
}
);
})();