1

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

见视觉表现

4

3 回答 3

6

编辑:根据 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. 检索当前元素位置(topleftCSS 属性)
  2. 反转事件返回的增量值mousewheel,因此向上滚动我们有一个负增量,向下滚动我们有一个正增量
  3. 设置定义对角线移动方向和度数所需的因子值
  4. 计算新位置
  5. 移动对象。

要更改度数和方向,只需更改factorX和/或factorY值,以便:

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

这是一个您可以测试的演示。

备选方案 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 表示速度的一倍半,或 2 表示两倍的速度,等等)。

可以在演示中尝试。


编辑

只是为了知识,您可以使用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-等)。

这是一个工作演示(如果它不起作用,您可能必须根据浏览器的特定前缀 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;
    });
});

这是一个工作演示


奖金:想法

代替对每个元素使用公共局部变量,HTML5data-*属性可以用来存储元素的数据(例如:校正因子、最后位置等),然后.data()可以使用 jQuery 方法检索这些数据并处理它们。

亲:

  • 将回调函数与元素解耦
  • 自定义页面上的每个元素以彼此不同

缺点:

  • 它可能会以某种方式影响渲染性能,尤其是是否必须通过回调函数同时管理许多元素。
于 2013-02-04T22:54:02.420 回答
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;
}

观看演示

于 2013-02-04T23:02:57.947 回答
0

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

这支笔

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

在这里发布的代码太大了,它可能比 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
      });
    }
  });
于 2014-10-27T15:55:53.217 回答