Add rotate shape operation (addresses #838)

This commit is contained in:
Ian B
2013-02-23 12:34:43 +01:00
parent 5e3eb4d247
commit 9f5564508f
5 changed files with 149 additions and 0 deletions
+3
View File
@@ -108,6 +108,7 @@
<script src='js/id/actions/merge.js'></script>
<script src='js/id/actions/move_node.js'></script>
<script src='js/id/actions/move_way.js'></script>
<script src='js/id/actions/rotate_way.js'></script>
<script src='js/id/actions/circularize.js'></script>
<script src='js/id/actions/orthogonalize.js'></script>
<script src='js/id/actions/noop.js'></script>
@@ -133,6 +134,7 @@
<script src='js/id/modes/draw_area.js'></script>
<script src='js/id/modes/draw_line.js'></script>
<script src='js/id/modes/move.js'></script>
<script src='js/id/modes/rotate_way.js'></script>
<script src='js/id/modes/select.js'></script>
<script src='js/id/operations.js'></script>
@@ -142,6 +144,7 @@
<script src='js/id/operations/disconnect.js'></script>
<script src='js/id/operations/merge.js'></script>
<script src='js/id/operations/move.js'></script>
<script src='js/id/operations/rotate.js'></script>
<script src='js/id/operations/reverse.js'></script>
<script src='js/id/operations/split.js'></script>
+39
View File
@@ -0,0 +1,39 @@
iD.actions.RotateWay = function(wayId, ref_points, pivot, mousePoint, projection) {
return function(graph) {
return graph.update(function(graph) {
var way = graph.entity(wayId),
nodes = _.uniq(graph.childNodes(way)),
angle, i, points;
points = deepCopy(ref_points);
angle = Math.atan2(mousePoint[1] - pivot[1], mousePoint[0] - pivot[0]);
for (i = 0; i < points.length; i++) {
var radial = [0,0];
radial[0] = points[i][0] - pivot[0];
radial[1] = points[i][1] - pivot[1];
points[i][0] = radial[0] * Math.cos(angle) - radial[1] * Math.sin(angle) + pivot[0];
points[i][1] = radial[0] * Math.sin(angle) + radial[1] * Math.cos(angle) + pivot[1];
}
for (i = 0; i < points.length; i++) {
graph = graph.replace(graph.entity(nodes[i].id).move(projection.invert(points[i])));
}
function deepCopy(o) {
var copy = o,k;
if (o && typeof o === 'object') {
copy = Object.prototype.toString.call(o) === '[object Array]' ? [] : {};
for (k in o) {
copy[k] = deepCopy(o[k]);
}
}
return copy;
}
});
};
};
+74
View File
@@ -0,0 +1,74 @@
iD.modes.RotateWay = function(context, wayId) {
var mode = {
id: 'rotate-way',
button: 'browse'
};
var keybinding = d3.keybinding('rotate-way');
mode.enter = function() {
var annotation = t('operations.rotate.annotation.' + context.geometry(wayId)),
way = context.graph().entity(wayId),
nodes = _.uniq(context.graph().childNodes(way)),
ref_points = nodes.map(function(n) { return context.projection(n.loc); }),
pivot = d3.geom.polygon(ref_points).centroid();
context.perform(
iD.actions.Noop(),
annotation);
function point() {
return d3.mouse(context.map().surface.node());
}
function rotate() {
var mousePoint = point();
context.replace(
iD.actions.RotateWay(wayId, ref_points, pivot, mousePoint, context.projection),
annotation);
}
function finish() {
d3.event.stopPropagation();
context.enter(iD.modes.Select(context, [wayId], true));
}
function cancel() {
context.pop();
context.enter(iD.modes.Select(context, [wayId], true));
}
function undone() {
context.enter(iD.modes.Browse(context));
}
context.surface()
.on('mousemove.rotate-way', rotate)
.on('click.rotate-way', finish);
context.history()
.on('undone.rotate-way', undone);
keybinding
.on('⎋', cancel)
.on('↩', finish);
d3.select(document)
.call(keybinding);
};
mode.exit = function() {
context.surface()
.on('mousemove.rotate-way', null)
.on('click.rotate-way', null);
context.history()
.on('undone.rotate-way', null);
keybinding.off();
};
return mode;
};
+24
View File
@@ -0,0 +1,24 @@
iD.operations.Rotate = function(selection, context) {
var entityId = selection[0];
var operation = function() {
context.enter(iD.modes.RotateWay(context, entityId));
};
operation.available = function() {
return selection.length === 1 &&
context.entity(entityId).type === 'way' &&
context.entity(entityId).isClosed();
};
operation.enabled = function() {
return true;
};
operation.id = "rotate";
operation.key = t('operations.rotate.key');
operation.title = t('operations.rotate.title');
operation.description = t('operations.rotate.description');
return operation;
};
+9
View File
@@ -115,6 +115,15 @@ locale.en = {
multiple: "Moved multiple objects"
}
},
rotate: {
title: "Rotate",
description: "Rotate this object around its centre point.",
key: "R",
annotation: {
line: "Rotated a line.",
area: "Rotated an area."
}
},
reverse: {
title: "Reverse",
description: "Make this line go in the opposite direction.",