【CSON原创】CSS的障眼法:利用border实现图片的翻转

功能说明:

利用css的border实现图片的翻转效果,支持从上到下、从下到上,从左到右,从右到左四种翻转。

兼容IE 7 8 9 10 firefox chrome

效果预览:


 
 
 
 

 

实现原理:

  之所以说这是CSS的障眼法,是因为这种效果并不是使用CSS原生的属性进行实现的,并不仅仅是使用一张图片,然后通过特定属性使其翻转,因为我们知道CSS并不提供另图片翻转的接口。要实现这种效果,我们需要的是通过图片和外层div的border的配合,使图片看起来翻转了一定角度。

  细心的读者可能会发现,我在选择图片的时候,已经有所讲究,看看上面这幅图片,它具有两个特点

  1.完全对称。

  2.图形周围的空白(黑色部分)较多。

  如果不是满足上述两个特点的图片,翻转效果看起来也会没那么好,要知道原因,首先就要清楚这种翻转效果的实现原理了。

 

  以从右到左的翻转为例,使图片翻转的实现步骤

  1.首先添加一张你需要实现翻转效果的图片,图片绝对定位。

  2.然后我们需要的是一个div,div高度和图片高度相等。该div除了右边框外,其他边框为和背景色一样且borderWidth为0,右边框则为透明且borderWidth和图片宽相等,定位与图片一致,zIndex比图片大。经过这两步后,我们就可以把一个透明正方形(实质上为div的右边框)覆盖在图片上面

  3.之后我们需要的就是使右边框和图片的尺寸和大小动态改变,实现翻转效果。我们开始同时逐渐减少右边框和图片的宽度,并且同时逐渐增大上下边框的宽度和图片的高度,并且调整图片和div的定位,使它们始终保持在原位置,就可以实现图片的翻转效果。简单地说,实现视觉上翻转效果的实际上是div的右边框,但是我们通过把右边框设置为透明从而露出下面的图片,看上去就是图片在翻转。


  之所以我之前说的选择的图片最好要有上面那两个特点:完全对称和四周空白较多。那是因为如果图片不对称,那么图片翻转过去之后,图片的显示就会不合理(没有达到镜像的显示效果,显示位置不对),但是,我也在程序里提供了onHalfLoop和onFullLoop两个回调函数的接口,分别是翻转90度和180度后触发的回调函数。大家完全可以使用ps把一张图片左右(或上下)翻转,然后在onHalfLoop里把图片路径设置为该翻转后图片的路径,在onFullLoop里把路径还原,这样就可以完全克服需要使用完全对称图片这个障碍,使不对称的图片也可以实现翻转。

  至于另一个特点:使用四周空白较多的图片。使用这种图片的好处是消除翻转的时候处在图片边缘的图纹被隐藏所带来的视觉破绽,具体这里说不清楚,不过大家找一张图片四周也有较多图纹的图片试试就清楚了。

 

最后给出所有代码吧,结合代码应该就可以更清楚地了解其中的原理:

  

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>无标题文档</title>
<style type="text/css" rel="stylesheet">
#container
{width:600px; height:500px; background:white; position:relative;}
.borderWrap
{position:absolute; border-style:solid; border-color:white; border-width:0 0 0 0; z-index:10; height:100px; width:0;}
.turnImg
{position:absolute;z-index:1; width:150px; height:100px;}

#borderWrapper1
{ left:100px; top:100px;}
#borderWrapper2
{ left:300px; top:100px;}
#borderWrapper4
{ left:100px; top:300px;}
#borderWrapper3
{ left:300px; top:300px;}

#turnImg1
{left:100px; top:100px;}
#turnImg2
{left:300px; top:100px;}
#turnImg3
{left:100px; top:300px;}
#turnImg4
{left:300px; top:300px;}
</style>
</head>

<body>

<div id="container">
<div id="borderWrapper1" class="borderWrap"></div>
<img id="turnImg1" class="turnImg" src="http://52photoshop.com/quan/photo/201001161611051194.jpg" />
<div id="borderWrapper2" class="borderWrap"></div>
<img id="turnImg2" class="turnImg" src="http://52photoshop.com/quan/photo/201001161611051194.jpg" />

<div id="borderWrapper3" class="borderWrap"></div>
<img id="turnImg3" class="turnImg" src="http://52photoshop.com/quan/photo/201001161611051194.jpg" />

<div id="borderWrapper4" class="borderWrap"></div>
<img id="turnImg4" class="turnImg" src="http://52photoshop.com/quan/photo/201001161611051194.jpg" />

</div>


