Лучший кроссбраузерный способ, который я могу придумать, чтобы сделать то, что вы хотите, - это выполнить ротацию самостоятельно, а не позволить SVG делать это.Поворот координат x, y довольно прост, и я использую этот код (tcl) всякий раз, когда мне нужно сделать двухмерное вращение: Поворот холста .
Преимущество в том, что у вас есть максимумконтроль вращения, так как вы делаете это вручную.Это решает проблемы, с которыми вы пытаетесь угадать окончательные координаты после поворота.Кроме того, это должно быть совместимо с разными браузерами.
Недостатком является то, что вы должны использовать пути.Таким образом, нет никаких rects (хотя должно быть легко преобразовать их в пути) или эллипсы (немного труднее преобразовать в путь, но выполнимо).Кроме того, поскольку вы делаете это вручную, это должно быть медленнее, чем позволить SVG сделать это за вас.
Вот частичная реализация этого кода Tcl в javascript:
сначала мынам нужно регулярное выражение для токенизации путей SVG:
var svg_path_regexp = (function(){
var number = '-?[0-9.]+';
var comma = '\s*[, \t]\s*';
var space = '\s+';
var xy = number + comma + number;
var standard_paths = '[mlcsqt]';
var horiz_vert = '[hv]\s*' + number;
var arc = 'a\s*' + xy + space + number + space + xy + space + xy;
var OR = '\s*|';
return new RegExp(
standard_paths +OR+
xy +OR+
horiz_vert +OR+
arc,
'ig'
);
})();
теперь мы можем реализовать функцию поворота:
function rotate_SVG_path (path, Ox, Oy, angle) {
angle = angle * Math.atan(1) * 4 / 180.0; // degrees to radians
var tokens = path.match(svg_path_regexp);
for (var i=0; i<tokens.length; i++) {
var token = tokens[i].replace(/^\s+|\s+$/g,''); // trim string
if (token.match(/\d/)) { // assume it's a coordinate
var xy = token.split(/[, \t]+/);
var x = parseFloat(xy[0]);
var y = parseFloat(xy[1]);
x = x - Ox; // Shift to origin
y = y - Oy;
var xx = x * Math.cos(angle) - y * Math.sin(angle); // Rotate
var yy = x * Math.sin(angle) + y * Math.cos(angle);
x = xx + Ox; // Shift back
y = yy + Oy;
token = x + ',' + y;
}
else if (token.match(/^[hv]/)) {
// handle horizontal/vertical line here
}
else if (token.match(/^a/)) {
// handle arcs here
}
tokens[i] = token;
}
return tokens.join('');
}
Вышеуказанная функция поворота реализует все, кромегоризонтальные / вертикальные линии (необходимо отслеживать предыдущее значение xy) и дуги.Ни один из них не должен быть слишком сложным для реализации.