Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The best cross-browser way I can think of to do what you want is to implement the rotation yourself rather than let SVG do it. Rotating x,y coordinates is fairly simple and I've been using this (tcl) code whenever I need to do 2D rotation: <a href="http://wiki.tcl.tk/8595" rel="nofollow">Canvas Rotation</a>.</p> <p>The upside to this is you have maximum control of the rotation since you're doing it manually. This solves the problems you're having trying to guess the final coordinates after rotation. Also, this should be cross browser compatible.</p> <p>The downside is you have to use paths. So no rects (though it should be easy to convert them to paths) or ellipses (a little bit harder to convert to path but doable). Also, since you're doing it manually, it should be slower than letting SVG do it for you.</p> <p>Here's a partial implementation of that Tcl code in javascript:</p> <p><em>first we need a regexp to tokenize SVG paths:</em></p> <pre><code>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' ); })(); </code></pre> <p><em>now we can implement the rotate function:</em></p> <pre><code>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&lt;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(''); } </code></pre> <p>The above rotate function implements everything except horizontal/vertical lines (you need to keep track of previous xy value) and arcs. Neither should be too hard to implement.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload