I have a rectangle that drawn with 4 points. I need to rotate all points an arbitrary degree and find the new x,y
of the points.I try to rotate these but the problem is when I'll increase the degree, rectangle Becomes smaller and when I'll decrease the degree, the first rectangle not drawn again. How can I do this by using 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>
Here is the JavaScript code:
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
};
});
You should use the
rotate
attribute as Lars Kotthoff already mentioned.As you're basically creating a rect I replaced your
path
with asvg:rect
for convenience. The following code does the rotation by rotating theg
element. This way you can crate any number of shapes inside and they will rotate properly.For rotating the
g
element around the center I calculated the center by adding half of the width and height of the element to its x and y position.