使用Angular旋转4个点的矩形

时间:2015-06-11 21:00:45

标签: javascript angularjs d3.js rotation

我有一个用4点绘制的矩形。我需要将所有点旋转到任意角度并找到新的x,y点。我尝试旋转它们但问题是当我增加度数时,矩形变得更小并且当我减小度数时,第一个矩形没有再绘制。我怎么能通过使用Angular来做到这一点。

<div ng-app="myApp">
    <div  ng-app="myApp" ng-controller="rectController">
         <input type="number" ng-model="Rotation" min="-360" max="360" value="0"/>
         <rect-rotate/>
    </div>
 </div>

以下是JavaScript代码:

var App = angular.module('myApp', []);
var Ctrl = App.controller('rectController', function($scope) { });

Ctrl.directive('rectRotate', function() {

        function link(scope, el, attr) {
            var w = 1200, h = 780;
            var width = 300, height = 200;
            var point1=[300,200],point2=[600,200],point3=[600,400],point4=[300,400];

            var svg = d3.select(el[0]).append("svg")
                .attr("width", w)
                .attr("height", h);
            var newg = svg.append("g").data([{ x: width, y: height }]);

             var rect = newg.append("path")
                .attr("x", function(d) {
                    return d.x;
                })
                .attr("y", function(d) {
                    return d.y;
                })
                .attr("fill-opacity", .5)
                .attr("d", function(d) {

        var dCommand
                    = "M" + point1[0] + "," + point1[1] + "L" + point2[0] 
                    + "," + point2[1] + "L " + point3[0] + "," + point3[1] 
                    + "L " + point4[0] + "," + point4[1] + "Z";
                    return dCommand;
                });
         scope.$watch('Rotation', function (newValues) {
            var rotateAngle = newValues;
            rotateAngle = rotateAngle * Math.PI / 180.0;
            var centerX = (point1[0]+point3[0]) / 2;
            var centerY = (point1[1]+point3[1]) / 2;

 //1
 point1[0] = (Math.cos(rotateAngle) * (point1[0] - centerX)
          -(Math.sin(rotateAngle) * (point1[1] - centerY)) + centerX;
 point1[1] = (Math.sin(rotateAngle) * (point1[0] - centerX)) 
          +(Math.cos(rotateAngle) * (point1[1] - centerY)) + centerY;

//2
point2[0] = (Math.cos(rotateAngle) * (point2[0] - centerX)
          -(Math.sin(rotateAngle) * (point2[1] - centerY)) + centerX;
point2[1] = (Math.sin(rotateAngle) * (point2[0] - centerX)) 
          +(Math.cos(rotateAngle) * (point2[1] - centerY)) + centerY;

//3
point3[0] = (Math.cos(rotateAngle) * (point3[0] - centerX)
          -(Math.sin(rotateAngle) * (point3[1] - centerY)) + centerX;
point3[1] = (Math.sin(rotateAngle) * (point3[0] - centerX)) 
          +(Math.cos(rotateAngle) * (point3[1] - centerY)) + centerY;

//4
point4[0] = (Math.cos(rotateAngle) * (point4[0] - centerX)
          -(Math.sin(rotateAngle) * (point4[1] - centerY)) + centerX;
point2[1] = (Math.sin(rotateAngle) * (point4[0] - centerX)) 
          +(Math.cos(rotateAngle) * (point4[1] - centerY)) + centerY;

 rect.attr("d", function (d) {

        var dCommand
                    = "M" + point1[0] + "," + point1[1] + "L" + point2[0] 
                    + "," + point2[1] + "L " + point3[0] + "," + point3[1] 
                    + "L " + point4[0] + "," + point4[1] + "Z";
                    return dCommand;
                    });
        }return {
            link: link
        };

    });

2 个答案:

答案 0 :(得分:1)

你应该使用rotate属性作为已经提到的Lars Kotthoff。

由于您基本上创建了一个矩形,为方便起见,我将path替换为svg:rect。以下代码通过旋转g元素来完成旋转。通过这种方式,您可以在内部创建任意数量的形状,它们将正确旋转。

为了围绕中心旋转g元素,我通过将元素的宽度和高度的一半加到x和y位置来计算中心。

var App = angular.module('myApp', []);
var Ctrl = App.controller('rectController', function($scope) { });

Ctrl.directive('rectRotate', function() {
  function link(scope, el, attr) {
    var w = 1200, h = 780;
    var width = 300, height = 200, positionX = 300, positionY = 200;

    var svg = d3.select(el[0]).append("svg")
        .attr("width", w)
        .attr("height", h);

    var newg = svg.append("g");

    var rect = newg.append("rect")
        .attr("x", positionX)
        .attr("y", positionY)
        .attr("fill-opacity", .5)
        .attr("width", width)
        .attr("height", height);

    scope.$watch('Rotation', function (newValues) {

      var rotateAngle = newValues || 0;
      newg.attr("transform","rotate(" + rotateAngle + " "+ (positionX + width / 2) +" "+ (positionY + height / 2) +")");
    });
  }
  return {link: link};
});

答案 1 :(得分:0)

旋转点有很多种方法。您可以使用矩阵旋转点。您的点协调矩阵的多个。这是链接,可能会对您有所帮助。

http://www.euclideanspace.com/maths/geometry/affine/aroundPoint/

Rotate point in rectangle