jQuery折叠褪色div和展开动画问题

发布于 2024-10-18 03:04:48 字数 373 浏览 1 评论 0原文

我正在尝试将图像动画化为 div 的完整宽度和高度,它与我期望的左上角图像一起使用,但其他图像将图像移动到左上角,然后对其进行动画处理

这是我的 jsFiddle 的链接

有没有办法让兄弟姐妹淡出,然后从当前位置为图像设置动画?

谢谢

解决方案

为了获得在所有浏览器中都有效的我想要的效果,我这样做了jsFiddle

感谢 iWasRobbed 帮助解决问题

I'm trying to animate an image to the full width and height of a div it works with the top left image as i'd expect but the others it moves the image to the top left and then animates it

Here's a link to my jsFiddle

Is there a way to fade the siblings out and then animate the image from its current position?

Thanks

SOLUTION

To get my desired effect which works in all browsers I did this jsFiddle

Thanks to iWasRobbed for helping with the solution

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

洛阳烟雨空心柳 2024-10-25 03:04:48

这绝对是可能的,只是不能使用 fadeInfadeOut 函数。相反,您必须为绝对定位元素设置不透明度动画。如果您尝试使用 fadeInfadeOut 那么它不会执行任何操作。

这是一个 jfiddle 版本,它在 jQuery 1.5.0 中工作(为看不到损坏图像符号的 Firefox 用户添加了 Orbling 图像):

<!DOCTYPE html>
<html>
<style media="screen" type="text/css">
    /* positioning */
    img.topLeft {position: absolute; top: 0; left: 0;}
    img.topRight {position: absolute; top: 0; right: 0;}
    img.bottomLeft {position: absolute; bottom: 0; left: 0;}
    img.bottomRight {position: absolute; bottom: 0; right: 0;}

    /* element dimensions */
    div.work {background-color: #ddd; height:240px; position: relative; width:300px;}
    img {width:150px; height:120px; border:none;}
</style>
<body>
<div class="work">
    <a href="#"><img class="topLeft" src="https://i.sstatic.net/JQFbb.jpg" /></a>
    <a href="#"><img class="topRight" src="https://i.sstatic.net/l5OPs.jpg" /></a>
    <a href="#"><img class="bottomLeft" src="https://i.sstatic.net/okxQz.jpg" /></a>
    <a href="#"><img class="bottomRight" src="https://i.sstatic.net/4uPHw.jpg" /></a>
</div>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
    // prevent click jump
    $('a').click(function() {
    return false;
    });

    // do work
    $('img').hover(
    function(){
        console.log( "mouseEnter" );
        var $that = $(this);
        $(this).parent().siblings('a').animate({opacity: 0},function() {
            $that.animate({
                width: "300px",
                height: "240px"
            });
        });
    },
    function(){
        console.log( "mouseLeave" );
        var $that = $(this);
        $(this).animate({
            width: "150px",
            height: "120px"
        }, 1500, function () {
            $that.parent().siblings('a').animate({opacity: 1});
        });
    });
});
</script>
</body>
</html>

It definitely is possible, just not with the fadeIn or fadeOut functions. Instead, you have to animate opacity on absolutely positioned elements. If you try and use fadeIn or fadeOut then it does nothing.

Here is a jfiddle version with jQuery 1.5.0 where it works (added Orbling's images for Firefox users who can't see a broken image symbol): http://jsfiddle.net/iwasrobbed/qPkr5/1/

<!DOCTYPE html>
<html>
<style media="screen" type="text/css">
    /* positioning */
    img.topLeft {position: absolute; top: 0; left: 0;}
    img.topRight {position: absolute; top: 0; right: 0;}
    img.bottomLeft {position: absolute; bottom: 0; left: 0;}
    img.bottomRight {position: absolute; bottom: 0; right: 0;}

    /* element dimensions */
    div.work {background-color: #ddd; height:240px; position: relative; width:300px;}
    img {width:150px; height:120px; border:none;}
</style>
<body>
<div class="work">
    <a href="#"><img class="topLeft" src="https://i.sstatic.net/JQFbb.jpg" /></a>
    <a href="#"><img class="topRight" src="https://i.sstatic.net/l5OPs.jpg" /></a>
    <a href="#"><img class="bottomLeft" src="https://i.sstatic.net/okxQz.jpg" /></a>
    <a href="#"><img class="bottomRight" src="https://i.sstatic.net/4uPHw.jpg" /></a>
</div>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
    // prevent click jump
    $('a').click(function() {
    return false;
    });

    // do work
    $('img').hover(
    function(){
        console.log( "mouseEnter" );
        var $that = $(this);
        $(this).parent().siblings('a').animate({opacity: 0},function() {
            $that.animate({
                width: "300px",
                height: "240px"
            });
        });
    },
    function(){
        console.log( "mouseLeave" );
        var $that = $(this);
        $(this).animate({
            width: "150px",
            height: "120px"
        }, 1500, function () {
            $that.parent().siblings('a').animate({opacity: 1});
        });
    });
});
</script>
</body>
</html>
白云不回头 2024-10-25 03:04:48

是啊,决定玩玩这个,可不容易实现。

这是我到目前为止所得到的,仍然有很多问题,但这是一个起点。

演示:http://jsfiddle.net/NzcZH/

初始布局

初始布局

淡入淡出

褪色

增长

增长

Fullsize

Fullsize


本质上,每个图像都挂接到 .mouseenter() (文档) / .mouseleave()(docs) 事件,并尝试激活所需的图像,或根据需要停用它,如果某些事情已经发生,则会创建一个原始队列(需要修复)。

激活就是你的方式,通过一些修改,它会淡出不透明度,然后增长活动图像。停用则相反,将活动图像缩小回原始图像,然后淡入(通过不透明度)。

对模型的更改主要是执行此类动画所需的 HTML/CSS。

如果您直接使用 .fadeIn()(docs) / .fadeOut()(文档) 例程,这些 .hide()(docs) 最后的图像 (display: none;),这会将它们从场景中删除,并最终将未褪色的活动图像移动到顶角,这破坏动画。使用不透明度和图像的绝对定位来将它们固定到位效果更好。您可以让它们淡出和隐藏,并在动画之前重置坐标,但如果您想要任何重叠,那就不好了。

理想情况下,应该更改图像上的 z-index 以使活动项目保持在顶部,这将允许并行淡入淡出和增长,目前它是上演的。

[我正在使用 .data()(docs) 例程来存储当前状态而不是一堆变量,有点整洁。]

HTML 结构

<div class="work">
    <img id="tl" width="150" height="120" src="https://i.sstatic.net/JQFbb.jpg" border="0" />
    <img id="tr" width="150" height="120" src="https://i.sstatic.net/l5OPs.jpg" border="0" />
    <img id="bl" width="150" height="120" src="https://i.sstatic.net/okxQz.jpg" border="0" />
    <img id="br" width="150" height="120" src="https://i.sstatic.net/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);
            }
        });
    });
}

Right, decided to have a play with this, it is not at all easy to achieve.

This is as far as I have got so far, still quite bugged, but it's a starting point.

Demo: http://jsfiddle.net/NzcZH/

Initial Layout

Initial Layout

Fading

Fading

Growing

Growing

Fullsize

Fullsize


Essentially, each image is hooked in to the .mouseenter()(docs) / .mouseleave()(docs) events, and an attempt is made to activate the required image, or deactivate it as required, if something is already going on, a primitive queue is created (which needs fixing).

Activation is how you had it, with a couple of modifications, it fades the opacity out, then grows the active image. Deactivation is the reverse, shrink the active image back to the original, and then fade in (via opacity).

The changes to the model are mainly HTML/CSS necessities to do this sort of animation.

If you use straight .fadeIn()(docs) / .fadeOut()(docs) routines, these .hide()(docs) the images (display: none;) at the end, which removes them from the scene and ends up moving the non-faded, active image to the top corner, which breaks the animation. Using opacity instead and absolute positioning of the images to hold them in place works better. You could let them fade and hide, and reset the coordinates before animation instead, but that is no good if you wanted any overlap.

Ideally, the z-index should be altered on the images to keep the active item on top, this would allow parallel fading and growing, at present it is staged.

[I'm using the .data()(docs) routine to store current state rather than a load of variables, bit neater.]

HTML Structure

<div class="work">
    <img id="tl" width="150" height="120" src="https://i.sstatic.net/JQFbb.jpg" border="0" />
    <img id="tr" width="150" height="120" src="https://i.sstatic.net/l5OPs.jpg" border="0" />
    <img id="bl" width="150" height="120" src="https://i.sstatic.net/okxQz.jpg" border="0" />
    <img id="br" width="150" height="120" src="https://i.sstatic.net/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 Code

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);
            }
        });
    });
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文