skip to Main Content

I’m trying to animate butterfly wings, which should look like butterfly flapping wings. Can you help me achieve this?

Here is the JSfiddle: https://jsfiddle.net/qfoy6hbc/

.butterfly {
  width: 150px;
  height: auto;
}

.left-wing {
  animation: left 1s linear infinite alternate;  
  transform-origin: right;
}

.right-wing {
  animation: right 1s linear infinite alternate;  
  transform-origin: left;
}

@keyframes left{
  to {transform:rotateY(20deg)}
}
@keyframes right{
  to {transform:rotateY(-20deg)}
}
<svg id="Layer_2" class="butterfly" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 442.32 429.5">
  <defs>
    <style>
      .cls-1 {
        stroke-width: 0px;
      }
    </style>
  </defs>
  <g id="Layer_1-2" data-name="Layer 1">
    <g>
      <g class="left-wing">
        <path class="cls-1" d="M42.56,2.5c-8.1,6.9-11.3,21.2-16.1,71-3.9,41.1-6.6,57.7-13.6,83-2.9,10.5-3.5,14.1-3.1,18.9,1.6,17.6,20.9,37.3,52.2,53.3,13.2,6.7,39.3,17,58,22.8,15.2,4.7,45.5,12.5,48.6,12.5,2.4,0,2.9-3.9,2.9-24.9,0-39.9-7-88.3-16.9-118.2-11.4-33.9-28.4-59-64.1-94.8C71.96,7.7,60.36,0,50.96,0c-4.3,0-6,.5-8.4,2.5Z"/>
        <path class="cls-1" d="M32.76,237.1c-8.9,2.6-22.4,26.1-28.7,49.9-6.4,24.2-5.2,44.6,3.4,56.3,15.6,21.2,52,13.3,107-23.2,12.3-8.1,27.6-20.9,37.6-31.2,8.2-8.5,16.5-19,15.8-20.1-.3-.4-2.1-.8-4.1-.8-5.3,0-23.5-4.8-56-14.9-46.7-14.5-66.1-18.6-75-16Z"/>
      </g>
      <g class="right-wing">
        <path class="cls-1" d="M405.16,119c-20.1,2.3-56.1,10.1-72.2,15.7-29.1,10.1-53,25.5-79.6,51.1-14.6,14-31.7,32.8-43.9,48.2-9.9,12.5-24.2,33.8-23.7,35.4.4,1.3,26.4,12,41.3,17,15.7,5.3,56,15.2,69.2,17,6.2.9,17.7,1.6,25.5,1.6,27.2,0,42.9-6.5,50.5-20.8,1.8-3.3,3.2-6.6,3.2-7.3,0-2.4,11.2-29.4,17.2-41.4,3.3-6.6,13.7-25.5,23.1-42,23.1-40.7,28.1-52.3,26.2-62.1-.9-4.8-5.9-9.9-11.1-11.3-6.1-1.5-17.1-2-25.7-1.1Z"/>
        <path class="cls-1" d="M184.86,285.1c1.7,29,12.1,63.5,29.2,96.9,7.8,15.3,14.8,25.5,23.3,34.1,10,9.9,16.8,13.4,26.6,13.4s15-2.8,24-11.9c16.2-16.5,28.5-49.1,28.5-75.6,0-9.6-1.4-14-5.2-17.2-4-3.4-19-11.2-31.8-16.6-18.3-7.8-84-31.7-92.9-33.9l-2.4-.6.7,11.4Z"/>
      </g>
      <path class="cls-1" d="M189.66,216.6c-1.2.8-2.2,2.5-2.2,3.8,0,1.2-1.2,3.8-2.6,5.7-4.6,6.2-6.3,10.5-7.4,19.5-2,15.2-3.7,20.9-10.8,35.1-10.1,20.3-11.2,23.9-11.1,38.1.1,17,.3,17.2,7.7,7.8,3.4-4.2,7.3-9.6,8.6-11.9,3.2-5.4,6.1-16.6,8.1-31.2,1.8-13.4,3.7-18.9,11.2-33.2,5-9.8,5.3-10.7,5.3-17.7,0-4.1.5-7.8,1-8.1,1.7-1,1.1-6.1-.8-7.8-2.3-2.1-4.1-2.1-7-.1Z"/>
    </g>
  </g>
</svg>

Here is the SVG code and CSS animations

2

