sfy
sfy

Reputation: 3228

css scale an SVG moves element

I am trying to make a svg animation, as the demo shows when I scale the charge fill of svg, it was pushed to the container's left edge.

Is it possible to keep the x,y attributes of the path in the svg? Or is my svg made impossible to animate correctly?

.svg {
  width: 40%;
}

#charge {
  /* animation: charge 1s ease infinite; */
  transform: scaleX(0.1);
}

@keyframes charge {
  0% {
    transform: scaleX(0.1);
  }
  100% {
    transform: scale(1);
  }
}
<div class="svg">
  <svg xmlns="http://www.w3.org/2000/svg" id="battery_1_" x="0px" y="0px" viewBox="0 0 214 100">
                <polygon id="outline" points="214,22.5 200,22.5 200,0 0,0 0,100 200,100 200,77.5 214,77.5"/>
                <rect id="charge" width="180" height="80" x="10" y="10" fill="#0071BC"/>
              </svg>
</div>

Upvotes: 6

Views: 1980

Answers (3)

Temani Afif
Temani Afif

Reputation: 272638

To avoid setting pixel value on the transform-origin you can also adjust the transform-box to have the transform-origin relative to the element and not the whole SVG:

.svg {
  width: 40%;
}

#charge {
  transform-origin: left;
  transform-box:fill-box;
  animation: charge 1s ease infinite;
  transform: scaleX(0.1);
}

@keyframes charge {
  0% {
    transform: scaleX(0.1);
  }
  100% {
    transform: scale(1);
  }
}
<div class="svg">
  <svg xmlns="http://www.w3.org/2000/svg" id="battery_1_" x="0px" y="0px" viewBox="0 0 214 100">
     <polygon id="outline" points="214,22.5 200,22.5 200,0 0,0 0,100 200,100 200,77.5 214,77.5"/>
     <rect id="charge" width="180" height="80" x="10" y="10" fill="#0071BC"/>
   </svg>
</div>

Upvotes: 9

milo
milo

Reputation: 976

You can use the transform-origin property allows you to change the position of transforming elements. The default values are 50%, 50%, making your transforms start in the middle of the element.

.svg {
  width: 40%;
}

#charge {
  transform-origin: 10px;
  animation: charge 1s ease infinite;
  transform: scaleX(0.1);
}

@keyframes charge {
  0% {
    transform: scaleX(0.1);
  }
  100% {
    transform: scale(1);
  }
}
<div class="svg">
  <svg xmlns="http://www.w3.org/2000/svg" id="battery_1_" x="0px" y="0px" viewBox="0 0 214 100">
     <polygon id="outline" points="214,22.5 200,22.5 200,0 0,0 0,100 200,100 200,77.5 214,77.5"/>
     <rect id="charge" width="180" height="80" x="10" y="10" fill="#0071BC"/>
   </svg>
</div>

Upvotes: 3

Anurag Srivastava
Anurag Srivastava

Reputation: 14413

You can animate the width instead, to achieve the desired effect:

.svg {
  width: 40%;
}

#charge {
  width: 10px;
  height: 80px;
  animation: charge 1s ease infinite;
}

@keyframes charge {
  0% {
    width: 0;
  }
  100% {
    width: 180px;
  }
}
<div class="svg">
  <svg xmlns="http://www.w3.org/2000/svg" id="battery_1_" x="0px" y="0px" viewBox="0 0 214 100">
   <polygon id="outline" points="214,22.5 200,22.5 200,0 0,0 0,100 200,100 200,77.5 214,77.5"/>
   <rect id="charge" x="10" y="10" fill="#0071BC"/>
  </svg>
</div>

Upvotes: 1

Related Questions