JS 动画之透明度
使用同一个封装的动画函数,当我们传入‘o’的时候,表示要设置透明度,但是ie8以下透明度是使用filter:alpha(opacity=xxx);来实现的,所以这里要对ie做个兼容。
首先对传参设置以下:
$('#pox').click(function() {
$('#box').animation({
'attr': 'o',
'start': 30,
'end': 100,
'step': 7,
'type' : 0
})
});
我们先不设置缓动,attr传入o,起步的透明度为30,最终值为100,表示从透明到不透明,传值的时候要传入整数,js对小数有一些支持上的问题,所以后续的传值都尽量使用整数。
我们先对attr做个判断
对之前的attr判断改为:
var attr = obj['attr'] == 'x' ? 'left' : obj['attr'] == 'y' ? 'top' :
obj['attr'] == 'w' ? 'width' : obj['attr'] == 'h' ? 'height' :
obj['attr'] == 'o' ? 'opacity' : 'left';
连续三元判断。
初始值start判断
既然你传入的是透明度,那么起始值start也要改,之前的start是判断如果传入有值,那么就是传入的值+‘px’单位,但是透明度没有单位,所以start也要做个判断。
var start = obj['start'] != undefined ? obj['start'] :
attr == 'opacity' ? getOpacity() : parseInt(getStyle(element, attr));
这里三元判断,如果有值,就使用这个传入的值,没有的话就判断attr是否为opacity,如果是,调用getOpacity函数获取opacity值,不是则使用之前的方法获取计算后的值。
跨浏览器获取opacity
filter:alpha(opacity=xxx);是ie8及以下使用的,ie9以上及其他浏览器直接使用opacity,于是:
function getOpacity() {
if (system.ie <= 8) {
var op = getStyle(element, 'filter');
var s = [];
if (op.match(/opacity=([\d]+)/)) {
s = op.match(/\=([\d]+)/);
} else {
throw new Error('ie8一下没有获取到filter中的opacity值');
}
return parseInt(s[1]);
} else {
return getStyle(element, 'opacity') * 100;
}
}
之前做的ua判断派上了用场,直接判断ie的版本,如果是小于或者等于8,就获取计算后的filter,然后通过正则,将匹配值赋值给数组s,然后通过小标的方式,将正则分组中的数字return出去,但是要注意,return的这个s[1]是一个string类型,所以通过parseInt()转换成数字。
如果是其他浏览器,获取opacity即可,但是获取的是0.xx这种,所以要乘以100获得整值,方便操作。
然后增量的问题了
增量判断
因为我们start的时候传入的参数是整数,然后增量自然也是传入整数,获取opacity也是返回的整数,所以增量没有问题。
设置初始值
之前我们设置初始值因为只针对移动和大小,使用了px单位,但是这里透明度是没有px单位的,所以要做个判断了
if (attr == 'opacity') {
element.style.filter = 'alpha(opacity=' + start + ')';
element.style[attr] = start / 100;
} else {
element.style[attr] = start + 'px';
}
这里判断是透明度就实用透明度的赋值方法给元素赋值,不是则之前的方法。
设置每次增加量
目前我们没有设置缓动,所以这要设置好匀速移动的间歇调用即可
同样,透明度的设置方法和移动不同,所以要另写一个if
var timer = setInterval(function() {
if (type == 'buffer') {
step = attr == 'opacity' ? (end - getOpacity()) / speed : (end - parseInt(getStyle(element, attr))) / speed;
step = (step > 0) ? Math.ceil(step) : Math.floor(step);
}
if (attr == 'opacity') {
var temp = getOpacity();
if (step > 0 && Math.abs(temp - end) <= step) {
setOpacity();
} else if (step < 0 && parseInt(temp - end) <= Math.abs(step)) {
setOpacity();
} else {
element.style.filter = 'alpha(opacity=' + parseInt(temp + step) + ')';
element.style[attr] = (temp + step) / 100;
}
} else {
if (step == 0) {
setAttr();
} else if (step > 0 && Math.abs(parseInt(getStyle(element, attr)) - end) <= step) {
setAttr();
} else if (step < 0 && (parseInt(getStyle(element, attr)) - end) <= Math.abs(step)) {
setAttr();
} else {
element.style[attr] = parseInt(getStyle(element, attr)) + step + 'px';
}
}
}, time)
if判断如果是透明opacity,就这样,else则使用之前的方法。
是透明,也一样要判断step步进的值,如果是<0表示从不透明到透明,并且最终的透明度 - 当前的透明度 <= step步进的值,那么就调用setOpacity方法,这个方法和之前的步进一样,让设置的值直接等于最终end值,解决超出回弹的问题,并且删除间歇调用,其他都一样,这里新增加了一个step== 0,事实上step等于0之前就已经被判断了,根本不会再运行,这里加了个==是做个保险。
setOpacity()方法:
function setOpacity() {
element.style.filter = 'alpha(opacity=' + parseInt(end) + ')';
element.style[attr] = parseInt(end) / 100;
clearInterval(timer);
}
ie8及以下的方法和其他浏览器的方法。
以上就差不多可以了,但是缓动还没有做,其实到这里就很简单了。
缓动修改
if (type == 'buffer') {
step = attr == 'opacity' ? (end - getOpacity()) / speed : (end - parseInt(getStyle(element, attr))) / speed;
step = (step > 0) ? Math.ceil(step) : Math.floor(step);
}
如果要使用缓动,step使用三元运算判断,如果attr是opacity,那么就让end减去getOpacity()获取的元素opacity值,然后除以倍速speed,如果attr不是opacity,那么就使用之前的方法,其他的都一样。
整合:
//设置动画
Base.prototype.animation = function(obj) {
for(var i = 0;i<this.arr.length;i++) {
var element = this.arr[i];
var attr = obj['attr'] == 'x' ? 'left' : obj['attr'] == 'y' ? 'top' :
obj['attr'] == 'w' ? 'width' : obj['attr'] == 'h' ? 'height' :
obj['attr'] == 'o' ? 'opacity' : 'left';
var start = obj['start'] != undefined ? obj['start'] :
attr == 'opacity' ? getOpacity() :
parseInt(getStyle(element, attr));
var time = obj['time'] != undefined ? obj['time'] : 30;
var step = obj['step'] != undefined ? obj['step'] : 20;
var add = obj['add'];
var end = obj['end'];
var speed = obj['speed'] != undefined ? obj['speed'] : 6;
var type = obj['type'] == 0 ? 'constant' : obj['type'] == 1 ? 'buffer' : 'buffer';
if(add != undefined && end == undefined) {
end = add + start;
}else if (add == undefined && end == undefined) {
throw new Error('alter增量或target目标量必须传一个!');
}
if(start > end) step = -step;
if(attr == 'opacity') {
element.style.opacity = parseInt(start) / 100;
element.style.filter = 'alpha(opacity=' + parseInt(start) +')';
}else {
element.style[attr] = start + 'px';
}
clearInterval(window.timer);
timer = setInterval(function () {
if(type == 'buffer') {
step = attr == 'opacity' ? (end - getOpacity())/speed :
(end - parseInt(getStyle(element, attr)))/speed;
step = (step > 0) ? Math.ceil(step) : Math.floor(step);
}
if (attr == 'opacity') {
if (step == 0) {
setOpacity();
}else if(step > 0 && Math.abs(getOpacity() - end) <= step) {
setOpacity();
}else if(step < 0 && (getOpacity() - end) <= Math.abs(step)) {
setOpacity();
}else {
var temp = getOpacity();
element.style.opacity = parseInt(temp + step) / 100;
element.style.filter = 'alpha(opacity=' + parseInt(temp + step) + ')'
}
}else {
if (step == 0) {
setTarget();
}else if(step > 0 && Math.abs(parseInt(getStyle(element, attr)) - end) <= step) {
setTarget();
}else if(step < 0 && (parseInt(getStyle(element, attr)) - end) <= Math.abs(step)) {
setTarget();
}else {
element.style[attr] = parseInt(getStyle(element, attr)) + step + 'px';
}
};
},time);
function setTarget() {
element.style[attr] = end + 'px';
clearInterval(timer);
}
function setOpacity() {
element.style.opacity = parseInt(end) / 100;
element.style.filter = 'alpha(opacity=' + parseInt(end) + ')';
clearInterval(timer);
}
function getOpacity() {
if (system.ie <= 8) {
var op = getStyle(element, 'filter');
var s = [];
if (op.match(/opacity=([\d]+)/)) {
s = op.match(/\=([\d]+)/);
} else {
throw new Error('ie8一下没有获取到filter中的opacity值');
}
return parseInt(s[1]);
} else {
return parseFloat(getStyle(element, 'opacity')) * 100;
}
}
}
return this;
}
调用:
$('#pox').click(function() {
$('#box').animation({
'attr': 'o',
'start': 30,
'end': 100,
'step': 7,
'type': 1
})
});
预览图:
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
全部评论 4
吃枣药丸
Google Chrome Windows 10木灵鱼儿
FireFox Windows 10吃枣药丸
Google Chrome Windows 10d
FireFox Windows 10