Masking a div with an image and animating gradient background

1.2k Views Asked by At

I am currently designing a logo that has an animated gradient background.

Requirements:

  • The mask image must be either jpg or png
  • The element being masked should preferably be a <div>
  • The gradient should be CSS and preferably come from the <div> background

The mask should look something like this:

enter image description here

i have the CSS animations down, but when it comes to cutting a shape out of a <div> with an jpg or png image i seem to be stuck.

What i came up with:

I do not like my current solutions because it relies on SVG animations and im masking a SVG <rect> element not a <div>. It is much less flexible then if it was achieved mainly using CSS. But, it gets the job done.

<!-- image masked gradient -->
<svg  height="200px" width="200px">  
    <defs>  
        <!-- the gradient for the rectangle element-->
        <linearGradient id='gradient1'>
            <stop stop-color='#020024'/>
            <stop offset='.35' stop-color='#090979'/>
            <stop offset='1' stop-color='#6699ff'/>
            </linearGradient>

        <!-- the mask shape of a thunder bolt -->
        <mask id="image-mask" x="0" y="0" width="100" height="100" >  
            <image href="https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcRU8cEP-xBjtmZ2ZhpNKMc0dwE7I5a-PB8RBA&usqp=CAU" height="200" width="200"/>
        </mask>  
    </defs>

    <!-- this is the gradient rectangle element to be masked -->
    <g mask="url(#image-mask)">  
        <rect class="posr " x="10" y="0"  width="500%" height="400%" fill="url(#gradient1)">
           <animate attributeName="x" values='0px;-450px;0px' dur="5s"  repeatCount="indefinite" />
        </rect>
    </g>  
</svg>

So i basically want the effect showed in the snippet but mainly with CSS animations and the image mask!

2

There are 2 best solutions below

1
On BEST ANSWER

You can use CSS mask but you need to fîrst create a PNG image like below:

enter image description here

Then use it like below:

.box {
  display:inline-block;
  width:300px;
  -webkit-mask:url(https://i.ibb.co/m9fR6H1/aLOO0.png) center/cover;
          mask:url(https://i.ibb.co/m9fR6H1/aLOO0.png) center/cover;
  background:linear-gradient(to right,red,blue,green) left/300% 100% no-repeat;
  animation:change 2s linear infinite alternate;
}

/* maintain the square ratio */
.box::before {
  content:"";
  display:block;
  padding-top:100%;
}
/**/


@keyframes change {
  to {
    background-position:right;
  }
}

body {
  background:#f2f2f2;
}
<div class="box"></div>
<div class="box" style="width:150px;"></div>

The quality of the image I am using is very bad. I only focusing on the trick rather than the quality.

2
On

Here is a full CSS version. You can tweak it as you wish.

https://codepen.io/antoniandre/pen/qBbzXZK?editors=1100

    .bolt {
      width: 10em;
      height: 10em;
      margin: 3em auto;
      background-color: blue;
      clip-path: polygon(35% 37%, 53% 0, 81% 0, 68% 29%, 81% 29%, 67% 53%, 79% 53%, 49% 100%, 55% 67%, 38% 67%, 53% 38%);
      animation: color-cycle 4s infinite alternate;
    }
    
    @keyframes color-cycle {
      0% {background-color: blue}
      100% {background-color: black}
    }