如何使用拖动使对象旋转,如何在原点周围获得旋转点使用sin或cos?

我一直在寻找很长时间,但找不到更好的方法来解决我的问题,
使div可拖动,旋转和调整每个手柄像这样的例子1 2 ,现在它可以拖动,但旋转..

关于Prasanth KC , Chango , Yi 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

 

您的方法存在两个问题:

  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 

    最后,原点应该是固定的(即不应在旋转之间改变)。 这样做的一种方法是将其保留为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 

    更新:原点的一个很好的候选者是CSS属性transform-origin (如果存在) – 它应该确保鼠标尽可能地跟随句柄。 然而,这是一个实验性特征,因此实际结果可能会有所不同。 PS我不确定将它设置为50% 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 

    之后,您将获得旋转工作 (至少一次用户迭代)。

您会注意到手柄没有精确跟随鼠标,原因是原点的选择 – 默认为元素的上/左角。 将其调整到元素内部的某个位置(可能使用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; } 
  

它们在变换属性中使用矩阵函数。 您可以通过旋转矩阵muliplay您的矩阵(元素坐标)来旋转元素。

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

更多信息和示例: CSS3矩阵()转换为数学挑战