10

私は長い間検索してきましたが、私の問題を解決するより良い方法を見つけることができません.divをドラッグ可能にし、これらの2例1 2
のように各ハンドルで回転およびサイズ変更します..

Prasanth KCChangoYi Jiang .. の回答については、これらのコードは正しくない可能性があります。1
.原点を中心に回転ポイントが必要です。
2.半径を考慮する必要があります。

しかし、ここでsinまたはcosを使用して、回転に半径を考慮する方法がわかりませんか?
どんな提案でも大歓迎です。 http://jsfiddle.net/tBgLh/8/

var dragging = false, target_wp;   
$('.handle').mousedown(function(e) {
    var o_x = e.pageX, o_y = e.pageY; // origin point
    e.preventDefault();
    e.stopPropagation();
    dragging = true;
    target_wp=$(e.target).closest('.draggable_wp');

    $(document).mousemove(function(e) {
        if (dragging) {
            var s_x = e.pageX, s_y = e.pageY; // start rotate point
            if(s_x !== o_x && s_y !== o_y){ //start rotate
                var s_rad = Math.atan2(s_y, s_x);
                var degree = (s_rad * (360 / (2 * Math.PI)));
                target_wp.css('-moz-transform', 'rotate(' + degree + 'deg)');
                target_wp.css('-moz-transform-origin', '50% 50%');
                target_wp.css('-webkit-transform', 'rotate(' + degree + 'deg)');
                target_wp.css('-webkit-transform-origin', '50% 50%');
                target_wp.css('-o-transform', 'rotate(' + degree + 'deg)');
                target_wp.css('-o-transform-origin', '50% 50%');
                target_wp.css('-ms-transform', 'rotate(' + degree + 'deg)');
                target_wp.css('-ms-transform-origin', '50% 50%');
            }
        }
    })
    $(document).mouseup(function() {
        dragging = false
    })
})// end mousemove

html

<div class="draggable_wp">
    <div class="el"></div>
    <div class="handle"></div>
</div>
4

2 に答える 2

23

あなたのアプローチには2つの問題があります:

  1. 原点は、ユーザーがクリックした場所 (つまりハンドル) ではなく、div 内の固定ポイントであるべきです。

    target_wp=$(e.target).closest('.draggable_wp');
    //var o_x = e.pageX, o_y = e.pageY; // origin point
    var o_x = target_wp.offset().left,
        o_y = target_wp.offset().top; // origin point
    

    クリックしたポイントも使用します、別の目的で使用します (後で詳しく説明します)。

    var h_x = e.pageX, h_y = e.pageY; // clicked point
    

    最後に、原点を固定する必要があります (つまり、回転間で変更しないでください)。これを行う 1 つの方法は、属性として保存することdataです (ただし、他のオプションもあります)。

    if ( !target_wp.data("origin") )
        target_wp.data("origin", { left:target_wp.offset().left,
                                   top:target_wp.offset().top    });
    var o_x = target_wp.data("origin").left, 
        o_y = target_wp.data("origin").top; // origin point
    

    更新:起点の良い候補の 1 つは CSS プロパティtransform-originです (存在する場合)。これにより、マウスがハンドルにできるだけ近づけるようにする必要があります。ただし、これは実験的な機能であるため、実際の結果は異なる場合があります。PS50% 50%変換自体が要素の幅と高さ、上と左を変える可能性があるため、に設定するのが良い考えかどうかはわかりません。

  2. 角度を見つけるにはatan2、マウス ポイントだけを呼び出すべきではありません。マウス ポイントとページの左上隅の間の角度のみが計算されるためです。その点と原点の間の角度が必要です。

    var s_rad = Math.atan2(s_y - o_y, s_x - o_x); // current to origin
    

    それはあなたを中途半端に導きますが、それでも奇妙な動作をします (要素の原点を中心に回転しますが、期待どおりにハンドルをたどりません)。ハンドルに追従させるには、クリックしたポイントに関連して角度を調整する必要があります。これは、回転量のベースとして機能します。

    s_rad -= Math.atan2(h_y - o_y, h_x - o_x); // handle to origin
    

    その後、ローテーションが機能します少なくとも1回のユーザー反復に対して)。

