缓动动画原理
-
缓动动画的原理:盒子本身的位置 + 步长 (不断变化的,由大变小)
-
步长:begin = begin + (end - begin) / 缓动系数
-
基本的缓动动画函数:
function buffer(obj, target) { // 1. 清除定时器 clearInterval(obj.timer); // 2. 设置定时器 obj.timer = setInterval(function () { // 2.1 求出步长 var speed = (target - obj.offsetLeft) / 20; console.log(speed); speed = speed > 0 ? Math.ceil(speed): Math.floor(speed); console.log(speed); // 2.2 设置动画 obj.style.left = obj.offsetLeft + speed + 'px'; obj.innerHTML = obj.offsetLeft; // 2.3 清除定时器 if(obj.offsetLeft == target){ clearInterval(obj.timer); } }, 20); }
1.1 常见的 js访问 CSS 属性
- 在开发中,访问得到css 属性,比较常用的有两种:
- 点语法
box.style.width,box.style.height,box.style.top,box.style.left
得到带有单位的属性值,比如:200px;
但是,点语法存在一个很致命的问题,跟在style后面的属性不能由外面传入
- 点语法
var h = 'height';
box.style.h = 300 + 'px';
- 下标语法
利用 [] 访问属性 元素.style[“属性”];
这种语法的好处就是可以动态的传递参数作为属性
- 下标语法
var h = 'height';
box.style[h] = 300 + 'px';
1.2 JS获取CSS的样式
在开发中,我们想要获得css 的样式,通常采用:box.style.top ,box.style.backgorundColor等, 但这种方式只能得到 行内样式,而平常用的最多的是页内样式或者外部样式, 那我们如何解决这样的问题?
- 在IE和Opera浏览器
obj.currentStyle - 其他W3C标准浏览器
window.getComputedStyle("元素", "伪类") ( 注意:两个选项是必须的, 没有伪类 用 *null *替代 )
- 在IE和Opera浏览器
- 兼容写法
function getStyleAttr(obj, attr) {
if(obj.currentStyle){ // IE 和 opera
return obj.currentStyle[attr];
}else {
return window.getComputedStyle(obj, null)[attr];
}
}
1.3 js对象遍历
- for in 关键字
for ( 变量 in 对象) { 执行语句; }
for(var k in json){
console.log(k); // key
console.log(json[k]); // value
}
1.4 回调函数
在开发中,有很多操作是链式的,下一个操作接着上一个操作执行,那么如何实现这样的行为?* 回调函数。*
回调函数什么时候调用?
--> 动画结束的时候调用 ?
--> 动画什么时候结束?
---> 定时器被清除的时候
--> 定时器被清除时调用回调函数
2.5 完整版缓动动画
/*
* 缓动动画
* obj: 要做动画的元素
* json: 要做动画的属性键值对
* fn: 回调函数
*/
function Buffer(obj, json, fn) {
// 1. 清除定时器
clearInterval(obj.timer);
// 2. 设置定时器
obj.timer = setInterval(function () {
var flag = true, begin, target;
// 2.1 遍历json
for(var k in json){
// 2.1.1 获取做动画属性的初始值
if('opacity' == k){ // 透明度
begin = parseInt(parseFloat(getCssStyleAttr(obj, k)) *100) || 0;
target = parseInt(parseFloat(json[k])*100);
}else { // 其他动画
begin = parseInt(getCssStyleAttr(obj, k));
target = parseInt(json[k]);
}
// 2.1.2 获取动画的步长
var speed = (target - begin) / 20;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
// 2.1.3 设置缓动动画
if('opacity' == k ){ // 透明度
obj.style.opacity = (begin + speed) / 100;
obj.style.filter = 'alpha(opacity='+ (begin + speed) +')';
}else if('zIndex' == k){
obj.style.zIndex = json[k];
}else { // 其他情况
obj.style[k] = begin + speed + 'px';
}
// 2.1.4 判断是否清除定时器
flag = (begin != target) ? false : true;
}
// 2.2 清除定时器
if(flag){
clearInterval(obj.timer);
//判断
if(fn){
fn(); // 执行函数
}
}
}, 20);
}
function $(id) {
return document.getElementById(id);
}
function getCssStyleAttr(obj, attr) {
if(obj.currentStyle){
return obj.currentStyle[attr];
}else {
return window.getComputedStyle(obj, null)[attr];
}
}
网友评论