利用JS和CSS3实现多浏览器图片旋转

2011年6月11日 · 14 years ago

很久以前写过一个利用JS和CSS3实现全浏览器图片旋转的,用在一个站点的首页上,后来那个站点没继续做下去,就没怎么再留意这个,最近项目要用到,就把JS代码OO封装了一下,顺便留点笔记下来。
截图如下:

一、原理

CSS3提供了transform: rotate(ndeg);方法用来作为元素旋转,其中n是数字。
目前支持CSS3的浏览器有Firefox,Chrome,Safari,Opera和IE9以上版本。但是每个浏览器使用的时候语句都不相同,Firefox加了-moz前缀,webkit引擎的(chrome,safari)加了-webkit前缀等等,所以要针对不同浏览器写不同的语句。另外,IE7,8都不支持CSS3,所以要使用IE的filter来进行旋转操作。[测试发现IE6是最最杯具的,完全用不了rotate,( -___- )b]

二、实践

1.编写HTML代码

<div>
<ul>
<li><img src="images/photo001.jpg" /></li>
<li><img src="images/photo001.jpg" /></li>
<li><img src="images/photo001.jpg" /></li>
<li><img src="images/photo001.jpg" /></li>
<li><img src="images/photo001.jpg" /></li>
</ul>
</div>

这里定义了一个ul列表,里面放着5张图片。

2.CSS文件

这里用li把图片包括之后,再使用绝对定位,以便图片的动画编写。

.photo-outer{margin: 0 auto;width: 1100px;overflow: hidden;border: 1px solid #000;}
.photo{width: 100%;height: 200px;position: relative;}
.photo li{position: absolute;padding: 4px;width: 200px;border: 1px solid #DDD;border-radius: 4px;box-shadow: 0px 0px 6px #DDD;background:#FFF;}
.photo li img{max-width: 100%;}
注意到这个CSS文件里面并没有写到transform语句,这是因为我原先的意图是使用JS做旋转动画,所以没必要在CSS里面先定义它的rotate参数,如果你仅仅是想要一个静态的图片旋转的页面那就直接写进去吧,当然想要每张图片都旋转不同角度就得每个li写一个语句,CSS3语句如下:

-moz-transform: rotate(-12deg); /*Firefox*/
-webkit-transform: rotate(-12deg); /*webkit引擎的浏览器,如safari和chrome*/
-o-transform: rotate(-12deg); /*Opera*/
-ms-transform: rotate(-12deg); /*IE9*/

3.JS代码

注意这里我用了JQuery框架。
首先我们需要定义一个Photo类(JS的类的定义很特殊,它的function既可以是函数也可以是类的声明外加构造函数,使用它作为类的时候,只要在实例化的时候使用New关键字就行了),接收一个index参数来确定它属于列表当中的哪一个:
//声明类和构造函数
function Photo(index){
//JS元素从1开始算起而CSS元素从0开始算起,从CSS选择器里面获取到的index是从0开始的,所以要+1
this.index = index+1;
//获取当前图片所在的li的对象
this.li = $('.photo li:nth-child('+this.index+')');
}
//声明类的方法
Photo.prototype={
//用来设置li的位置
setPos: function(posX, posY){
this.li.css({left: posX,top: posY});
},
rotate: function($deg){
//这几句用来定义CSS3的旋转参数,配合setTimeOut多次调用就可以变成动画了。
this.li.css({'-moz-transform': 'rotate('+ $deg +'deg)'});
this.li.css({'-webkit-transform': 'rotate('+ $deg +'deg)'});
this.li.css({'-0-transform': 'rotate('+ $deg +'deg)'});
this.li.css({'-ms-transform': 'rotate('+ $deg +'deg)'});
//下面是针对IE7、8
//自定义函数,把度数转换为弧度
$rad = degToRad($deg);
//计算cos和sin值
$costheta = Math.cos($rad);
$sintheta = Math.sin($rad);
//给css写入filter
this.li.css({
filter: 'progid:DXImageTransform.Microsoft.Matrix(sizingMethod=\'auto expand\', M11=' + $costheta + ', M12=' + (-$sintheta) + ', M21=' + $sintheta + ', M22=' + $costheta + ')progid:DXImageTransform.Microsoft.Shadow(color=#f4f0e7,direction=0)progid:DXImageTransform.Microsoft.Shadow(color=#f4f0e7,direction=90)progid:DXImageTransform.Microsoft.Shadow(color=#f4f0e7,direction=225)progid:DXImageTransform.Microsoft.Shadow(color=#f4f0e7,direction=270)'
});
this.li.css({'transform': 'rotate('+ $deg +'deg)'});
}
}
在针对IE7、8写filter的时候用到一个自定义函数,代码如下:
var pi = Math.PI;
function degToRad(x) { return ( x/(360/(2*pi)) ); }
用来把度数转换成弧度。
然使用到IE的一个filter,
progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand', M11=$costheta, M12=(-$sintheta), M21=$sintheta, M22=$costheta)
这个函数使用起来真够麻烦的,各位想知道原理可以google一下该函数,会出来MicroSoft的官网解释= =
最后,类定义完了我们在页面加载完之后调用之即可:
$(document).ready(function(){
//获取当前li节点的个数,CSS从0开始计数,所以值是4
var n = $('.photo li:last-child').index();
//新建一个photo数组
var photo = new Array();
//每个photo数组的元素实例化一个photo对象
for($i=0;$i<=n;$i++){
photo[$i] = new Photo($i);
}
//现在就可以针对每个不同的photo实例进行方法调用鸟~setPos是设置left和top的值来定位,rotate则是旋转了,接收一个度数作为参数
photo[0].setPos(20,20);
photo[0].rotate(-12);
photo[1].setPos(220,20);
photo[1].rotate(2);
photo[2].setPos(420,20);
photo[2].rotate(0);
photo[3].setPos(620,20);
photo[3].rotate(-15);
photo[4].setPos(820,20);
photo[4].rotate(5);
});

OK,这就是俺写了一下午的结果鸟,主要是JS的OO封装不太熟悉,看了好一会《编写高质量代码》这本书,写得可真不错。
全部代码打包下载