【CSON原创】 3D翻转相册发布
2011-03-27 22:57
351 查看
功能说明:
通过鼠标上下左右的移动,翻转呈现相册。支持浏览器IE6 7 8(IE8下会比较卡,IE6 7则不会) firefox chrome
效果图:
// var util = {
$: function(sId) { return document.getElementById(sId); },
addEventHandler: function(elem, type, handler) {
if (elem.addEventListener) {
elem.addEventListener(type, handler, false);
}
else {
elem.attachEvent("on" + type, handler);
}
},
removeEventHandler: function(elem, type, handler) {
if (elem.removeEventListener) {
elem.removeEventListener(type, handler, false);
}
else {
elem.detachEvent("on" + type, handler);
}
},
getComputedStyle: function(elem) {
if (elem.currentStyle)
return elem.currentStyle;
else {
return document.defaultView.getComputedStyle(elem, null);
}
},
getElementsByClassName: function(className, parentElement) {
var elems = (parentElement || document.body).getElementsByTagName("*");
var result = [];
for (i = 0; j = elems[i]; i++) {
if ((" " + j.className + " ").indexOf(" " + className + " ") != -1) {
result.push(j);
}
}
return result;
}
}
// ]]>
// /*
author:xiaoc support ie 6 7 8 firefox chrome
*/
var shower = (function() {
var defaults = {
containerId: 'phos_container', /* id of photos' container */
imgSize: 50, /* size of imgs */
imgMargin: 60, /* margin between every img */
countEveryRow: 4, /* imgs' count every in row */
times: 1.5 /* the max size of biggest scale*/
},
container = util.$(defaults.containerId),
count = document.getElementsByTagName('img').length,
rowCount = Math.ceil(count / defaults.countEveryRow),
newContainer,
newContainer_width = defaults.countEveryRow * defaults.imgSize + (defaults.countEveryRow - 1) * defaults.imgMargin,
newContainer_height = rowCount * defaults.imgSize + (rowCount - 1) * defaults.imgMargin,
subContainers = [],
imgs = container.getElementsByTagName('img'),
centerPoint;
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 = 'width:' + defaults.imgSize + 'px;'
+ 'height:' + defaults.imgSize + 'px;'
+ 'position:absolute;'
+ 'left:' + left + 'px;'
+ 'top:' + top + 'px;'
+ 'display:block;';
}
}
function _setImgsPosition(oSubContainer) {
var imgs = document.getElementsByTagName('img');
if (imgs.length > 0) {
for (var i = 0; i < defaults.countEveryRow; i++) {
if (imgs[0]) {
oSubContainer.appendChild(_setImgsStyle(imgs[0], i));
}
else
break;
}
}
return oSubContainer;
}
/* set the style of images' container */
function _setContainerStyle() {
container.style.cssText = 'width:' + newContainer_width + 'px;'
+ 'height:' + newContainer_height + 'px;'
+'position:relative;'
+ 'background-color:black;';
}
/* init the value of center point of screen */
function _initCenterPoint() {
var len = defaults.imgSize + defaults.imgMargin;
centerPoint = {
left: document.documentElement.clientWidth / 2,
top: document.documentElement.clientHeight / 2
}
}
/* attach events for mouse move */
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);
}
}
}
return {
init: function() {
_setContainerStyle();
_setImgsStyle();
_initCenterPoint();
_attachMouseMoveHandler();
}
}
})();
// ]]>
// shower.init();
// ]]>
实现原理:
根据鼠标的坐标,以及层与层之间缩放的倍数,早鼠标移动时重新计算每层图片的宽度,高度以及位置,形成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 = 'width:' + defaults.imgSize + 'px;' + 'height:' + defaults.imgSize + 'px;' + 'position:absolute;' + 'left:' + left + 'px;' + 'top:' + top + 'px;' + 'display:block;'; } }
设置每个图片样式的私有方法,里面通过图片的索引,设置图片在容器的位置,其中使用到cssText来批量设置样式属性。
function _setContainerStyle() { container.style.cssText = 'width:' + 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>
欢迎转载,但请标明出处:/article/5223719.html
相关文章推荐
- 【CSON原创】javascript椭圆旋转相册发布
- 【CSON原创】基于HTML5的横版射击游戏发布
- 【CSON原创】 图片滑动展开效果发布
- [原创]:2004末的彩蛋,FlashVml1.0(在线图像、动画、3D网页设计工具)发布
- [原创]纯CSS3打造的3D翻页翻转特效
- 非常酷的3D翻转相册展示特效
- 【CSON原创】HTML5游戏《坦克后援队》发布
- 【CSON原创】HTML5字体动态粒子效果发布
- 【CSON原创】CSS的障眼法:利用border实现图片的翻转
- 【CSON原创】HTML5圈泡泡游戏发布
- CSS3——3D翻转相册
- 【CSON原创】 图片放大器效果发布
- 【CSON原创】javascript实现3D房间
- 【CSON原创】HTML5第一人称射击游戏发布
- 【CSON原创】javascript实现3D涂鸦效果
- Google发布多平台基于网页的3D API“O3D”
- CSS 3D翻转卡片动画
- 微信小游戏正式发布原创保护四大措施
- 【Cson原创】IE下:当eval遇上function
- 3d翻转动画记录