Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
386 views
in Technique[技术] by (71.8m points)

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...