对,决定玩一下这个,一点都不轻松。
这是我目前所了解的,仍然有很多问题,但这是一个起点。
演示:http://jsfiddle.net/NzcZH/
初始布局
褪色
成长
全尺寸
本质上,每个图像都与.mouseenter()(docs) / .mouseleave()(docs) 事件挂钩,并尝试激活所需的图像,或根据需要停用它,如果某些事情已经发生,则会创建一个原始队列(需要修复)。
Activation 就是你的方式,经过一些修改,它会淡出不透明度,然后增大活动图像。停用则相反,将活动图像缩小回原始图像,然后淡入(通过不透明度)。
模型的变化主要是 HTML/CSS 做这种动画的必要性。
如果你直接使用.fadeIn()(docs) / .fadeOut()(docs) 例程,这些.hide()(docs)最后的图像(display: none;),这会将它们从场景中移除并最终将未褪色的活动图像移动到顶角,这会破坏动画。使用不透明度和图像的绝对定位来将它们固定在适当的位置效果更好。您可以让它们淡出和隐藏,并在动画之前重置坐标,但如果您想要任何重叠,那就不好了。
理想情况下,应更改图像上的z-index 以将活动项目保持在顶部,这将允许并行淡入淡出和增长,目前它已上演。
[我正在使用.data()(docs) 例程来存储当前状态而不是大量变量,更简洁一点。]
HTML 结构
<div class="work">
<img id="tl" width="150" height="120" src="http://i.stack.imgur.com/JQFbb.jpg" border="0" />
<img id="tr" width="150" height="120" src="http://i.stack.imgur.com/l5OPs.jpg" border="0" />
<img id="bl" width="150" height="120" src="http://i.stack.imgur.com/okxQz.jpg" border="0" />
<img id="br" width="150" height="120" src="http://i.stack.imgur.com/4uPHw.jpg" border="0" />
</div>
CSS
.work {
padding: 5px 5px;
border: 1px solid black;
width: 309px;
height: 249px;
}
.active { border: 1px solid red; }
img { position: absolute; border: 1px dashed #aaa; }
#tl { top: 16; left: 16; }
#tr { top: 16; left: 171px; }
#bl { top: 141px; left: 16; }
#br { top: 141px; left: 171px; }
jQuery 代码
var work = $('.work');
var workImages = work.find('img');
var growSpeed = 1500;
var fadeSpeed = 500;
work.data('changing', false).data('queue', false);
workImages.mouseenter(function() {
var activeImg = workImages.filter('.active');
if (activeImg.length == 0) {
activate(this);
}
}).mouseleave(function() {
var activeImg = workImages.filter('.active');
if (activeImg.length > 0) {
deactivate();
}
});
function activate(cImg) {
if (work.data('changing') !== false) {
work.data('queue', cImg);
return;
}
var activeImg = workImages.filter('.active');
if (activeImg.length != 0) {
return;
}
work.data('changing', cImg);
activeImg = $(cImg);
activeImg.addClass('active');
if (!activeImg.data('origPos')) {
activeImg.data('origPos', { left: parseInt(activeImg.css('left')), top: parseInt(activeImg.css('top')) } );
}
workImages.stop();
workImages.not(activeImg).animate({ opacity: 0 }, fadeSpeed, 'linear', function() {
activeImg.animate({
left: 16,
top: 16,
width: 307,
height: 247
}, growSpeed, 'linear', function() {
work.data('changing', false);
if (work.data('queue') !== false) {
var queued = work.data('queue');
work.data('queue', false);
if (queued == 'deactivate') {
deactivate();
} else if (queued != cImg) {
deactivate(queued);
}
}
});
});
}
function deactivate(cImg) {
if (work.data('changing') !== false && work.data('changing') !== 'deactivate') {
work.data('queue', 'deactivate');
return;
}
if (cImg) {
work.data('queue', cImg);
}
var activeImg = workImages.filter('.active');
if (activeImg.length == 0) {
return;
}
work.data('changing', 'deactivate');
var origPos = activeImg.data('origPos');
workImages.stop();
activeImg.animate({
left: origPos.left,
top: origPos.top,
width: 150,
height: 120
}, growSpeed, 'linear', function() {
workImages.not(activeImg).animate({ opacity: 100 }, fadeSpeed, 'linear', function() {
activeImg.removeClass('active');
work.data('changing', false);
if (work.data('queue') !== false) {
var queued = work.data('queue');
work.data('queue', false);
activate(queued);
}
});
});
}