通过引导点拖动div(就像在水中的船)

时间:2013-06-21 16:20:07

标签: jquery rotation draggable jquery-ui-draggable game-physics

我试图让一个div像水中的船一样拖动,但是我在旋转方面遇到了一些麻烦。

这是我到目前为止: 的 jsFiddle

JS

var start, stop;
$('#canoe').draggable({
    containment: '#board',
    cursor: 'none',
    cursorAt: {
        top: 5
    },
    drag: function (event, ui) {
        start = ui.position.left;
        setTimeout(function () {
            stop = ui.position.left;
        }, 150);
        $('#canoe').css({
            'transform': 'rotate(' + (start - stop) + 'deg)'
        });
    }
});

CSS

#board {
    height:100%;
    width:100%;
    background:blue;
}
#canoe {
    background: #fff;
    border-radius:100% 100% 100% 100%;
    height:60px;
    width:10px;
    position:absolute;
    left:50%;
    bottom:0;
    transform-origin:top center;
    transition: transform .2s;
}

HTML

<div id="board">
    <div id="canoe">A</div>
</div>

有没有更好的方法来设置旋转,以便船的前部总是领先,即使旋转360度?

其他背景:我正在处理 Basic Game

Bounty更新: 我需要“船”能够在一个连续的运动中被拖动成一个圆圈而不会翻转/切换旋转方向。

2 个答案:

答案 0 :(得分:2)

你需要:

  • 每次更改时存储position
  • 在更改时,计算所述位置之间的直线角度
  • 保存上次position

http://jsfiddle.net/AstDerek/799Tp/

运动看起来并不柔和但更接近你想要的东西。

如果你想模拟水阻力,你需要通过某种因素减小角度变化,然后使用一些时间间隔或类似的时间来拖动结束后继续运动,直到船的角度与它应该的角度相匹配有,或新的拖拽事件开始。

答案 1 :(得分:1)

这有点复杂,但这就是我要做的事情:

var save = false, timer;

$('#canoe').draggable({
    containment: '#board',
    cursor: 'none',
    cursorAt: {
        top: 5
    },
    drag: function (event, ui) {
        if ( !save ) save = ui.offset;
        var canoe    = $('#canoe'),
            center_x = save.left + 5,
            center_y = save.top + 30,
            radians  = Math.atan2(event.pageX - center_x, event.pageY - center_y),
            degree   = (radians * (180 / Math.PI) * -1) + 180,
            time     = Math.abs(ui.offset.top-save.top) + Math.abs(ui.offset.left-save.left);

        canoe.css({
            '-moz-transform'    : 'rotate('+degree+'deg)',
            '-webkit-transform' : 'rotate('+degree+'deg)',
            '-o-transform'      : 'rotate('+degree+'deg)',
            '-ms-transform'     : 'rotate('+degree+'deg)'
        });

        timer = setTimeout(function() {
            clearTimeout(timer);
            save = ui.offset;
        }, Math.abs( time-300 ) + 400 );
    }
});

FIDDLE

它将当前鼠标位置与独木舟中心的位置进行比较 时间根据鼠标的移动速度设置,因为较慢的移动需要较长的超时等。

清除超时以便它们不会累积也是一个好主意,即使在我测试它时它并不是真正的问题,并且Math.abs的使用确保它始终是一个正整数。 / p>

我在CSS中添加了一些浏览器前缀。