</body>
<script>
var overturnImg=(function(){

var _overturnImg=function(imgId,wrapperId,options){
this.init(imgId,wrapperId,options);

}
_overturnImg.prototype
=(function(){

var dirObj={//方向对应的扩大border
'RTL':{preHalf:'right',afterHalf:'left'},
'LTR':{preHalf:'left',afterHalf:'right'},
'TTB':{preHalf:'top',afterHalf:'bottom'},
'BTT':{preHalf:'bottom',afterHalf:'top'}
}



var $=function(id){return document.getElementById(id);};
var emptyFunction=function(){};


var changeTurningStyle=function(self){

var timeId;
var speed=self.speed;
var img=self.img;
var borderWrapper=self.borderWrapper;
var bwWidth,imgWidth,bwHeight,imgHeight,bwTop,imgTop,bwLeft,imgLeft,bwOther2Width;
var dir=self.direction;
var preHalf=true;
var enhanceBorder='border-'+dirObj[dir]['preHalf']+'-';//根据旋转方向映射出需要被扩大的border
bwWidth=imgWidth=img.clientWidth;
bwHeight
=imgHeight=img.clientHeight;
bwOther2Width
=0;
bwTop
=imgTop=img.offsetTop;
bwLeft
=imgLeft=img.offsetLeft;

return function(){

var reduceBorder;
if(dir=='RTL'||dir=='LTR'){

if(preHalf){

bwOther2Width
+=speed;
bwWidth
-=speed*2;
bwLeft
+=speed;
bwTop
-=speed;

if(bwWidth<=0){
preHalf
=false;
self.onHalfLoop(self);
enhanceBorder
='border-'+dirObj[dir]['afterHalf']+'-';//根据旋转方向映射出需要被扩大的border
}

}
else{

bwOther2Width
-=speed;
bwWidth
+=speed*2;
bwLeft
-=speed;
bwTop
+=speed;

if(bwWidth>=imgWidth){
preHalf
=true;
enhanceBorder
='border-'+dirObj[dir]['preHalf']+'-';//根据旋转方向映射出需要被扩大的border
self.onFullLoop(self);
}
}

borderWrapper.style.cssText
=enhanceBorder+'width:'+bwWidth+'px;'
+enhanceBorder+'color:transparent;'
+'width:0;'
+'border-top-width:'+bwOther2Width+'px;'
+'border-bottom-width:'+bwOther2Width+'px;'
+'top:'+bwTop+'px;'
+'left:'+bwLeft+'px;';

img.style.cssText
='height:'+(bwOther2Width*2+bwHeight)+'px;'
+'width:'+Math.max(0,bwWidth)+'px;'
+'top:'+bwTop+'px;'
+'left:'+bwLeft+'px;';


}
else if(dir=='TTB'||'BTT'){
if(preHalf){

bwOther2Width
+=speed;
bwHeight
-=speed*2;
bwLeft
-=speed;
bwTop
+=speed;

if(bwHeight<=0){
preHalf
=false;
enhanceBorder
='border-'+dirObj[dir]['afterHalf']+'-';//根据旋转方向映射出需要被扩大的border
self.onHalfLoop(self);
}

}
else{

bwOther2Width
-=speed;
bwHeight
+=speed*2;
bwLeft
+=speed;
bwTop
-=speed;

if(bwHeight>=imgHeight){
preHalf
=true;
enhanceBorder
='border-'+dirObj[dir]['preHalf']+'-';//根据旋转方向映射出需要被扩大的border
self.onFullLoop(self);
}
}

borderWrapper.style.cssText
=enhanceBorder+'width:'+bwHeight+'px;'
+enhanceBorder+'color:transparent;'
+'height:0;'
+'width:'+bwWidth+'px;'
+'border-left-width:'+bwOther2Width+'px;'
+'border-right-width:'+bwOther2Width+'px;'
+'top:'+bwTop+'px;'
+'left:'+bwLeft+'px;';
img.style.cssText
='width:'+(bwOther2Width*2+bwWidth)+'px;'
+'height:'+Math.max(0,bwHeight)+'px;'
+'top:'+bwTop+'px;'
+'left:'+bwLeft+'px;'



}
timeId
=window.setTimeout(arguments.callee,20);

}


}

return{
/* 初始化 */
init:
function(imgId,wrapperId,options){
var strArr=[];
var ags=arguments||[];
var ag;
for(var i=0,len=ags.length;i<len;i++){ //参数修复
ag=arguments[i];
(
typeof ag=='string')?strArr.push(ag):options=ag;
}
imgId
=ags[0];
wrapperId
=ags[1];

options
=options||{};

this.img=$(imgId||'turnImg');//获取要翻转的图片元素
this.borderWrapper=$(wrapperId||'borderWrapper');//获取制造翻转的div元素
this.speed=options.speed||2;
this.direction=options.direction||'RTL';
this.onHalfLoop=options.onHalfLoop||emptyFunction;
this.onFullLoop=options.onFullLoop||emptyFunction;


},
run:
function(){
changeTurningStyle(
this)();
}

};
})();

return _overturnImg;

})();
var b=new overturnImg('turnImg1','borderWrapper1');
b.run();
var b2=new overturnImg('turnImg2','borderWrapper2',{direction:'TTB'});
b2.run();
var b3=new overturnImg('turnImg3','borderWrapper3',{direction:'BTT'});
b3.run();
var b4=new overturnImg('turnImg4','borderWrapper4',{direction:'LTR'});
b4.run();

</script>

 

  可以看看最后的调用方法:

var b=new overturnImg('turnImg1','borderWrapper1');
b.run();
var b2=new overturnImg('turnImg2','borderWrapper2',{direction:'TTB'});
b2.run();
var b3=new overturnImg('turnImg3','borderWrapper3',{direction:'BTT'});
b3.run();
var b4=new overturnImg('turnImg4','borderWrapper4',{direction:'LTR'});
b4.run();


  我们想要使图片向不同的方向翻转,需要的就是在direction中传入不同的数值:RTL(右向左翻转)、LTR(左向右翻转)、BTT(下向上翻转)、TTB(上向下翻转)。

 

  欢迎转载,请标明出处:http://www.cnblogs.com/Cson/archive/2012/02/01/2335087.html

 

  

posted @ 2012-02-01 21:54  Cson  阅读(2511)  评论(3编辑  收藏  举报