Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

transform-origin for CSS animation on SVG working in Chrome, not FF

I am trying to create a simple animation using CSS and SVG: a rotating gear. The animation works perfectly in Chrome but not Firefox. Here is the code in action: http://jsfiddle.net/fL8Qn/

The gear is a path in a SVG file:

<div class="svg">
    <svg x="0px" y="0px" width="200" height="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
    <title>PDP</title>
    <text x="44" y="120" class="gear_text">PDP</text>
    <g transform="translate(50%, 50%)">
        <path id="gear1" class="gear go-clockwise" x="0px" y="0px" d="m91.63252,0l-4.16735,23.73752l0.01604,0.01606c-5.09374,0.83228 -10.02215,2.16622 -14.72963,3.9428l0,-0.01584l-15.46727,-18.48038l-14.53742,8.39871l8.25439,22.63163l0.03211,0.01585c-3.9412,3.23531 -7.55353,6.86028 -10.78684,10.8031l-0.01604,-0.04816l-22.63164,-8.25463l-8.39871,14.53743l18.48035,15.48333c-1.77354,4.70347 -3.09585,9.62447 -3.92695,14.71362l-0.01604,-0.01586l-23.73753,4.16734l0,16.79736l23.73753,4.16735l0.01604,-0.01587c0.83109,5.08915 2.15341,10.01014 3.92695,14.71381l-18.48035,15.48312l8.39871,14.53743l22.63164,-8.25444l0.01604,-0.04832c3.23331,3.94261 6.84564,7.56799 10.78684,10.80287l-0.03211,0.0159l-8.25439,22.63168l14.53742,8.39873l15.46727,-18.48027l0,-0.01582c4.70748,1.77637 9.63589,3.11047 14.72963,3.94278l-0.01604,0.01587l4.16735,23.73772l16.78132,0l4.16733,-23.73772l-0.01603,-0.01587c5.09294,-0.83009 10.02274,-2.15297 14.72985,-3.92696l15.4831,18.48047l14.53743,-8.39871l-8.27046,-22.63173c3.93234,-3.22687 7.54289,-6.83942 10.771,-10.7708l22.64757,8.25439l8.38263,-14.53741l-18.4642,-15.48308c1.77402,-4.70432 3.11153,-9.62388 3.94283,-14.71384l23.73775,-4.15126l0,-16.79738l-23.73775,-4.16735c-0.83148,-5.08432 -2.17067,-9.99828 -3.94283,-14.69775l18.4642,-15.4831l-8.38263,-14.53745l-22.64757,8.25443c-3.2281,-3.93136 -6.83842,-7.54391 -10.771,-10.77079l8.27046,-22.63168l-14.53743,-8.39871l-15.4831,18.48042c-4.70711,-1.77378 -9.63691,-3.09688 -14.72985,-3.92696l0.01603,-0.01586l-4.16733,-23.73761l-16.78132,0l0,-0.00011l0,0zm8.39869,40.8716c32.67677,0 59.17564,26.48283 59.17564,59.1596c0,32.67677 -26.49887,59.15962 -59.17564,59.15962c-32.67677,0 -59.15962,-26.48285 -59.15962,-59.15962c0,-32.67677 26.48286,-59.1596 59.15962,-59.1596z" stroke-dashoffset="0" stroke-miterlimit="4" stroke-linejoin="round" stroke-linecap="round" stroke-width="2"/>
    </g>
</svg>

And the animation is applied using CSS:

.svg {
  width:200px;
  height:200px;
  float:left;
  position: fixed;
  top: 20px;
  left: 50px;
}

.go-clockwise {
  -webkit-animation: clockwise 3s infinite linear;
  -moz-animation: clockwise 3s infinite linear;
}

.go-counter-clockwise {
  -webkit-animation: counter-clockwise 3s infinite linear;
  -moz-animation: counter-clockwise 3s infinite linear;
}
path.gear{
  fill: #3f3f3f;
}
text.gear_text{
  font-size: 55px;
  font-weight: 900;
  fill: #3f3f3f;
}

