使用Jquery UI后,图像无法旋转 - 可调整大小且可通过UI旋转

时间:2016-07-01 11:17:18

标签: jquery jquery-ui rotation resize drag

我有一个使用手柄按预期旋转的图像,就像在这个link..中一样。当我尝试使用可拖动和可调整大小的Jquery UI拖动,删除和调整同一图像的大小时,我无法像link..中那样实现旋转图像。请不要指定我使用旋转Jquery UI,使用JQuery UI旋转后调整大小功能不起作用。请帮助我做好这件事......在此先感谢..

$('#image_box').draggable().resizable({
        handles: 'ne, nw, se, sw' 
});

1 个答案:

答案 0 :(得分:1)

暂时发布此答案可能会在我解决“错误”之后再次更新,但这确实可以满足您的要求。

当前工作示例:https://jsfiddle.net/Twisty/npmtfLt6/22/

<强> HTML

<div id="box_wrapper">
  <div id="rotate_limit"></div>
  <div id="rotate_handle"></div>
  <div id="image_box"></div>
</div>


dial.offset().left: <span id="left"></span>
<br> dial.offset().top: <span id="top"></span>
<br> dial.centerX: <span id="centerX"></span>
<br> dial.centerY: <span id="centerY"></span>
<br> pageX: <span id="pageX"></span>
<br> pageY: <span id="pageY"></span>
<br> offset: <span id="offset"></span>
<br> newOffset: <span id="newOffset"></span>
<br> RAD2DEG: <span id="RAD2DEG"></span>
<br> r: <span id="r"></span>
<br>

首先,我们必须将手柄分开,以便我们可以自由移动。我们还需要在包装器中包含它。我现在已经添加了#canvas,但正如我在评论中提到的,我认为没有这个元素就可以完成。

<强> CSS

#box_wrapper {
  position: relative;
  margin-left: 180px;
  margin-top: 100px;
  width: 180px;
  height: 180px;
}

#image_box {
  background: url('https://placehold.it/80x80/c9112d/fff&text=Image');
  background-size: 100% 100%;
  position: absolute;
  top: 40px;
  left: 40px;
  width: 100px;
  height: 100px;
  border: 4px solid white;
  -webkit-transform: rotate(0deg);
  transform: rotate(0deg);
}

#image_box:hover {
  border: 4px solid black;
}

#rotate_limit {
  background: transparent;
  position: absolute;
  height: 180px;
  width: 180px;
  top: 0;
  left: 0;
  -webkit-border-radius: 180px;
  -moz-border-radius: 180px;
  border-radius: 180px;
  border: dashed #ccc 1px;
  z-index: -1;
}

#rotate_handle {
  background: url('https://s32.postimg.org/re2hwf3fp/rotate_handle_down.png') no-repeat;
  position: absolute;
  background-size: 100% 100%;
  left: 18px;
  top: 18px;
  width: 20px;
  height: 20px;
}

.ui-resizable-handle {
  border: 3px solid greenyellow;
  cursor: pointer;
}

此处对新元素进行了细微更改,以及我们如何将它们放置在包装器中。

<强>的jQuery

var RAD2DEG = 180 / Math.PI;

var dial = $("#image_box");
var pointerEl = $("#rotate_handle")[0];
var canvasEl = $("#rotate_limit")[0];
var canvas = {
  width: canvasEl.offsetWidth,
  height: canvasEl.offsetHeight,
  top: canvasEl.offsetTop,
  left: canvasEl.offsetLeft
};

canvas.center = [canvas.left + canvas.width / 2, canvas.top + canvas.height / 2];
canvas.radius = canvas.width / 2;

pointerEl.ondragstart = function() {
  return false;
};

function limit(x, y) {
  x = x - canvas.center[0];
  y = y - canvas.center[1];
  var radians = Math.atan2(y, x);
  return {
    x: Math.cos(radians) * canvas.radius + canvas.center[0],
    y: Math.sin(radians) * canvas.radius + canvas.center[1]
  };
}

$('#left').text(dial.offset().left);
$('#top').text(dial.offset().top);
dial.centerX = dial.offset().left + dial.width() / 2;
dial.centerY = dial.offset().top + dial.height() / 2;
$('#centerX').text(dial.centerX);
$('#centerY').text(dial.centerY);

var offset, rotate = false;

pointerEl.onmousedown = function(e) {
  rotate = true;
  offset = Math.atan2(dial.centerY - e.pageY, e.pageX - dial.centerX);
  $('#pageX').text(e.pageX);
  $('#pageY').text(e.pageY);
  $('#offset').text(offset);
};

$(document).mouseup(function() {
  rotate = false;
});

$(document).mousemove(function(e) {
  if (rotate) {
    var newOffset = Math.atan2(dial.centerY - e.pageY, e.pageX - dial.centerX);
    $('#newOffset').text(newOffset);
    var r = (offset - newOffset) * RAD2DEG;
    $('#RAD2DEG').text(RAD2DEG);
    $('#r').text(r);
    dial.css('-webkit-transform', 'rotate(' + r + 'deg)');
    dial.css('transform', 'rotate(' + r + 'deg)');

    var result = limit(e.pageX, e.pageY);
    pointerEl.style.left = result.x + "px";
    pointerEl.style.top = result.y + "px";
  }
});

dial.resizable({
  handles: 'ne, nw, se, sw'
});

$("#box_wrapper").draggable({
  handle: dial
});

由于数学运算,您的个人代码没有太多变化。只是一些组织变化。由于您要拖动所有这些,我们使包装器可拖动,但将句柄设置为#image_box。这允许我们在抓住它时移动盒子,但让旋转手柄可以独立移动。这样我们就可以在不拖动整个元素的情况下进行旋转。

移动旋转手柄时,它(主要是)受约束,然后pageXpageY用于计算变换。

旋转手柄的定位不如旋转本身那么平滑。您可能对此有一些了解,但这确实实现了您目前所需的功能。如果您愿意,我们可以努力改进它。

另见:

<强>更新

更正了“错误”。工作示例:https://jsfiddle.net/Twisty/npmtfLt6/28/

  1. 针对此特定用例改进了calcDeg()
  2. function calcDeg(e){
       // Retrieve degree from current handle position vs. circle center
       var mPos = {
         x : e.x - canvas.center[0],
         y : e.y - canvas.center[1]
       }; 
       var getAtan = Math.atan2(mPos.y, mPos.x);    
       return getAtan*180/Math.PI;
    }
    1. CSS的圆度值:
    2. var r = calcDeg(result);
      $('#r').text(Math.round(r));
      dial.css({
         '-webkit-transform': 'rotate(' + Math.round(r) + 'deg)',
         'transform': 'rotate(' + Math.round(r) + 'deg)'
      });
      1. 调整指针样式和位置更加动态:
      2. #rotate_handle {
          background: url('https://s32.postimg.org/re2hwf3fp/rotate_handle_down.png') no-repeat;
          position: absolute;
          background-size: 100% 100%;
          left: 100%;
          top: 50%;
          margin-top: -10px;
          margin-left: -10px;
          width: 20px;
          height: 20px;
        }
        1. 调整大小调整,以便使用图像调整限制和包装:
        2. dial.resizable({
              handles: 'ne, nw, se, sw',
              alsoResize: "#box_wrapper, #rotate_limit"
          });

          调整大小有效,但我建议设置aspectRatio: true。这将使图像保持正方形,这允许限制器变为椭圆形或变成椭圆形。

          这可能无法满足您的需求,因此您可能需要考虑编写一个在resize期间执行的功能,该功能可能会增加widthheight和{{1}正确的包装器和限制器。

          我希望这完全回答你的问题。