The effect is as its name, must have seen snow (except maybe southerners haha), but the snow effect is just a kind of effect name, can be red rain and other free fall movement effect, this paper is to use pure CSS to simulate the effect of snow.

1. Introduction

Due to the activities of the company’s products, the effect similar to snow needs to be simulated. Browser animation is nothing more than CSS3 and Canvas (and GIF). Compare the advantages and disadvantages of CSS3 and Canvas:

  1. Freedom of animation:canvasWins;
  2. Complexity:canvasWins;
  3. Compatibility:canvasWins;
  4. Performance:css3Wins (requestAnimationFrameAnd hardware acceleration).

Due to certain performance requirements, Canvas has more computation than CSS3, which may result in poor performance. Therefore, CSS3 is used to simulate snow effect (PS: problems solved by CSS are not solved by javascript).

The enclosed address

  • Snow effect Github code
  • Snow effect Codepen

Principle 2.

Css3 animation is used in this paper. Add an animation property to the DOM element to simulate animation, as in the w3School example:


      
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>animation</title>
  <style>
    .animation{
      width:100px;
      height:100px;
      background:red;
      position:relative;
      animation:mymove 5s infinite;
      -webkit-animation:mymove 5s infinite;
    }
    @keyframes mymove{
      from {
        left:0px;
      }
      to {
        left:200px; }}</style>
</head>
<body>
  <div class="animation"></div>
</body>
</html>
Copy the code

Of course, this can be anyone, but there is a problem is that snow is not a mechanical fall, but fast and slow, swing amplitude, time is uncertain, the focus here is the need to structure randomness, rational analysis.

  1. [Fixed] Snow starts randomly in browser
  2. The speed of snow is random;
  3. The time of snowfall from the beginning to the ground is random (the time delay is random and the time of the whole snowfall process is random);
  4. During the snow swing randomly.

We can find the corresponding properties of randomness in CSS:

  1. The starting point:position(we usually use positioning in animation, because it can reduce unnecessary rearrangement and redrawing);
  2. Speed:animation-timing-function(provides rich speed attributes);
  3. Time:animation-durationandanimation-delay;
  4. Swing:transform: translateX()Displacement in the horizontal direction

Some might ask, these attributes are not random, like math. random. Let’s change the way we think about it. What we mean by random in this article is random snow, not random snow. The falling time, falling speed and swing range of each snow are fixed, and the falling time, falling speed and swing range between snow are different, so the effect is achieved.

With this in mind, the last question remains: how do you give each snow a different fall time, speed, and swing? Here we use the real random function Math.random, using the data custom property in conjunction with math. random and CSS property matching rules to determine the animation effect.

3. Create snow shapes

3.1 A linear gradient

.linear{
  width: 100px;
  height: 100px;
  background: linear-gradient(0, green 40%, red 40%, red 60%, green 60%);
}
Copy the code

3.2 Multiple linear gradient drawing snowflakes

.linear{
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background-image: linear-gradient(0, rgba(255,255,255,0) 40%.#fff 40%.#fff 60%.rgba(255255255, 0)60%),
    linear-gradient(45 deg, rgba (255255255, 0)43%.#fff 43%.#fff 57%.rgba(255255255, 0)57%),
    linear-gradient(90 deg, rgba (255255255, 0)40%.#fff 40%.#fff 60%.rgba(255255255, 0)60%),
    linear-gradient(135 deg, rgba (255255255, 0)43%.#fff 43%.#fff 57%.rgba(255255255, 0)57%);
}
Copy the code

4. Construct snow animation

I use CSS written by Sass to construct the animation. In fact, language doesn’t matter, but principle.

4.1 starting point

@for $i from 1 through 100 {
  .animation[data-animation-position='#{$i}'] {
    left: # {$i}vw; }}Copy the code

Here we use the loop function of Sass to create a match between 1 and 100 with a class name of animation and a property selector of [data-animation-position=1~100vw]. For example, we want the element left to be 50vw. Add class name data-animation-position=50vw. There are two points to note here:

  1. Range 1-100vw: Notice the units arevw, we want the starting point of a snowflake to be anywhere in the horizontal direction, andvwIt’s dividing the screen into equal parts100A,100vwIt’s a full screen;
  2. Why loop through 1 to 100: This is the only way to match the values we need in the range.

4.2 speed

$timing: (
  linear: linear,
  ease: ease,
  ease-in: ease-in,
  ease-out: ease-out,
  ease-in-out: ease-in-out
);

@each $key.$value in $timing {
  .animation[data-animation-timing='#{$key}'] {
    transition-timing-function: $value; }}Copy the code

4.3 time

Time includes animation motion time and delay time.

@for $i from 1 through 4 {
  .animation[data-animation-delay='#{$i}'] {
    animation-delay: # {$i}s; }} @for $i from 4 through 8 {
  .animation[data-animation-duration='#{$i}'] {
    animation-duration: # {$i}s; }}Copy the code

4.4 swing

Snow is composed of two animations, fall and Swing. The falling animation is fixed, and only the swing animation needs to be random. Therefore, I customized the attribute matching rules, and then the swing can be random.

@for $i from 1 through 4 {
  .animation[data-animation-name='#{$i}'] {
    animation-name: fall, swing#{$i}; }} @for $i from 1 through 4 {
  @keyframes swing#{$i25%} {{transform: translateX(-#{$i * 10}px); 50%} {transform: translateX(#{$i * 10}px);
    }
    75%{
      transform: translateX(-#{$i * 10}px);
    }
    100%{
      transform: translateX(#{$i * 10}px); }}}Copy the code

5. The randomness

I’m using React to show you code, but again, the language doesn’t really matter as long as you understand how it works.

5.1 Snowflake Element

<div className='page'>
  {
    Array(10).fill().map((v, i) = > (
      <span
        key={i}
        className='animation span'
        data-animation-position={this.position()}
        data-animation-timing={this.timing()}
        data-animation-delay={this.delay()}
        data-animation-duration={this.duration()}
        data-animation-name={this.name()}
      />))}</div>
Copy the code

Our snowflake element contains several attribute values:

  1. data-animation-position: start bit;
  2. data-animation-timing: snow speed;
  3. data-animation-delay: time delay;
  4. data-animation-duration: Total snow time;
  5. data-animation-name: Fall animation and swing animation.

5.1 Random range function

random(min, max){
  return Math.floor(Math.random() * (max - min + 1) + min)
}
Copy the code

5.2 Random attribute assignment

position(){
  return this.random(1.100)
}
delay(){
  return this.random(1.4)
}
duration(){
  return this.random(4.8)
}
name(){
  return this.random(1.4)
}
timing(){
  return ['linear'.'ease'.'ease-in'.'ease-out'.'ease-in-out'] [this.random(0.4)]}Copy the code

6. Summary

Zhang Xinxu’s three principles: no width, no pictures and no float.

I personally think that if you have to add a fourth none, it can be no JS lol (kidding). With the development of CSS, its field is very wide and deep and also indispensable, many times if CSS is used well, it will save a lot of time and JS code, the difficulty of the whole function will be reduced, mutual encouragement.