Answers


  1. There are no correct answer to your questions, but here is some advice

    First you need to set your pivot point correctly, you have transform-origin:left and right, but as the svg fot the wings expand left AND right, i would advise puting a transform-origin:center, or in your specific case somewhere along transform-origin:40% 65%

    Then amplify the movement of your wings and you will discover that it folds well along the X axis, but you will need a bit of folding along the other axis since you butterfly is not perfectly vertical.

    Two solutions here : play with rotateY, or start with a vertical svg and when it’s looking all good, rotate the whole Layer 1

    Login or Signup to reply.
  2. From the looks of it you’re not transforming relative to the coordinate of the butterfly body/the point where the wings meet the body. This becomes super obvious if you pick something like 120 degrees instead of 20, so: you probably want a different transform-origin property.

    And to make "picking the right origin" much easier: export your butterfly without the rotations baked in, and then work on your animation transforms for that axis-aligned butterfly first. Then, once those work, all you need to do is rotate the entire butterfly by adding a transform: rotate(...) to the .butterfly class:

    .butterfly {
      width: 150px;
      height: auto;
      transform-origin: center center;
      transform: rotate(30deg);
    }
    
    .left-wing {
      animation: left 1s linear infinite alternate;
      transform-origin: calc(50% - 10px) 0;
    }
    
    .right-wing {
      animation: right 1s linear infinite alternate;  
      transform-origin: calc(50% + 10px) 0;
    }
    
    @keyframes left {
      to {
        transform:rotateY(80deg)
      }
    }
    
    @keyframes right {
      to {
        transform:rotateY(-80deg);
      }
    }
    <svg width="425" height="347" viewBox="0 0 425 347" class="butterfly">
       <g class="left-wing">
          <path d="M 3.25,6.76 C -4.76,25.69 4.27,46.37 6.75,65.56 14.46,100.95 22.40,136.62 22.61,173.00 c 3.94,24.18 30.50,33.68 51.07,39.65 42.38,9.42 86.46,8.82 129.48,4.56 -0.74,-23.72 -13.48,-45.91 -21.61,-68.07 C 162.29,104.79 135.37,61.45 93.11,35.75 70.03,22.05 46.59,6.50 19.95,1.04 14.11,0.51 6.82,1.60 3.25,6.76 z"/>
          <path d="m 65.65,233.12 c -12.55,15.35 -12.07,37.29 -12.06,56.28 1.39,21.08 6.32,48.74 28.95,56.75 24.19,4.94 44.32,-14.64 60.54,-29.88 25.67,-26.28 48.96,-56.42 60.65,-91.66 -10.50,-4.02 -34.04,2.36 -49.73,0.66 -28.26,1.12 -57.32,-1.40 -84.87,6.04 z"/>
       </g>
       <g class="right-wing">
          <path d="M 384.10,6.82 C 342.38,26.89 300.33,51.58 275.03,91.75 c -24.15,38.06 -43.48,79.81 -53.83,123.80 15.97,6.62 39.55,4.40 58.40,4.84 37.97,-2.15 79.42,-2.54 111.46,-25.75 18.11,-13.71 11.23,-38.03 14.84,-57.30 C 409.50,96.97 423.93,58.13 425.60,17.59 425.20,-7.03 398.35,0.14 384.10,6.82 Z" />
          <path d="m 225.14,232.32 c 16.51,39.80 44.53,74.74 78.20,101.41 14.53,10.95 36.75,20.29 52.19,5.71 19.62,-24.37 20.23,-59.03 13.70,-88.34 -1.21,-22.04 -24.69,-23.52 -41.67,-25.17 -35.43,-2.78 -71.03,-4.56 -106.57,-4.24 1.38,3.54 2.76,7.09 4.15,10.64 z" />
       </g>
       <path d="m 208.77,165.63 c -6.38,17.39 -1.35,35.52 -0.65,53.52 -1.69,19.82 -8.16,40.50 1.20,59.52 6.04,19.57 13.75,-15.67 13.20,-23.24 -0.60,-19.43 -7.44,-38.78 -2.02,-58.17 1.15,-6.41 1.76,-42.76 -11.73,-31.62 z" />
    </svg>

    And if you’re going to put this on the web: optimize your SVG so it doesn’t contain application-specific properties like layer ids, data attributes, <defs> that don’t actually do anything, etc. No point in keeping any of that, it just bloats your SVG file.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search