ハンドルがマウスに正確に追従していないことに気付くでしょう。その理由は、要素の左上隅にデフォルト設定されている原点の選択にあります。data-要素内のどこかに(おそらく属性を使用して)調整すると、期待どおりに機能するはずです。

ただし、ユーザーがハンドルを複数回操作する場合は、回転角度を設定するだけでは十分ではなく、最後の反復中の値を更新する必要があります。したがってlast_angle、最初のクリックで設定され、ドラッグ中に最終的な角度に追加される var を追加しています。

// on mousedown
last_angle = target_wp.data("last_angle") || 0;

// on mousemove
s_rad += last_angle; // relative to the last one

// on mouseup    
target_wp.data("last_angle", s_rad);

これが最終的な作業例です。(注: マウス ハンドラーのネストを修正したので、クリックするたびに再度追加されません)

$(function () {
    var dragging = false,
        target_wp,
        o_x, o_y, h_x, h_y, last_angle;
    $('.handle').mousedown(function (e) {
        h_x = e.pageX;
        h_y = e.pageY; // clicked point
        e.preventDefault();
        e.stopPropagation();
        dragging = true;
        target_wp = $(e.target).closest('.draggable_wp');
        if (!target_wp.data("origin")) target_wp.data("origin", {
            left: target_wp.offset().left,
            top: target_wp.offset().top
        });
        o_x = target_wp.data("origin").left;
        o_y = target_wp.data("origin").top; // origin point
        
        last_angle = target_wp.data("last_angle") || 0;
    })

    $(document).mousemove(function (e) {
        if (dragging) {
            var s_x = e.pageX,
                s_y = e.pageY; // start rotate point
            if (s_x !== o_x && s_y !== o_y) { //start rotate
                var s_rad = Math.atan2(s_y - o_y, s_x - o_x); // current to origin
                s_rad -= Math.atan2(h_y - o_y, h_x - o_x); // handle to origin
                s_rad += last_angle; // relative to the last one
                var degree = (s_rad * (360 / (2 * Math.PI)));
                target_wp.css('-moz-transform', 'rotate(' + degree + 'deg)');
                target_wp.css('-moz-transform-origin', '50% 50%');
                target_wp.css('-webkit-transform', 'rotate(' + degree + 'deg)');
                target_wp.css('-webkit-transform-origin', '50% 50%');
                target_wp.css('-o-transform', 'rotate(' + degree + 'deg)');
                target_wp.css('-o-transform-origin', '50% 50%');
                target_wp.css('-ms-transform', 'rotate(' + degree + 'deg)');
                target_wp.css('-ms-transform-origin', '50% 50%');
            }
        }
    }) // end mousemove
    
    $(document).mouseup(function (e) {
        dragging = false
        var s_x = e.pageX,
            s_y = e.pageY;
        
        // Saves the last angle for future iterations
        var s_rad = Math.atan2(s_y - o_y, s_x - o_x); // current to origin
        s_rad -= Math.atan2(h_y - o_y, h_x - o_x); // handle to origin
        s_rad += last_angle;
        target_wp.data("last_angle", s_rad);
    })
})
.draggable_wp {
    position: absolute;
    left: 150px;
    top: 150px;
}
.el {
    width: 25px;
    height: 50px;
    background-color: yellow;
}
.handle {
    position: absolute;
    left:0;
    top:-75;
    width: 25px;
    height: 25px;
    background-color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="draggable_wp">
    <div class="el"></div>
    <div class="handle"></div>
</div>

于 2013-02-02T22:57:00.180 に答える
0

変換プロパティで行列関数を使用します。行列 (要素座標) を回転行列で乗算して要素を回転させることができます。

transform:  matrix(a, c, b, d, tx, ty)

詳細と例はこちら: The CSS3 matrix() Transform for the Mathematical Challenged

于 2013-01-30T11:59:16.670 に答える