8

我试图让一个 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 度旋转?

附加背景:我正在开发一个基本游戏

赏金更新: 我需要“船”能够以一个连续的动作在一个圆圈中拖动,而无需翻转/切换旋转方向。

4

2 回答 2

2

你需要:

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

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

运动看起来并不柔软,但更接近你想要的。

如果要模拟水阻力,则需要将角度变化减少一些因素,然后在拖动结束后使用一些时间间隔或类似的时间继续移动,直到船的角度与应有的角度相匹配,或者一个新的拖动事件开始。

于 2013-06-21T16:56:30.910 回答
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 );
    }
});

小提琴

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

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

我在 CSS 中添加了更多浏览器前缀。

于 2013-06-26T12:30:40.680 回答