@-webkit-keyframes clockwise {
  0% {
    -webkit-transform: rotate(0deg);
    -moz-transform: rotate(0deg);
    -ms-transform: rotate(0deg);
    -o-transform: rotate(0deg);
    transform: rotate(0deg);
    -webkit-transform-origin: center center;
    -moz-transform-origin: center center;
    transform-origin: center center;

  }

  100% {
    -webkit-transform: rotate(360deg);
    -moz-transform: rotate(360deg);
    -ms-transform: rotate(360deg);
    -o-transform: rotate(360deg);
    transform: rotate(360deg);
    -webkit-transform-origin: center center;
    -moz-transform-origin: center center;
    transform-origin: center center;

  }
}

@-moz-keyframes clockwise {
  0% {
    -webkit-transform: rotate(0deg);
    -moz-transform: rotate(0deg);
    -ms-transform: rotate(0deg);
    -o-transform: rotate(0deg);
    transform: rotate(0deg);
    -webkit-transform-origin: center center;
    -moz-transform-origin: center center;
    transform-origin: center center;

  }

  100% {
    -webkit-transform: rotate(360deg);
    -moz-transform: rotate(360deg);
    -ms-transform: rotate(360deg);
    -o-transform: rotate(360deg);
    transform: rotate(360deg);
    -webkit-transform-origin: center center;
    -moz-transform-origin: center center;
    transform-origin: center center;

  }
}

@-webkit-keyframes counter-clockwise {
  0% {
    -webkit-transform: rotate(0deg);
    -moz-transform: rotate(0deg);
    -ms-transform: rotate(0deg);
    -o-transform: rotate(0deg);
    transform: rotate(0deg);
    -webkit-transform-origin: center center;
    -moz-transform-origin: center center;
    transform-origin: center center;

  }

  100% {
    -webkit-transform: rotate(-360deg);
    -moz-transform: rotate(-360deg);
    -ms-transform: rotate(-360deg);
    -o-transform: rotate(-360deg);
    transform: rotate(-360deg);
    -webkit-transform-origin: center center;
    -moz-transform-origin: center center;
    transform-origin: center center;

  }
}

@-moz-keyframes counter-clockwise {
  0% {
    -webkit-transform: rotate(0deg);
    -moz-transform: rotate(0deg);
    -ms-transform: rotate(0deg);
    -o-transform: rotate(0deg);
    transform: rotate(0deg);
    -webkit-transform-origin: center center;
    -moz-transform-origin: center center;
    transform-origin: center center;

  }

  100% {
    -webkit-transform: rotate(-360deg);
    -moz-transform: rotate(-360deg);
    -ms-transform: rotate(-360deg);
    -o-transform: rotate(-360deg);
    transform: rotate(-360deg);
    -webkit-transform-origin: center center;
    -moz-transform-origin: center center;
    transform-origin: center center;
  }
}

Using CSS is the preferred approach because I am applying the class dynamically. (counter clockwise when scrolling down, clockwise while scrolling up) but for the purposes of this question I’m just applying the one class. Chrome renders it fine, but Firefox doesnt seem to pick up on the -moz-transform-origin property. No matter what I use, firefox seems to be applying the transformation from an origin of (0,0) whereas Chrome picks up on the transform-origin property and works correctly.

I've tried just about everything I could find. Anyone have any ideas?

like image 557
Fingel Avatar asked Sep 21 '13 22:09

Fingel


2 Answers

I have a working example:

http://jsfiddle.net/4h3xL/1/

The problem with this answer is that the x="" and y="" attributes don't work on all svg elements, in your case they are valid on the text element but not the path.

My answer involves css transform: translate(). These values (along with the inline path attribute transform="translate()") get reset when you try to run an animation on the same element, as the animation is also a transform - transform: rotate(). I tried to chain the translate onto the rotate, but this weirdly didn't work in FF either.

I wrapped the path in two g's. The path and the outer group are used for offset/reset alignment, and the middle one for the animation.

like image 63
daviestar Avatar answered Sep 25 '22 14:09

daviestar


Seems as if Firefox has a "problem" with assigning the CSS animation to the <path> element inside the <svg>.

If updated your jsFiddle and just moved the class attribute from <path> to <svg>. Then it works as expected (except that the text now also rotates).

Alternatively you may use <animateTransform> in your SVG file.

See DEMO

like image 37
Netsurfer Avatar answered Sep 23 '22 14:09

Netsurfer