通过前导点拖动 div(就像水中的船)
Posted
技术标签:
【中文标题】通过前导点拖动 div(就像水中的船)【英文标题】:Drag div by leading point (like a boat in water) 【发布时间】:2013-06-18 20:41:11 【问题描述】:我正在尝试让 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;
<div id="board">
<div id="canoe">A</div>
</div>
有没有更好的方法来设置旋转,使船的前部始终领先,即使是 360 度旋转?
其他背景:我正在处理 Basic Game
赏金更新: 我需要“船”能够以一个连续的动作绕一圈拖动,而无需翻转/切换旋转方向。
【问题讨论】:
您可能需要在setTimeout
- jsfiddle.net/unuCD/9 内设置旋转
@Vega 似乎没有做到这一点jsfiddle.net/apaul34208/unuCD/10 ...除非我还缺少更多内容?
【参考方案1】:
你需要:
每次更改时存储position
在变化时,计算所述位置之间的线的角度
最后保存position
http://jsfiddle.net/AstDerek/799Tp/
运动看起来并不柔和,但更接近你想要的。
如果要模拟水阻力,则需要将角度变化减少一些因素,然后在拖动结束后使用一些时间间隔或类似的时间继续移动,直到船的角度与应有的角度匹配有,或者新的拖动事件开始。
【讨论】:
这似乎有点疯狂。有什么办法可以降低灵敏度? 将角度乘以某个值 在this example 我设法减少了一点点波动 一个建议:不要存储最后一个位置,而是存储最后 x 个位置(尝试使用 2、3、4...),然后取这些 + 当前位置的平均值 嗯...有点抑制了小故障,但并不完美jsfiddle.net/799Tp/2【参考方案2】:这有点复杂,但我会这样做:
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
确保它始终是一个正整数。
我在 CSS 中添加了更多浏览器前缀。
【讨论】:
这似乎更接近我所追求的,但执行圆周运动似乎仍然存在问题。 @apaul34208 - 你在使用 Firefox 吗? 试试 Chrome 或 IE,好像 Firefox 有问题!试图弄清楚 FF 中的问题是什么,但它不会按照我说的那样做。 我解决了这个问题,我在#canoe
上设置了transition: transform .2s;
,这使FF 中的工作变得混乱。不幸的是,没有它似乎有点抽搐。你知道有什么其他的方法可以解决问题吗?
稍微增加超时可能会使其更顺畅,但同时会“变慢”一点,看看这是否有帮助 -> jsfiddle.net/unuCD/26以上是关于通过前导点拖动 div(就像水中的船)的主要内容,如果未能解决你的问题,请参考以下文章