对角滚动div

时间:2013-02-04 21:46:48

标签: javascript jquery html css

如何对角创建div滚动?常规滚动会上/下或左/右,但我想让div向上滚动向右滚动向下在左边。

See visual representation

3 个答案:

答案 0 :(得分:5)

编辑:根据OP的要求,我更新了示例代码以引入校正因子,这是修改对角线移动方向和度数所必需的。

如果你想使用jQuery,你必须下载MouseWheel插件。

然后,您可以编写一个绑定到mousewheel事件的简单函数,例如:

<强> HTML

<div id="block"></div>

<强> CSS

#block {
    position: absolute;
    width: 200px;
    height: 150px;
    top: 200px;
    left: 50px;
    background-color: red;
}

备选方案1:JS使用CSS top and left

$(function(){
    $(window).on('mousewheel', function(evt,delta){
        var $block = $('#block'),
            // retrieves the top and left coordinates
            top = parseInt($block.css('top')),
            left = parseInt($block.css('left')),
            // mouse wheel delta is inverted respect to the direction, so we need to
            // normalize it against the direction
            offset = -1 * delta,
            // X and Y factors allows to change the diagonal movement direction and
            // degree. Negative values inverts the direction.
            factorX = 5,
            factorY = 2,
            // calculates the new position. NOTE: if integers only are used for factors,
            // then `Math.floor()` isn't required.
            newTop = top + Math.floor(offset * factorY),
            newLeft = left - Math.floor(offset * factorX);

        // moves the block
        $block.css({ 
            top: newTop + 'px',
            left: newLeft + 'px'
        });
    });
});

备选方案2:JS使用offset()

$(function(){
    $(window).on('mousewheel', function(evt,delta){
        var $block = $('#block'),
            // retrieves the top and left coordinates
            position = $block.offset(),
            // mouse wheel delta is inverted respect to the direction, so we need to
            // normalize it against the direction
            offset = -1 * delta,
            // X and Y factors allows to change the diagonal movement direction and
            // degree. Negative values inverts the direction.
            factorX = 5,
            factorY = 2,
            // calculates the new position. NOTE: if integers only are used for factors,
            // then `Math.floor()` isn't required.
            newTop = position.top + Math.floor(offset * factorY),
            newLeft = position.left - Math.floor(offset * factorX);

        // moves the block
        $block.offset({ top: newTop, left: newLeft });
    });
});

