Search code examples
csscss-animationscss-transitionscss-transforms

Can I create a butterfly animation effect with translate3D (css), or another css animation on a single image or element?


I have an image of a butterfly, something like this.

butterfly

I am trying to figure out if there is any way to make it look like its wings are opening and closing with a 3D CSS transform/translate or animation, but without having to split the image up into parts (it can be a background image of a div though if that helps).


Solution

  • Yes, using background applied to two elements where each one will show only one half and then you simply rotate both on the Y axis.

    .box {
      width:300px;
      margin:20px;
      display:flex;
      perspective:500px;
    }
    .box::before,
    .box::after{
      content:"";
      padding-top:56%; /* ratio based on your image */
      flex:1; /* half the main element size */
      background-image:url(https://i.imgur.com/DgMoHC5.jpg);
      background-size:200% 100%; /* twice bigger than the pseudo element to get half the image*/
      animation:left 1s linear infinite alternate;  
      transform-origin:right;
    }
    .box::after {
      background-position:right; /* get the right part of the image */
      animation-name:right;
      transform-origin:left;
    }
    
    @keyframes left{
      to {transform:rotateY(60deg)}
    }
    @keyframes right{
      to {transform:rotateY(-60deg)}
    }
    <div class="box"></div>

    A more realistic animation with some translation:

    .box {
      width: 300px;
      margin: 20px;
      display: flex;
      perspective: 500px;
    }
    
    .box::before,
    .box::after {
      content: "";
      padding-top: 56%;
      flex: 1;
      background-image: url(https://i.imgur.com/DgMoHC5.jpg);
      background-size: 200% 100%;
      animation: left 0.5s linear infinite alternate;
      transform-origin: right;
    }
    
    .box::after {
      background-position: right;
      animation-name: right;
      transform-origin: left;
    }
    
    @keyframes left {
      from {
        transform: translateZ(80px) rotateY(-30deg)
      }
      to {
        transform:translateZ(0px) rotateY(50deg) 
      }
    }
    
    @keyframes right {
      from { 
        transform: translateZ(80px) rotateY(30deg)
      }
      to {
        transform:translateZ(0px) rotateY(-50deg) 
      }
    }
    <div class="box"></div>