编程知识 cdmana.com

Pure CSS image fragmentation animation tutorial

 picture
Like it Focus on Let's


This article is translated from :
https://dev.to/afif/css-only-fragmentation-effect-using-one-element-18kg

Article begins , Let's go first GIF Let's show the final results of the development . No, JavaScript Handle , No, SVG Trick . Use only a single <img> And some of the CSS Rendering . When we hover over the picture , You can see the magic effect .

 picture

Isn't it cool ? ok , I have to admit that it's not just CSS, Because there's more SCSS, But it's still pure CSS effect , Because it doesn't involve JS.

The above effect involves two processes .

  1. Mask
  2. Animation gradient

Mask

Masks are sometimes difficult to conceptualize , And it's often confused with shear . most important of all : Masks are images . When applying an image as a mask to an element , Any transparent part of the image allows us to see directly through the element . Any opaque part makes the element fully visible .

How masks work and opacity (opacity) identical , It's just that they act on different parts of the same element . It's not like cutting , Clipping is a path that hides everything except the path . The advantage of masking is , You can have any number of layer masks on the same element —— And in background-image The way to link multiple images on is similar .

Because the mask is an image , So we can use CSS Gradient to make . Here's a simple example to better understand this technique .

img {
  mask:
    linear-gradient(rgba(0,0,0,0.80 0) left,  /* 1 */
    linear-gradient(rgba(0,0,0,0.50 0) right; /* 2 */
  mask-size50% 100%;
  mask-repeat: no-repeat;
}

 picture

We define two layer masks on the image , It's all solid color , however alpha The transparency values are different .

It is worth noting that , It doesn't matter what color you use , Because the default mask-mode by alpha. The only thing that matters is alpha value . Gradients can be linear-gradient(rgba(X,Y,Z,0.8) 0 0), among X,Y and Z It's all random values .

The mask size of each layer is 50% 100%( Or half the width and full height of the image ). A layer mask covers the left side , The other covers the right side . then , We get two non overlapping masks , They cover the entire area of the image , And as we said earlier , Each mask defines alpha The transparency values are different .

Animation gradient

What we're going to do is apply animation to the linear gradient of the mask alpha value , To create transparent animation . later , We'll make them asynchronous animations , To create a fragmentation effect .

Animation gradients are what we're doing CSS What we can't do in the world . however , Now we have @property Support for , Although support is limited .

In short ,@property Allows us to create custom CSS attribute , We can define the syntax by specifying the type . Let's create two properties --c-0 and --c-1, The initial value is 1.

@property --c-0 {
   syntax: "<number>";
   initial-value: 1;
   inheritsfalse;
}
@property --c-1 {
   syntax: "<number>";
   initial-value: 1;
   inheritsfalse;
}

These properties will represent CSS In the mask alpha value . And because they are all completely opaque by default ( Because the value is 1), So the whole image will be displayed through the mask . Here's how we can use custom properties to override masks :

/* Omitting the @property blocks above for brevity */

img {
  mask:
    linear-gradient(rgba(0,0,0,var(--c-0)) 0 0) left,  /* 1 */
    linear-gradient(rgba(0,0,0,var(--c-1)) 0 0) right; /* 2 */
  mask-size50% 100%;
  mask-repeat: no-repeat;
  transition: --c-0 0.5s, --c-1 0.3s 0.4s;
}

img:hover {
  --c-0:0;
  --c-1:0;
}

What we're doing here is applying different transition durations and delays for each custom variable . Next, let's move on to the effect of hovering the mouse over the image . The first gradient of the mask will fade out , until alpha The value is 0, To make the image completely transparent , And then there's the second gradient .

 picture

More masks !

up to now , We only used two linear gradients on the mask , Only two custom attributes are processed . To create a fragmentation effect , This is not enough , That means you need more gradients and custom attributes !

SCSS To make this work rather trivial , So now we're going to start writing styles . As we saw in the first example , We have a splicing matrix . We can think of them as rows and columns , So you can define two SCSS Variable $x and $y To express .

Custom properties

Every attribute needs to have @property Definition . however , No one wants to do it by hand , So use SCSS Do this heavy work for us by looping through properties :

@for $i from 0 through ($x - 1) {
  @for $j from 0 through ($y - 1) {
    @property --c-#{$i}-#{$j} {
      syntax"<number>";
      initial-value1;
      inherits: false;
    }
  }
}

And then when you hover over the mouse, make them all 0:

img:hover {
  @for $i from 0 through ($x - 1) {
    @for $j from 0 through ($y - 1) {
      --c-#{$i}-#{$j}: 0;
    }
  }
}

The gradient

We are going to write @mixin Generate gradients for us :

@mixin image() {
  $all_t: (); // Transition
  $all_m: (); // Mask
  @for $i from 0 through ($x - 1) {
    @for $j from 0 through ($y - 1) {
      $all_tappend($all_t--c-#{$i}-#{$j} transition($i,$j), comma);
      $all_mappend($all_mlinear-gradient(rgba(0,0,0,var(--c-#{$i}-#{$j})) 0 0) calc(#{$i}*100%/(#{$x} - 1)) calc(#{$j}*100%/(#{$y} - 1)), comma);
    }
  }
  transition: $all_t;
  mask: $all_m;
}

All of our layer masks are equal in size , So we just need one attribute , It depends on $x and $y Variables and calc()

mask-sizecalc(100%/#{$x}) calc(100%/#{$y})

You may have noticed this line of code as well :

$all_tappend($all_t--c-#{$i}-#{$j} transition($i,$j), comma);

We will also generate transition properties , Transition properties contain all previously defined custom properties .

Last , Thanks to the SCSS Medium random() function , Different durations are generated for each attribute / Delay .

@function transition($i,$j) {
  @return $s*random()+s $s*random()+s;
}

Now? , All we have to do is adjust $x and $y Variable , To control the size of the debris .

We can extend the code and change the random configuration , To consider different kinds of animation .

 picture

In the code above , I defined transition() function , As shown below :

// Uncomment one to use it
@function transition($i,$j) {
  // @return (($s*($i+$j))/($x+$y))+s (($s*($i+$j))/($x+$y))+s; /* diagonal */
  // @return (($s*$i)/$x)+s (($s*$j)/$y)+s; /* left to right */
  // @return (($s*$j)/$y)+s (($s*$i)/$x)+s; /* top to bottom */
  // @return  ($s*random())+s (($s*$j)/$y)+s; /* top to bottom random */
  @return  ($s*random())+s (($s*$i)/$y)+s; /* left to right random */
  // @return  ($s*random())+s (($s*($i+$j))/($x+$y))+s; /* diagonal random */
  // @return ($s*random())+s ($s*random())+s; /* full random*/
}

By adjusting the formula , We can get different kinds of animation : Just uncomment the line you want to use . This list is not exhaustive —— You can also consider more formulas for any combination .( imagine , If you add advanced math functions , for example sin(),sqrt() etc. , What might happen .)

We can also work with the code by adjusting the gradient , such , We can animate the starting color , Not right. alpha Value for animation . The gradient code is like this :

linear-gradient(white var(--c-#{$i}-#{$j}),transparent 0)

then , Animation variables from 100% Turn into 0%. wait , It doesn't have to be a linear gradient . Why not try radial ?

 picture

Same as before , The combination of definable gradients is infinite !

Let's introduce another variable to control the overlap between gradient masks . This variable will set mask-size, As shown below :

calc(#{$o}*100%/#{$x}) calc(#{$o}*100%/#{$y})

If it is equal to 1, There is no overlap . If it is greater than 1, Then there must be overlap . So we can make more kinds of animations :

 picture

Conclusion

All we have to do is find the perfect combination of variables and formulas , You can create amazing super cool image fragmentation effects .

( The text after the )

 picture

Share daily Front end plug-in dry goods , Welcome to your attention !

 Front end new world
Front end new world
Share HTML5/CSS3 technology ;jQuery plug-in unit ;Vue、React And other front-end development components
248 Original content
official account

Praise and watching is the greatest support

版权声明
本文为[Front end new world]所创,转载请带上原文链接,感谢
https://cdmana.com/2021/04/20210422160938374m.html

Scroll to Top