现在,您可以通过向上滚动向上和向右移动框,反之亦然向下滚动框。 在此示例中,在每个mousewheel事件上,回调函数:

  1. 检索当前元素位置(topleft CSS属性)
  2. 反转mousewheel事件返回的delta值,因此向上滚动我们有一个负delta,向下滚动我们有一个正delta
  3. 设置定义对角线移动方向和度数所需的因子值
  4. 计算新职位
  5. 移动对象。
  6. 要更改程度和方向,只需更改factorX和/或factorY值,即可:

    • 负值反转方向,
    • 不同的值会改变度数(例如,X = 2和Y = 5会使元素以更大的闭合角度移动,相对于X = 5和Y = 2)。

    这是你可以测试的demo

    备选3:JS使用cos()和sin()

    $(function(){
        $(window).on('mousewheel', function(evt,delta){
            var $block = $('#block'),
                // read current block position
                position = $block.offset(),
                // inverts the delta; scroll up == -1 - scroll down == +1
                direction = -1 * delta,
                // sets the angle and converts it in radians
                angle = 45 * Math.PI / 180,
                // set displacememt factor
                factorX = Math.cos(angle) * direction,
                factorY = Math.sin(angle) * direction,
                // calculate the new position
                newTop = position.top + factorY,
                newLeft = position.left - factorX;
    
            // moves the block
            $block.offset({ top: newTop, left: newLeft });
        });
    });
    

    在此示例中,要更改的是angle中的值(本例中为45)。其他一切都像其他例子一样有效。

    最后,如果需要更改运动的速度,只需将factorX和/或factorY乘以所需系数(例如,1.5为1)速度的一半时间,或速度的两倍,等等。)

    可以在demo中尝试。


    修改

    只是为了知识,您可以使用CSS Transform达到相同的目标。这使您可以利用GPU加速硬件。 (更多信息可以在Smashing MagazinePaul Irish)的文章中找到。

    <强> HTML

    <div id="block"></div>
    

    <强> CSS

    #block {
        width: 200px;
        height: 150px;
        background-color: red;
        transform: translate3d(0, 0, 0);
    }
    

    <强> JS

    $(function(){
        var blockOffsetX = 50,
            blockOffsetY = 200;
    
        $('#block').css({
            transform: 'translate3d(' + blockOffsetX + 'px' + ', ' + blockOffsetY + 'px, 0)'
        });
    
        $(window).on('mousewheel', function(evt,delta){
            var $block = $('#block'),
                offset = -1 * delta;
                factorX = 5,
                factorY = 2;
    
            blockOffsetX -= offset * factorX;
            blockOffsetY += offset * factorY;
            $block.css({ 
                transform: 'translate3d(' + blockOffsetX + 'px, ' + blockOffsetY + 'px, 0)'
            });
        });
    });
    

    但是,正如您在本示例中所看到的,您需要跟踪元素X,Y位置,因为直接从CSS检索这些值有点复杂。此外,此示例更容易,但在生产中,您必须支持每个供应商特定的CSS属性(-webkit--moz--o--ms-等。)

    这是一个有效的demo(如果它不起作用,您可能需要根据浏览器的特定前缀CSS属性编辑代码。)


    编辑:由于OP已经看到听scroll事件对他来说是更好的选择,我已经添加了相关代码(只有JS代码这里报告,因为HTML和CSS与第一个例子相同:

    $(function(){
        var lastScrollYPos = 0;
        $(window).on('scroll', function(){
            var $this = $(this),
                $block = $('#block'),
                // retrieves the top and left coordinates
                position = $block.offset(),
                // X and Y factors allows to change the diagonal movement direction and
                // degree. Negative values inverts the direction.
                factorX = 1,
                factorY = 1,
                // retrieves current vertical scrolling position and calculate the
                // relative offset
                scrollYPos = $this.scrollTop(),
                offset = Math.abs(scrollYPos - lastScrollYPos),
                // mouse wheel delta is inverted respect to the direction, so we need to
                // normalize it against the direction
                direction = scrollYPos > lastScrollYPos ? -1 : 1,
                // calculates the new position. NOTE: if integers only are used for factors,
                // then `Math.floor()` isn't required.
                newTop = position.top + Math.floor(direction * offset * factorY),
                newLeft = position.left - Math.floor(direction * offset * factorX);
    
            // moves the block
            $block.offset({ top: newTop, left: newLeft });
            lastScrollYPos = scrollYPos;
        });
    });
    

    这是一个有效的demo


    BONUS:IDEA

    不是为每个元素使用公共局部变量,而是可以使用HTML5 data-*属性来存储元素的数据(例如:校正因子,最后位置等),然后jQuery .data()方法可以用于检索这些数据并进行处理。

    PRO:

    • 将回调函数与元素
    • 分离
    • 自定义页面上的每个元素以使其彼此不同

    CONS:

    • 它可能会以某种方式影响渲染性能,尤其是回调函数是否必须同时管理许多元素。

答案 1 :(得分:2)

您可以使用onScroll事件,检测用户是垂直还是水平滚动,然后适当地滚动另一个方向。

示例:

<强> JS

var lastScrollTop = 0;
$("#diagonalscroller").scroll(function(e) {
    var scrollTop = $(this).scrollTop();    
    if (scrollTop === lastScrollTop) {
        // Vertical scroll position is unchanged, so we're scrolling horizontal.
        $(this).scrollTop($(this).scrollLeft());
    } else {
        // Vertical scroll position has changed, so we're scrolling vertical.
        $(this).scrollLeft($(this).scrollTop());
    }
    lastScrollTop = scrollTop;
});

<强> HTML

<h1>Try scrolling using the scrollbars</h1>
<div id="diagonalscroller">
    <img src="http://dummyimage.com/800/" />
</div>

<强> CSS

#diagonalscroller {
 width: 200px;
 height: 200px;
 overflow: scroll;
}

观看Demo

答案 2 :(得分:0)

老问题..但是遇到这个问题的人可能会喜欢

  
    

this pen

  

这是对角网页布局的概念。

这里的代码很大,可能比OP要求更多。

要发布代码。这是魔术的一部分。 (使用Modernizr进行跨浏览器支持)

  var $window = $(window);
  var con = $('#content');
  $window.on('touchmove scroll', function() {
    var winScroll = $window.scrollTop() * -1;
    if (!Modernizr.csstransforms3d && Modernizr.csstransforms) {
      con.css({
        transform: 'translate(' + winScroll + 'px,' + winScroll + 'px)'
      });
    } else if (Modernizr.csstransforms3d) {
      con.css({
        transform: 'translate3d(' + winScroll + 'px,' + winScroll + 'px,0)'
      });
    } else {
      con.css({
        left: winScroll,
        top: winScroll
      });
    }
  });