功能说明:
通过鼠标上下左右的移动,翻转呈现相册。支持浏览器IE6 7 8(IE8下会比较卡,IE6 7则不会) firefox chrome
效果图:
实现原理:
根据鼠标的坐标,以及层与层之间缩放的倍数,早鼠标移动时重新计算每层图片的宽度,高度以及位置,形成3D翻转效果。翻转角度和鼠标移动位移占页面一半宽度的比例成正比。
代码分析:
var defaults = {
containerId: 'phos_container', /* id of photos' container */
imgSize: 80, /* size of imgs */
imgMargin: 100, /* margin between every img */
countEveryRow: 4, /* imgs' count every in row */
times: 1.5 /* the max size of biggest scale*/
},
首先指定一个储存默认值的单体,里面包括各种默认参数值,如容器ID,图片尺寸等。最后的times是层与层之间的缩放倍数,times越大,则显得图片和图片在翻转时距离较大。
function _setImgsStyle() {
var imgs = container.getElementsByTagName("img");
for (var i = 0; i < imgs.length; i++) {
var left,
top,
distant = defaults.imgMargin + defaults.imgSize,
n = (i + 1) % defaults.countEveryRow;
if (n == 0)
left = (defaults.countEveryRow - 1) * distant;
else
left = (n - 1) * distant;
top = Math.floor(i / defaults.countEveryRow) * distant;
imgs[i].style.cssText = '' + defaults.imgSize + 'px;'
+ 'height:' + defaults.imgSize + 'px;'
+ 'position:absolute;'
+ 'left:' + left + 'px;'
+ 'top:' + top + 'px;'
+ 'display:block;';
}
}
设置每个图片样式的私有方法,里面通过图片的索引,设置图片在容器的位置,其中使用到cssText来批量设置样式属性。
function _setContainerStyle() {
container.style.cssText = '' + newContainer_width + 'px;'
+ 'height:' + newContainer_height + 'px;'
+ 'position:absolute;'
+ 'left:50%;'
+ 'top:50%;'
+ 'margin-left:' + newContainer_width / -2 + 'px;'
+ 'margin-top:' + newContainer_height / -2 + 'px;'
+ 'background-color:black;';
}
设置容器的样式,注意这里和demo的样式设置并不相同,这里是把容器相对于浏览器可视区域水平垂直局中,而demo中由于页面大小限制并没有这样做。
function _initCenterPoint() {
var len = defaults.imgSize + defaults.imgMargin;
centerPoint = {
left: document.documentElement.clientWidth / 2,
top: document.documentElement.clientHeight / 2
}
}
初始化屏幕中心点对象,该中心点是实现翻转效果的参考点。鼠标相对于该中心点的位移决定翻转的角度大小。
function _attachMouseMoveHandler() {
document.documentElement.onmousemove = function(eve) {
eve = eve || window.event;
var xpercent = ((centerPoint.left - eve.clientX) / centerPoint.left),
ypercent = ((centerPoint.top - eve.clientY) / centerPoint.top),
max_img_size = defaults.times * defaults.imgSize,
_size, _top, _left;
for (var i = 0; i < imgs.length; i++) {
var n = i % defaults.countEveryRow;
var m = Math.floor(i / defaults.countEveryRow);
if (xpercent > 0) {
var xtimes = (1 - n * (1 / defaults.countEveryRow)),
size = xpercent * max_img_size * xtimes + (1 - xpercent) * defaults.imgSize,
xaddleft = ((newContainer_width - max_img_size * xtimes) / 2 - (defaults.imgSize + defaults.imgMargin) * n) * xpercent,
xtop = -((max_img_size * xtimes - defaults.imgSize) / 2) * xpercent;
}
else if (xpercent < 0) {
var xtimes = 1 + (n - (defaults.countEveryRow - 1)) * (1 / defaults.countEveryRow),
size = -xpercent * max_img_size * xtimes + (1 + xpercent) * defaults.imgSize;
xaddleft = ((newContainer_width - max_img_size * xtimes) / 2 - (defaults.imgSize + defaults.imgMargin) * n) * -xpercent,
xtop = -((max_img_size * xtimes - defaults.imgSize) / 2) * -xpercent;
}
_size = size;
_left = (defaults.imgSize + defaults.imgMargin) * n + xaddleft;
_top = m * (defaults.imgSize + defaults.imgMargin) + xtop;
if (ypercent > 0) {
var ytimes = (1 - m * (1 / rowCount)),
size = ypercent * _size * defaults.times * ytimes + (1 - ypercent) * _size,
yaddtop = ((newContainer_width - _size * defaults.times * ytimes) / 2 - _top) * ypercent,
yleft = -((_size * defaults.times * ytimes - _size) / 2) * ypercent;
}
else if (ypercent < 0) {
var ytimes = 1 + (m - (rowCount - 1)) * (1 / rowCount),
size = -ypercent * _size * defaults.times * ytimes + (1 + ypercent) * _size,
yaddtop = ((newContainer_width - _size * defaults.times * ytimes) / 2 - _top) * -ypercent,
yleft = -((_size * defaults.times * ytimes - _size) / 2) * -ypercent;
}
_size = size;
_top = _top + yaddtop;
_left = _left + yleft;
imgs[i].style.width = imgs[i].style.height = _size + 'px';
imgs[i].style.top = _top + 'px';
imgs[i].style.left = _left + 'px';
imgs[i].style.zIndex = Math.ceil(_size);
}
}
}
这里是整个程序最复杂的部分,通过对水平翻转以及垂直翻转两个“分运动”的计算最后得出总体的翻转情况,该实现可以细分为以下几个步骤:
1。获取鼠标x坐标相对于中心点位移占1/2页面宽度的百分比,该百分比映射到翻转角度的变化。
2.首先实现的是水平方向上的翻转,此时需要计算鼠标在水平方向上的移动导致图片大小以及位置的变化情况。
3.然后再在水平翻转计算结果的基础上,计算垂直翻转导致的图片大小以及位置的变化情况。
4.把两个分运动计算结果作为最终结果设置图片的样式值,其中要注意的是由于图片的大小越大,证明离观察者距离越短,所以应该层叠级最高,因此可以直接把图片尺寸取整后作为zIndex的值。
return {
init: function() {
_setContainerStyle();
_setImgsStyle();
_initCenterPoint();
_attachMouseMoveHandler();
}
}
最后返回单体,为调用者提供简单的接口init函数,该函数内部调用上文分析的多个私有函数。
<script>
shower.init();
</script>
欢迎转载,但请标明出处:http://www.cnblogs.com/Cson/archive/2011/03/27/1997267.html