在计算时还要注意一个问题,上面提到在webkit和ie8,left和top都需要除以scale来修正,当scale接近0到一定程度,结果会变成Infinity(无穷大)。
用Infinity进行运算会出错,需要修正这个问题:
left = Math.min(MAX, Math.max( -MAX, left )) | 0;
top = Math.min(MAX, Math.max( -MAX, top )) | 0;
其中MAX是Number.MAX_VALUE(js能表达的最大数)。
【base模式】
还有兼容全部浏览器的base模式,用的是传统的方法,即根据缩放比例,计算并设置每个图片的尺寸和位置。
每次显示时,历遍层里面的图片,再逐个计算设置。
计算需要图片的原始位置和尺寸,在第一次计算时会把数据保存在_original属性中:
var original = img._original = img._original || {
width: img.offsetWidth, height: img.offsetHeight,
left: img.offsetLeft, top: img.offsetTop
};
尺寸只要根据比例缩放就行,位置除了计算相对层的缩放还要加上相对容器的位移,这个跟zoom模式的计算是一样的。
理解了层变换的方式后,再理解这个就不难了。
【zIndex】
深度除了要缩放和定位,还需要合理的前后遮盖。
前后遮盖需要用来实现,可以在图片或层上设置。
首先最简单的方法是在层上设置:
复制代码 代码如下:
<style>
div,img{width:200px;height:200px;position:absolute;left:0;top:0;}
img{width:150px;height:150px;}
</style>
<div>
<img alt="300">
</div>
<div>
<img alt="100">
</div>
实现一般的3D效果可以这样设置。
但点击测试,在ff和webkit前面的能触发后面的不能触发,而ie和opera就前后都可以触发。
ps:如果img换成div,那么ie和opera后面的元素也不能触发,原因还不清楚。
这样要想像3DRoom那样触发图片事件的话就不能在层设置zIndex。
还可以在图片上设置:
复制代码 代码如下:
<style>
div,img{width:200px;height:200px;position:absolute;left:0;top:0;}
img{width:150px;height:150px;}
</style>
<div>
<img alt="300">
</div>
<div>
<img alt="100">
</div>
这样图片在所有浏览器都能正常触发,但在ie6/7层叠的效果失效了,看来在ie6/7只能在层用zIndex。
还有一个问题,如果给div加上变换效果:
div{-moz-transform:scale(1);-webkit-transform:scale(1);-o-transform:scale(1);}
那图片上的zIndex就会失效,那css3模式就只能在层设置zIndex了。
总结一下:
在css3模式肯定要在层设置zIndex,但图片也不能触发事件。
在zoom和base模式,应该在图片设置zIndex,但在ie6/7就要在层设置。
这样至少在base模式层叠和图片触发事件都是正常的。
【msInterpolationMode】
开始做的时候,效果在ie8下会很卡,但这个3DRoom却不会卡,最后发现是使用了-ms-interpolation-mode。
这个东西在aoao的文章中看过,但没想到可以用在这里。
在MSDN有msInterpolationMode的介绍:
Gets or sets the interpolation (resampling) method used to stretch images.
即获取或设置用于拉伸图像的插值(重采样)方法。
它有两个值:
nearest-neighbor:使用近邻插值模式。
bicubic:使用高品质的双三次插值模式。
这些名词比较专业,我们只要知道使用nearest-neighbor效率高但效果差,而bicubic效果好效率低就够了。
程序把它设为nearest-neighbor提高效率,这样在ie8中也不会卡了。
【拖动方向变换/滚轮深度变换】