how to obtain a complete clockwise rotation in D3












1















I want a square to complete a full clockwise rotation on itself, after a pause on the half of the rotation.
The following code makes it doing an half rotation clockwise, and the other half counter-clockwise, contrary to what I expect.






var svg = d3.select('svg');

var s = svg.append("rect")
.attr("width", 50)
.attr("height", 50)
.attr("x", -25)
.attr("y", -25)
.attr("fill", "red")
.attr("transform", "translate(100,100)");

s
.transition()
.duration(1000)
.attr("transform", "translate(100,100) rotate(180)")
.transition()
.delay(1000)
.duration(1000)
.attr("transform", "translate(100,100) rotate(360)");

* {
margin: 0;
padding: 0;
border: 0;
}

body {
background: #ffd;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>





I can hack such a code splitting the second half rotation in two quarter clockwise rotations, but I wish to know if there is a more elegant solution.










share|improve this question





























    1















    I want a square to complete a full clockwise rotation on itself, after a pause on the half of the rotation.
    The following code makes it doing an half rotation clockwise, and the other half counter-clockwise, contrary to what I expect.






    var svg = d3.select('svg');

    var s = svg.append("rect")
    .attr("width", 50)
    .attr("height", 50)
    .attr("x", -25)
    .attr("y", -25)
    .attr("fill", "red")
    .attr("transform", "translate(100,100)");

    s
    .transition()
    .duration(1000)
    .attr("transform", "translate(100,100) rotate(180)")
    .transition()
    .delay(1000)
    .duration(1000)
    .attr("transform", "translate(100,100) rotate(360)");

    * {
    margin: 0;
    padding: 0;
    border: 0;
    }

    body {
    background: #ffd;
    }

    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
    <svg></svg>





    I can hack such a code splitting the second half rotation in two quarter clockwise rotations, but I wish to know if there is a more elegant solution.










    share|improve this question



























      1












      1








      1








      I want a square to complete a full clockwise rotation on itself, after a pause on the half of the rotation.
      The following code makes it doing an half rotation clockwise, and the other half counter-clockwise, contrary to what I expect.






      var svg = d3.select('svg');

      var s = svg.append("rect")
      .attr("width", 50)
      .attr("height", 50)
      .attr("x", -25)
      .attr("y", -25)
      .attr("fill", "red")
      .attr("transform", "translate(100,100)");

      s
      .transition()
      .duration(1000)
      .attr("transform", "translate(100,100) rotate(180)")
      .transition()
      .delay(1000)
      .duration(1000)
      .attr("transform", "translate(100,100) rotate(360)");

      * {
      margin: 0;
      padding: 0;
      border: 0;
      }

      body {
      background: #ffd;
      }

      <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
      <svg></svg>





      I can hack such a code splitting the second half rotation in two quarter clockwise rotations, but I wish to know if there is a more elegant solution.










      share|improve this question
















      I want a square to complete a full clockwise rotation on itself, after a pause on the half of the rotation.
      The following code makes it doing an half rotation clockwise, and the other half counter-clockwise, contrary to what I expect.






      var svg = d3.select('svg');

      var s = svg.append("rect")
      .attr("width", 50)
      .attr("height", 50)
      .attr("x", -25)
      .attr("y", -25)
      .attr("fill", "red")
      .attr("transform", "translate(100,100)");

      s
      .transition()
      .duration(1000)
      .attr("transform", "translate(100,100) rotate(180)")
      .transition()
      .delay(1000)
      .duration(1000)
      .attr("transform", "translate(100,100) rotate(360)");

      * {
      margin: 0;
      padding: 0;
      border: 0;
      }

      body {
      background: #ffd;
      }

      <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
      <svg></svg>





      I can hack such a code splitting the second half rotation in two quarter clockwise rotations, but I wish to know if there is a more elegant solution.






      var svg = d3.select('svg');

      var s = svg.append("rect")
      .attr("width", 50)
      .attr("height", 50)
      .attr("x", -25)
      .attr("y", -25)
      .attr("fill", "red")
      .attr("transform", "translate(100,100)");

      s
      .transition()
      .duration(1000)
      .attr("transform", "translate(100,100) rotate(180)")
      .transition()
      .delay(1000)
      .duration(1000)
      .attr("transform", "translate(100,100) rotate(360)");

      * {
      margin: 0;
      padding: 0;
      border: 0;
      }

      body {
      background: #ffd;
      }

      <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
      <svg></svg>





      var svg = d3.select('svg');

      var s = svg.append("rect")
      .attr("width", 50)
      .attr("height", 50)
      .attr("x", -25)
      .attr("y", -25)
      .attr("fill", "red")
      .attr("transform", "translate(100,100)");

      s
      .transition()
      .duration(1000)
      .attr("transform", "translate(100,100) rotate(180)")
      .transition()
      .delay(1000)
      .duration(1000)
      .attr("transform", "translate(100,100) rotate(360)");

      * {
      margin: 0;
      padding: 0;
      border: 0;
      }

      body {
      background: #ffd;
      }

      <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
      <svg></svg>






      javascript d3.js svg rotation transition






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 3 at 20:02









      RyanZim

      3,2181531




      3,2181531










      asked Jan 1 at 19:47









      tictic

      1,254112858




      1,254112858
























          2 Answers
          2






          active

          oldest

          votes


















          0














          If I use D3v3 it does not rotate to 180 degrees, if I switch to D3v4 it rotates to 180.



          You can interpolate to 359.99. It does not follow the string interpolator from the docs, because you also get scale() in the transform.



          translate(100, 100) rotate(359.989990234375) scale(0.999,0.999)


          This does not happen if you write your own interpolator.






          var svg = d3.select('svg');

          var s=svg.append("rect")
          .attr("width",50)
          .attr("height",50)
          .attr("x",-25)
          .attr("y",-25)
          .attr("fill","red")
          .attr("transform","translate(100,100) rotate(0)");

          s
          .transition()
          .duration(3000)
          .ease(d3.easeLinear)
          .attr("transform","translate(100,100) rotate(180)")
          .transition()
          .delay(2000)
          .duration(3000)
          .ease(d3.easeLinear)
          .attrTween("transform", () => d3.interpolate("translate(100,100) rotate(180)", "translate(100,100) rotate(360)") );

          <script src="https://d3js.org/d3.v5.min.js"></script>

          <svg></svg>








          share|improve this answer































            3














            The culprit here is D3 itself, not any SVG spec.



            The problem is that your transition uses d3.interpolateTransform, as we can see here:



            var fullname = namespace(name), i = fullname === "transform" ? interpolateTransform : interpolate;


            This is v4 source code, not v3, but the principle is the same, as you can see in the actual v3 code:



            var interpolate = nameNS == "transform" ? d3_interpolateTransform : d3_interpolate, name = d3.ns.qualify(nameNS);


            Then, if we look in the source code for interpolateTransform (again, v4, but v3 is almost the same), we'll see that it uses a function called parseSvg that calculates the matrix for the new transform:



            function parseSvg(value) {
            if (value == null) return identity;
            if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g");
            svgNode.setAttribute("transform", value);
            if (!(value = svgNode.transform.baseVal.consolidate())) return identity;
            value = value.matrix;
            return decompose(value.a, value.b, value.c, value.d, value.e, value.f);
            }


            That function is generating 0 as the final value in the matrix when you pass rotate(360) to it (the actual value is -2.4492935982947064e-16, which is practically zero).



            Solution



            There are several possible solutions here, the easiest one is using interpolateString instead of interpolateTransform.



            Also, since your code uses D3 v3, you can take advantage of d3.transform(), which was removed in v4/v5:



            d3.interpolateString(d3.transform(d3.select(this).attr("transform")), "translate(100,100) rotate(360)")


            Here is your code with that change:






            var svg = d3.select('svg');

            var s = svg.append("rect")
            .attr("width", 50)
            .attr("height", 50)
            .attr("x", -25)
            .attr("y", -25)
            .attr("fill", "red")
            .attr("transform", "translate(100,100)");

            s.transition()
            .duration(1000)
            .attr("transform", "translate(100,100) rotate(180)")
            .transition()
            .delay(1000)
            .duration(1000)
            .attrTween("transform", function() {
            return d3.interpolateString(d3.transform(d3.select(this).attr("transform")), "translate(100,100) rotate(360)")
            });

            <svg></svg>
            <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>








            share|improve this answer

























              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53998448%2fhow-to-obtain-a-complete-clockwise-rotation-in-d3%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              0














              If I use D3v3 it does not rotate to 180 degrees, if I switch to D3v4 it rotates to 180.



              You can interpolate to 359.99. It does not follow the string interpolator from the docs, because you also get scale() in the transform.



              translate(100, 100) rotate(359.989990234375) scale(0.999,0.999)


              This does not happen if you write your own interpolator.






              var svg = d3.select('svg');

              var s=svg.append("rect")
              .attr("width",50)
              .attr("height",50)
              .attr("x",-25)
              .attr("y",-25)
              .attr("fill","red")
              .attr("transform","translate(100,100) rotate(0)");

              s
              .transition()
              .duration(3000)
              .ease(d3.easeLinear)
              .attr("transform","translate(100,100) rotate(180)")
              .transition()
              .delay(2000)
              .duration(3000)
              .ease(d3.easeLinear)
              .attrTween("transform", () => d3.interpolate("translate(100,100) rotate(180)", "translate(100,100) rotate(360)") );

              <script src="https://d3js.org/d3.v5.min.js"></script>

              <svg></svg>








              share|improve this answer




























                0














                If I use D3v3 it does not rotate to 180 degrees, if I switch to D3v4 it rotates to 180.



                You can interpolate to 359.99. It does not follow the string interpolator from the docs, because you also get scale() in the transform.



                translate(100, 100) rotate(359.989990234375) scale(0.999,0.999)


                This does not happen if you write your own interpolator.






                var svg = d3.select('svg');

                var s=svg.append("rect")
                .attr("width",50)
                .attr("height",50)
                .attr("x",-25)
                .attr("y",-25)
                .attr("fill","red")
                .attr("transform","translate(100,100) rotate(0)");

                s
                .transition()
                .duration(3000)
                .ease(d3.easeLinear)
                .attr("transform","translate(100,100) rotate(180)")
                .transition()
                .delay(2000)
                .duration(3000)
                .ease(d3.easeLinear)
                .attrTween("transform", () => d3.interpolate("translate(100,100) rotate(180)", "translate(100,100) rotate(360)") );

                <script src="https://d3js.org/d3.v5.min.js"></script>

                <svg></svg>








                share|improve this answer


























                  0












                  0








                  0







                  If I use D3v3 it does not rotate to 180 degrees, if I switch to D3v4 it rotates to 180.



                  You can interpolate to 359.99. It does not follow the string interpolator from the docs, because you also get scale() in the transform.



                  translate(100, 100) rotate(359.989990234375) scale(0.999,0.999)


                  This does not happen if you write your own interpolator.






                  var svg = d3.select('svg');

                  var s=svg.append("rect")
                  .attr("width",50)
                  .attr("height",50)
                  .attr("x",-25)
                  .attr("y",-25)
                  .attr("fill","red")
                  .attr("transform","translate(100,100) rotate(0)");

                  s
                  .transition()
                  .duration(3000)
                  .ease(d3.easeLinear)
                  .attr("transform","translate(100,100) rotate(180)")
                  .transition()
                  .delay(2000)
                  .duration(3000)
                  .ease(d3.easeLinear)
                  .attrTween("transform", () => d3.interpolate("translate(100,100) rotate(180)", "translate(100,100) rotate(360)") );

                  <script src="https://d3js.org/d3.v5.min.js"></script>

                  <svg></svg>








                  share|improve this answer













                  If I use D3v3 it does not rotate to 180 degrees, if I switch to D3v4 it rotates to 180.



                  You can interpolate to 359.99. It does not follow the string interpolator from the docs, because you also get scale() in the transform.



                  translate(100, 100) rotate(359.989990234375) scale(0.999,0.999)


                  This does not happen if you write your own interpolator.






                  var svg = d3.select('svg');

                  var s=svg.append("rect")
                  .attr("width",50)
                  .attr("height",50)
                  .attr("x",-25)
                  .attr("y",-25)
                  .attr("fill","red")
                  .attr("transform","translate(100,100) rotate(0)");

                  s
                  .transition()
                  .duration(3000)
                  .ease(d3.easeLinear)
                  .attr("transform","translate(100,100) rotate(180)")
                  .transition()
                  .delay(2000)
                  .duration(3000)
                  .ease(d3.easeLinear)
                  .attrTween("transform", () => d3.interpolate("translate(100,100) rotate(180)", "translate(100,100) rotate(360)") );

                  <script src="https://d3js.org/d3.v5.min.js"></script>

                  <svg></svg>








                  var svg = d3.select('svg');

                  var s=svg.append("rect")
                  .attr("width",50)
                  .attr("height",50)
                  .attr("x",-25)
                  .attr("y",-25)
                  .attr("fill","red")
                  .attr("transform","translate(100,100) rotate(0)");

                  s
                  .transition()
                  .duration(3000)
                  .ease(d3.easeLinear)
                  .attr("transform","translate(100,100) rotate(180)")
                  .transition()
                  .delay(2000)
                  .duration(3000)
                  .ease(d3.easeLinear)
                  .attrTween("transform", () => d3.interpolate("translate(100,100) rotate(180)", "translate(100,100) rotate(360)") );

                  <script src="https://d3js.org/d3.v5.min.js"></script>

                  <svg></svg>





                  var svg = d3.select('svg');

                  var s=svg.append("rect")
                  .attr("width",50)
                  .attr("height",50)
                  .attr("x",-25)
                  .attr("y",-25)
                  .attr("fill","red")
                  .attr("transform","translate(100,100) rotate(0)");

                  s
                  .transition()
                  .duration(3000)
                  .ease(d3.easeLinear)
                  .attr("transform","translate(100,100) rotate(180)")
                  .transition()
                  .delay(2000)
                  .duration(3000)
                  .ease(d3.easeLinear)
                  .attrTween("transform", () => d3.interpolate("translate(100,100) rotate(180)", "translate(100,100) rotate(360)") );

                  <script src="https://d3js.org/d3.v5.min.js"></script>

                  <svg></svg>






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jan 2 at 1:47









                  rioV8rioV8

                  4,5742312




                  4,5742312

























                      3














                      The culprit here is D3 itself, not any SVG spec.



                      The problem is that your transition uses d3.interpolateTransform, as we can see here:



                      var fullname = namespace(name), i = fullname === "transform" ? interpolateTransform : interpolate;


                      This is v4 source code, not v3, but the principle is the same, as you can see in the actual v3 code:



                      var interpolate = nameNS == "transform" ? d3_interpolateTransform : d3_interpolate, name = d3.ns.qualify(nameNS);


                      Then, if we look in the source code for interpolateTransform (again, v4, but v3 is almost the same), we'll see that it uses a function called parseSvg that calculates the matrix for the new transform:



                      function parseSvg(value) {
                      if (value == null) return identity;
                      if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g");
                      svgNode.setAttribute("transform", value);
                      if (!(value = svgNode.transform.baseVal.consolidate())) return identity;
                      value = value.matrix;
                      return decompose(value.a, value.b, value.c, value.d, value.e, value.f);
                      }


                      That function is generating 0 as the final value in the matrix when you pass rotate(360) to it (the actual value is -2.4492935982947064e-16, which is practically zero).



                      Solution



                      There are several possible solutions here, the easiest one is using interpolateString instead of interpolateTransform.



                      Also, since your code uses D3 v3, you can take advantage of d3.transform(), which was removed in v4/v5:



                      d3.interpolateString(d3.transform(d3.select(this).attr("transform")), "translate(100,100) rotate(360)")


                      Here is your code with that change:






                      var svg = d3.select('svg');

                      var s = svg.append("rect")
                      .attr("width", 50)
                      .attr("height", 50)
                      .attr("x", -25)
                      .attr("y", -25)
                      .attr("fill", "red")
                      .attr("transform", "translate(100,100)");

                      s.transition()
                      .duration(1000)
                      .attr("transform", "translate(100,100) rotate(180)")
                      .transition()
                      .delay(1000)
                      .duration(1000)
                      .attrTween("transform", function() {
                      return d3.interpolateString(d3.transform(d3.select(this).attr("transform")), "translate(100,100) rotate(360)")
                      });

                      <svg></svg>
                      <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>








                      share|improve this answer






























                        3














                        The culprit here is D3 itself, not any SVG spec.



                        The problem is that your transition uses d3.interpolateTransform, as we can see here:



                        var fullname = namespace(name), i = fullname === "transform" ? interpolateTransform : interpolate;


                        This is v4 source code, not v3, but the principle is the same, as you can see in the actual v3 code:



                        var interpolate = nameNS == "transform" ? d3_interpolateTransform : d3_interpolate, name = d3.ns.qualify(nameNS);


                        Then, if we look in the source code for interpolateTransform (again, v4, but v3 is almost the same), we'll see that it uses a function called parseSvg that calculates the matrix for the new transform:



                        function parseSvg(value) {
                        if (value == null) return identity;
                        if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g");
                        svgNode.setAttribute("transform", value);
                        if (!(value = svgNode.transform.baseVal.consolidate())) return identity;
                        value = value.matrix;
                        return decompose(value.a, value.b, value.c, value.d, value.e, value.f);
                        }


                        That function is generating 0 as the final value in the matrix when you pass rotate(360) to it (the actual value is -2.4492935982947064e-16, which is practically zero).



                        Solution



                        There are several possible solutions here, the easiest one is using interpolateString instead of interpolateTransform.



                        Also, since your code uses D3 v3, you can take advantage of d3.transform(), which was removed in v4/v5:



                        d3.interpolateString(d3.transform(d3.select(this).attr("transform")), "translate(100,100) rotate(360)")


                        Here is your code with that change:






                        var svg = d3.select('svg');

                        var s = svg.append("rect")
                        .attr("width", 50)
                        .attr("height", 50)
                        .attr("x", -25)
                        .attr("y", -25)
                        .attr("fill", "red")
                        .attr("transform", "translate(100,100)");

                        s.transition()
                        .duration(1000)
                        .attr("transform", "translate(100,100) rotate(180)")
                        .transition()
                        .delay(1000)
                        .duration(1000)
                        .attrTween("transform", function() {
                        return d3.interpolateString(d3.transform(d3.select(this).attr("transform")), "translate(100,100) rotate(360)")
                        });

                        <svg></svg>
                        <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>








                        share|improve this answer




























                          3












                          3








                          3







                          The culprit here is D3 itself, not any SVG spec.



                          The problem is that your transition uses d3.interpolateTransform, as we can see here:



                          var fullname = namespace(name), i = fullname === "transform" ? interpolateTransform : interpolate;


                          This is v4 source code, not v3, but the principle is the same, as you can see in the actual v3 code:



                          var interpolate = nameNS == "transform" ? d3_interpolateTransform : d3_interpolate, name = d3.ns.qualify(nameNS);


                          Then, if we look in the source code for interpolateTransform (again, v4, but v3 is almost the same), we'll see that it uses a function called parseSvg that calculates the matrix for the new transform:



                          function parseSvg(value) {
                          if (value == null) return identity;
                          if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g");
                          svgNode.setAttribute("transform", value);
                          if (!(value = svgNode.transform.baseVal.consolidate())) return identity;
                          value = value.matrix;
                          return decompose(value.a, value.b, value.c, value.d, value.e, value.f);
                          }


                          That function is generating 0 as the final value in the matrix when you pass rotate(360) to it (the actual value is -2.4492935982947064e-16, which is practically zero).



                          Solution



                          There are several possible solutions here, the easiest one is using interpolateString instead of interpolateTransform.



                          Also, since your code uses D3 v3, you can take advantage of d3.transform(), which was removed in v4/v5:



                          d3.interpolateString(d3.transform(d3.select(this).attr("transform")), "translate(100,100) rotate(360)")


                          Here is your code with that change:






                          var svg = d3.select('svg');

                          var s = svg.append("rect")
                          .attr("width", 50)
                          .attr("height", 50)
                          .attr("x", -25)
                          .attr("y", -25)
                          .attr("fill", "red")
                          .attr("transform", "translate(100,100)");

                          s.transition()
                          .duration(1000)
                          .attr("transform", "translate(100,100) rotate(180)")
                          .transition()
                          .delay(1000)
                          .duration(1000)
                          .attrTween("transform", function() {
                          return d3.interpolateString(d3.transform(d3.select(this).attr("transform")), "translate(100,100) rotate(360)")
                          });

                          <svg></svg>
                          <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>








                          share|improve this answer















                          The culprit here is D3 itself, not any SVG spec.



                          The problem is that your transition uses d3.interpolateTransform, as we can see here:



                          var fullname = namespace(name), i = fullname === "transform" ? interpolateTransform : interpolate;


                          This is v4 source code, not v3, but the principle is the same, as you can see in the actual v3 code:



                          var interpolate = nameNS == "transform" ? d3_interpolateTransform : d3_interpolate, name = d3.ns.qualify(nameNS);


                          Then, if we look in the source code for interpolateTransform (again, v4, but v3 is almost the same), we'll see that it uses a function called parseSvg that calculates the matrix for the new transform:



                          function parseSvg(value) {
                          if (value == null) return identity;
                          if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g");
                          svgNode.setAttribute("transform", value);
                          if (!(value = svgNode.transform.baseVal.consolidate())) return identity;
                          value = value.matrix;
                          return decompose(value.a, value.b, value.c, value.d, value.e, value.f);
                          }


                          That function is generating 0 as the final value in the matrix when you pass rotate(360) to it (the actual value is -2.4492935982947064e-16, which is practically zero).



                          Solution



                          There are several possible solutions here, the easiest one is using interpolateString instead of interpolateTransform.



                          Also, since your code uses D3 v3, you can take advantage of d3.transform(), which was removed in v4/v5:



                          d3.interpolateString(d3.transform(d3.select(this).attr("transform")), "translate(100,100) rotate(360)")


                          Here is your code with that change:






                          var svg = d3.select('svg');

                          var s = svg.append("rect")
                          .attr("width", 50)
                          .attr("height", 50)
                          .attr("x", -25)
                          .attr("y", -25)
                          .attr("fill", "red")
                          .attr("transform", "translate(100,100)");

                          s.transition()
                          .duration(1000)
                          .attr("transform", "translate(100,100) rotate(180)")
                          .transition()
                          .delay(1000)
                          .duration(1000)
                          .attrTween("transform", function() {
                          return d3.interpolateString(d3.transform(d3.select(this).attr("transform")), "translate(100,100) rotate(360)")
                          });

                          <svg></svg>
                          <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>








                          var svg = d3.select('svg');

                          var s = svg.append("rect")
                          .attr("width", 50)
                          .attr("height", 50)
                          .attr("x", -25)
                          .attr("y", -25)
                          .attr("fill", "red")
                          .attr("transform", "translate(100,100)");

                          s.transition()
                          .duration(1000)
                          .attr("transform", "translate(100,100) rotate(180)")
                          .transition()
                          .delay(1000)
                          .duration(1000)
                          .attrTween("transform", function() {
                          return d3.interpolateString(d3.transform(d3.select(this).attr("transform")), "translate(100,100) rotate(360)")
                          });

                          <svg></svg>
                          <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>





                          var svg = d3.select('svg');

                          var s = svg.append("rect")
                          .attr("width", 50)
                          .attr("height", 50)
                          .attr("x", -25)
                          .attr("y", -25)
                          .attr("fill", "red")
                          .attr("transform", "translate(100,100)");

                          s.transition()
                          .duration(1000)
                          .attr("transform", "translate(100,100) rotate(180)")
                          .transition()
                          .delay(1000)
                          .duration(1000)
                          .attrTween("transform", function() {
                          return d3.interpolateString(d3.transform(d3.select(this).attr("transform")), "translate(100,100) rotate(360)")
                          });

                          <svg></svg>
                          <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>






                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Jan 2 at 8:44

























                          answered Jan 2 at 2:18









                          Gerardo FurtadoGerardo Furtado

                          66.2k65193




                          66.2k65193






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53998448%2fhow-to-obtain-a-complete-clockwise-rotation-in-d3%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

                              Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

                              A Topological Invariant for $pi_3(U(n))$