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:CSSを上下に使用するJS

$(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:offset()を使用するJS

$(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. 現在の要素の位置(topおよびleftCSSプロパティ)を取得します
  2. イベントによって返されるデルタ値を反転するmousewheelため、上にスクロールすると負のデルタになり、下にスクロールすると正のデルタになります。
  3. 対角線の移動方向と次数を定義するために必要な係数値を設定します
  4. 新しい位置を計算します
  5. オブジェクトを移動します。

次数と方向を変更するには、値を変更するfactorXか、次のようにします。factorY

  • 負の値は方向を反転し、
  • 異なる値は次数を変更します(たとえば、X=2およびY=5は、X=5およびY=2に関して、要素をはるかに閉じた角度で移動させます)。

これがテストできるデモです。

代替案3:cos()とsin()を使用するJS

$(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.5、速度の2倍の場合は2など)。

デモで試すことは可能です。


編集

知識のために、 CSSTransformを使用して同じ目標を達成できます。これにより、GPUアクセラレーションハードウェアを利用できます。(詳細については、SmashingMagazinePaulIrishの記事を参照してください)。

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)'
        });
    });
});

ただし、この例でわかるように、CSSから直接これらの値を取得するのは少し複雑なので、要素のX、Y位置を追跡する必要があります。さらに、この例は簡単に保つことができますが、本番環境では、すべてのベンダー固有のCSSプロパティ(、、、、など)をサポートする必要が-webkit-あります。-moz--o--ms-

これが機能するデモです(機能しない場合は、ブラウザの特定のプレフィックス付きCSSプロパティに従ってコードを編集する必要があります)。


編集:OPは、scrollイベントを聞くことが彼にとってより良い選択であると判断したので、相対コードを追加しました(HTMLとCSSは最初の例とほとんど同じであるため、ここではJSコードのみを報告します):

$(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;
    });
});

これが実際のデモです。


ボーナス:IDEA

すべての要素に共通のローカル変数を使用する代わりに、HTML5data-*プロパティを使用して要素のデータ(たとえば、補正係数、最後の位置など)を格納し、jQuery.data()メソッドを使用してこれらのデータを取得して処理することができます。

プロ:

  • コールバック関数を要素から切り離します
  • ページ上のすべての要素をカスタマイズして、互いに異なる動作をする

短所:

  • 特に、コールバック関数によって多くの要素を同時に管理する必要があるかどうかは、レンダリングのパフォーマンスに何らかの影響を与える可能性があります。
于 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

古い質問..しかし、この質問に出くわした人は誰が好きかもしれません

このペン

これは、斜めのWebページレイアウトの概念です。

コードはここに投稿するには大きすぎて、おそらく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 に答える