Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>To rotate an SVG object on an arbitrary axis, you need two transformations: <code>translate</code> (to set the axis) and <code>rotate</code>. What you really want is to apply the <code>translate</code> fully first and then rotate the already moved element, but it appears that <code>translate</code> and <code>rotate</code> operate independently and simultaneously. This ends at the right place, but animating the <code>translate</code> is essentially moving the axis during rotation, creating the wobble. You can isolate the <code>translate</code> from the <code>rotate</code> by having them occur at separate places in the SVG element hierarchy. For example, take a look at the following:</p> <pre><code>&lt;g class="outer"&gt; &lt;g class="rect-container"&gt; &lt;rect class="rotate-me" width=200 height=100 /&gt; &lt;/g&gt; &lt;/g&gt; </code></pre> <p>You can center the <code>&lt;rect&gt;</code> on (0,0) with <code>translate (-100, -50)</code>. It will wobble if you apply your rotation to the <code>&lt;rect&gt;</code> element, but it will rotate cleanly if you <code>rotate</code> the <code>g.rect-container</code> element. If you want to reposition, scale, or otherwise transform the element further, do so on <code>g.outer</code>. That's it. You now have full control of your transforms.</p> <p>Finding a <code>&lt;rect&gt;</code>'s center is easy, but finding the center of a <code>&lt;path&gt;</code>, <code>&lt;g&gt;</code>, etc. is much harder. Luckily, a simple solution is available in the <a href="http://www.w3.org/Graphics/SVG/IG/resources/svgprimer.html#getBBox" rel="nofollow">.getBBox()</a> method (code in CoffeeScript; see below for a JavaScript version*):</p> <pre><code>centerToOrigin = (el) -&gt; boundingBox = el.getBBox() return { x: -1 * Math.floor(boundingBox.width/2), y: -1 * Math.floor(boundingBox.height/2) } </code></pre> <p>You can now center your element/group by passing the non-wrapped element (using D3's <code>.node()</code> method) </p> <pre><code>group = d3.select("g.rotate-me") center = centerToOrigin(group.node()) group.attr("transform", "translate(#{center.x}, #{center.y})") </code></pre> <p>For code that implements this on a both a single <code>&lt;rect&gt;</code> and <code>&lt;g&gt;</code> of of 2 <code>rect</code>s with repositioning and scaling, <a href="http://jsfiddle.net/rdickert/hQBEw/1/" rel="nofollow">see this fiddle</a>.</p> <hr> <p>*Javascript of the above code:</p> <pre><code>var center, centerToOrigin, group; centerToOrigin = function(el) { var boundingBox; boundingBox = el.getBBox(); return { x: -1 * Math.floor(boundingBox.width / 2), y: -1 * Math.floor(boundingBox.height / 2) }; }; group = d3.select("g.rotate-me"); center = centerToOrigin(group.node()); group.attr("transform", "translate(" + center.x + ", " + center.y + ")"); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

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