背景图像全景

时间:2013-07-17 16:57:13

标签: javascript jquery

我有一个关于滚动背景图像的问题,它无休止地重复它。 我遇到的问题是它快速启动但很快变得越来越慢(口吃等)。这是代码:

var panoramaTimeOutId = null;
var panoramaPosition = null;
$('.panorama-left').mousedown(function() {
    panoramaTimeOutId = setInterval(function(){
        panoramaMove(8, 1)
    }, 50);
}).bind('mouseup mouseleave', function() {
       clearInterval(panoramaTimeOutId);
});
$('.panorama-right').mousedown(function() {
    panoramaTimeOutId = setInterval(function(){
        panoramaMove(8, 2)
    }, 50);
}).bind('mouseup mouseleave', function() {
        clearInterval(panoramaTimeOutId);
});
function panoramaMove(amount, direction)
{
    var panorama = document.getElementsByClassName('panorama_foto')[0];
    if(panoramaPosition == null)
    {
        panoramaPosition = panorama.style.backgroundPosition;
        panoramaPosition = parseInt(panoramaPosition[0].replace("px",""));
    }
    if(direction == 1)
    {
        panoramaPosition = panoramaPosition + amount;
        panorama.style.backgroundPosition = panoramaPosition+"px";
    }
    else
    {
        panoramaPosition = panoramaPosition - amount;
        panorama.style.backgroundPosition = panoramaPosition+"px";
    }
}

我已经尝试了一些优化的东西。就像用标准的javascript编写函数一样。在仅通过仅包含简单int的变量递增它之前,仅计算一次panoramaPosition。但它仍然口吃。

我还尝试更改间隔时间和px的数量,但它仍然在某些计算机上断断续续。例如,该网站是专为平板电脑上的平板电脑而设计的,它在电脑上断续续续,我不会对其进行编程。并且它必须在平板电脑上正常工作。

这是一个JSbin示例: http://jsbin.com/upociv/1/edit

希望有人可以提供有关如何优化此提示或一般性建议如何改进它的提示。

快速注意:Ipad(1/2/3)必须支持所有星系片,即8+ firefox chrome等。

2 个答案:

答案 0 :(得分:2)

不要使用越来越多的像素移动panoramaPosition,而是尝试将其移动panoramaPosition % (image width)

通过这种方式,您不会让浏览器尝试无形地平铺从左侧开始10,000像素的背景图像 - 相反,它将永远不必将其平铺两次以上。 (您还可以避免整数溢出错误的小但非零的可能性。)

if(direction == 1)
{
    panoramaPosition = panoramaPosition + amount;
    panorama.style.backgroundPosition = (panoramaPosition%1277)+"px";
}
else
{
    panoramaPosition = panoramaPosition - amount;
    panorama.style.backgroundPosition = (panoramaPosition%1277)+"px";
}

http://jsbin.com/upociv/2/edit

但是,如果你可以在CSS3中实现它,你应该 - Modernizr允许你在JavaScript中检测浏览器是否支持CSS3转换和转换。

答案 1 :(得分:1)

jQuery 有很大的开销,所以我一直在玩重写它,因为我的评论不使用 jQuery 。另外,要尽可能地缓存。调用Panorama会返回一个 Object ,它在属性中包含所有内容。前两个参数是必需的。

我为 addEventListener 做了兼容性的事情我调用了listen,你可能还需要一个用于 getElementsByClassName 的颜色。

DemoCode

function Panorama(fullheight, fullwidth, foto, left, right) {
    var panorama = {};
    // crossbrowser listener
    function listen(node, ev, fn) {
        var a = ev.split(' '), i;
        if (node.addEventListener)
            for (i = 0; i < a.length; ++i)
                node.addEventListener(a[i], fn);
        else
            for (i = 0; i < a.length; ++i)
                node.attachEvent('on' + a[i], fn);
    }
    // short convert (px?) string to number, might be useful
    function Xpx(s) {
        return parseFloat(s.replace(/[^\d.]/, ''));
    }
    // movement
    function move(amount, direction) {
        if(direction) {
            panorama.position += amount;
            if (panorama.position > panorama.width)
                panorama.position %= panorama.width;
            foto.style.backgroundPosition = panorama.position + 'px';
        }
        else {
            panorama.position -= amount;
            if (panorama.position < 0)
                panorama.position = panorama.width - ((-panorama.position) % panorama.width);
            foto.style.backgroundPosition = panorama.position + 'px';
        }
    }
    function zoom(scale) {
        panorama.scale = scale;
        panorama.height = scale * fullheight;
        panorama.width = scale * fullwidth;
        foto.style.zoom = scale;
    }
    panorama.move = move;
    panorama.zoom = zoom;
    // cache nodes
    if (!foto) foto = document.getElementsByClassName('panorama_foto')[0];
    if (!left) left = document.getElementsByClassName('panorama-left')[0];
    if (!right) right = document.getElementsByClassName('panorama-right')[0];
    panorama.node = {
        foto: foto,
        left: left,
        right: right
    };
    // panorama scaled size info
    panorama.height = fullheight;
    panorama.width = fullwidth;
    panorama.scale = 1;
    // values
    panorama.timeout = null;
    panorama.position = 0;
    // left
    listen(left, 'mousedown', function() {
        panorama.timeout = setInterval(
            function(){ move(8, 1); },
            50
        );
    });
    listen(left, 'mouseup mouseout', function() { clearInterval(panorama.timeout); });
    // right
    listen(right, 'mousedown', function() {
        panorama.timeout = setInterval(
            function(){ move(8, 0); },
            50
        );
    });
    listen(right, 'mouseup mouseout', function() { clearInterval(panorama.timeout); });
    return panorama;
}

var pan = Panorama(414, 1277);