here we go again! 10 minutes to realize WeChat "exploding shit" battle

Time:2022-8-8

Hello everyone, I am Qiufeng. Recently, WeChat has released new functions (updated to WeChat 8.0.6). The most popular is the function of "exploding shit", and various groups have played the function of blasting shit.

here we go again! 10 minutes to realize WeChat "exploding shit" battle

I don’t know if you have ever experienced such a time, when you were a child during the New Year’s Eve, you would see the kids next door doing this kind of nasty fun, but I didn’t expect WeChat to make an online version of it. This functional invention even made fun of the person who created the product. But it's not in vain to make a function to make the whole people have fun.

here we go again! 10 minutes to realize WeChat "exploding shit" battle

When WeChat 8.0 was updated before, I also wrote an article"Teach you to realize the special effect of fireworks emoji of WeChat 8.0 "exploding"". In a previous post I usedcanvasTo achieve, last time someone commented at the end of the article, you can passlottie To achieve similar functions, in fact, I am quite interested in this, but I have not tried it, this time I want to use a new methodlottieto implement this function.

Effect experience:

https://example.qiufeng.blue/…

Github address:

https://github.com/hua1995116…

Steps to disassemble

Any object is composed of smaller objects, so if we want to achieve the above functions, we naturally have to do it step by step. I roughly disassembled the above functions into the following four steps. Each of them is not too difficult, and it can be said that the front-end Xiaobai can easily achieve it.

1. Drop bombs

In this step, we can use the knowledge of the quadratic function to write a trajectory path (similar to y = $x^2$ ), and then passtween.jsto do animation tween.

2. Bomb Explosion

uselottieto achieve animation.

3. Baba was blasted

usecssAnimation implementation

4. Everyone shakes

usecssAnimation implementation

Summarize

The ideas we generally want to talk about above, maybe you are already familiar with the implementation of some of them when you see the ideas, so you can skip some of them. With the above ideas, then we will start to practice.

Implementation

1. Drop bombs

here we go again! 10 minutes to realize WeChat "exploding shit" battle

We can actually see through careful observation that the trajectory of the bomb is actually a parabola. We want to achieve this function, it is easy to think of quadratic functions.

First, let's take a look at the definition of a quadratic function.

Generally, the formy=ax²+bx+c(a≠0)(a, b, c areconstant)offunctionis called a quadratic function.

This is how it is expressed from the image.

here we go again! 10 minutes to realize WeChat "exploding shit" battle

Obviously this is very similar to the trajectory we want.

Because the normal Cartesian coordinate system is the positive y axis vertically upward, and the positive x axis horizontally to the right. For dom positioning, the upper left is (0, 0), the horizontal and right are the positive x-axis, and the vertical and downward are the positive y-axis. It just flips the coordinate system along the x-axis.

Therefore, we only need to determine a quadratic function, and we can get the trajectory. Since the general term of a quadratic function has 3 unknowns, we only need to know 3 points to determine a quadratic function. Let's first assume that our quadratic function looks like this.

here we go again! 10 minutes to realize WeChat "exploding shit" battle

Our 3 points are (0,H), (H,0), (3H, 3H) We can get the following formula by substituting the general term:

here we go again! 10 minutes to realize WeChat "exploding shit" battle

then solve

here we go again! 10 minutes to realize WeChat "exploding shit" battle

get:

here we go again! 10 minutes to realize WeChat "exploding shit" battle

Therefore, we only need to get the height of the bomb's highest point from the "shit" to draw the entire trajectory.

here we go again! 10 minutes to realize WeChat "exploding shit" battle

Now suppose our bomb is a small square of 10px * 10px, set the starting point to (300, 300) and the end point to (0, 100) H=100, the quadratic function we get at this time is:

here we go again! 10 minutes to realize WeChat "exploding shit" battle

We can get the following trajectory animation:

here we go again! 10 minutes to realize WeChat "exploding shit" battle

To render each frame of animation, we use the famous tween animation libraryTween.jsTweening (animation) is a concept that allows you to change the properties of an object in a smooth way. You just tell it which properties to change, what final values ​​they should have when the tween finishes running, and how long this takes, and the tween engine will take care of calculating the values ​​from the start point to the end point.

var coords = { x: 300 }; // start at x = 300
var tween = new TWEEN.Tween(coords)
    .to({ x: 0 }, 1000) // the end point is x = 0, and the action will be completed in 1 second
  .easing(TWEEN.Easing.Linear.None)    // 匀速

Through the above definition, we canonUpdate, get the value of each changexvalue, and then get y through the above quadratic function, and then update the small square.

tween.onUpdate(function() {
    var x = coords.x;
    var y = 1/120 * x * x - 11/6 * x + 100;
        box.style.setProperty('transform', 'translate(' + x + 'px, ' + y + 'px)');
})

At this point, the effect we have completed is still missing something, just like painting, we only drew the bones for him, we need to color it, and then we only need to do the following two things, and then we can see It works~

1. Replace the block with a bomb, the shape of the bomb is very simple, we can cut it out from the layer through ps.

2. Modify the angle at which it moves.

here we go again! 10 minutes to realize WeChat "exploding shit" battle

The complete code of this section:https://github.com/hua1995116…

2. Bomb Explosion

Then I will talk about the effect of the bomb explosion. I also said it above. I want to replace it withlottie to write animation, thenlottiewhat is it then?

Lottie is a library that can parse animations made with AE (which needs to be exported to json format with bodymovin), and supports web, ios, android and react native. On the web side, the lottie-web library can parse the exported animation json file and draw the animation to our page in the form of svg or canvas.

then i gohttps://lottiefiles.com/found onejsonExplosion effect file.

here we go again! 10 minutes to realize WeChat "exploding shit" battle

And its writing is very simple, just need to introducelottie , and then callbodymovin.loadAnimationmethod.

<script></script>
</head>
<body>
<div class="bodymovin"></div>
<script>
    const animation = window.bodymovin.loadAnimation({
        container: document.querySelector('.bodymovin'), // the dom element to contain the animation
        renderer: 'svg', // rendering method, svg, canvas, html (light version only svg rendering)
        loop: true, // whether to loop playback
        autoplay: true, // whether to autoplay
        path: './bomb.json', // animation json file path
    });
</script>

So we only need to call the explosion effect immediately after the parabola is complete, andtween.jsalso gives me the event methodonComplete. we just need toonCompleteIn the callback, let the explosion animation begin.

tween.onComplete(function () {
  // write explosion animation
})

here we go again! 10 minutes to realize WeChat "exploding shit" battle

here we go again! 10 minutes to realize WeChat "exploding shit" battle

The complete code of this section:https://github.com/hua1995116…

3. Baba was blasted

3.1 Shape

In the same way, the bomb uses PS cutout to cut out &quot;Baba&quot; into a transparent layer, just like this. (It’s okay to have a little burr, the actual Baba is not so big, so it’s not easy to see the burr, you can also fix it by fine-tuning)

here we go again! 10 minutes to realize WeChat "exploding shit" battle

.feces {
  position: absolute;
  background-image: url(./feces.png);
  background-size: 100%;
  background-position: center;
  background-repeat: no-repeat;
  width: 80px;
  height: 80px;
  transform-origin: center;
}
// Create a Baba element
function createfeces(scale = 1) {
  const fece = document.createElement('div');
  fece.className = 'feces';
  // Since Baba is big or small and has direction, the value is reserved.
  const symbol = Math.random() > 0.5 ? 1 : -1;
  fece.style.transform = `scale(${scale * 1.1}) rotate(${symbol * 20 * Math.random()}deg)`
  return fece;
}

3.2 Location

here we go again! 10 minutes to realize WeChat "exploding shit" battle

We can see that the Baba flew out from the cracked place. There were mainly 7 Baba that flew out, the middle one was the largest, and the others became smaller as they were farther away from the center. The arrangement was similar to a circle, but Not so regular.

Therefore, we can implement the simplest way first, which is to surround with a circle. A circle is 360°, we just need to divide it into 6 equal parts. There are a total of 6 Baba we surround, so there is 60° between each.

Since our bomb above is roughly a 300*300 area, I willThe coordinates of the center are given as (150,150), and then randomly generate an x ​​point of 70 ~ 230 to calculate the y value. After determining the first point, according to the angle between each point is 60°, the remaining 5 points can be calculated.

here we go again! 10 minutes to realize WeChat "exploding shit" battle

Since the center point is (150,150) to calculate the center of the circle, it is more troublesome, so I moved the center point to (0, 0) for calculation, and finally all the calculated points are shifted to the x-axis and the y-axis by 150.

// Calculate the position of multiple Baba to be generated
// The incoming parameter num is the number of cakes to be generated
function randomPosition(num) {
  const radius = 80; // circle radius
  const randomX = Math.random() * radius // take any x from 0 to the radius
  const y = Math.round(Math.sqrt(radius * radius - randomX * randomX)); // Determine a point where the first quadrant is on the circle
  const radian = Math.atan(y / randomX); // radian value of this point

  const step = Math.PI * 2 / num; // the radian value of the interval between each shit

  return new Array(num).fill(0).map((item, index) => {
    const r = (index * step + radian)
    // Set radians to 0 - 2 * PI
    const tr = r > Math.PI * 2 ? r - Math.PI * 2 : r < 0 ? r + Math.PI * 2 : r;
    return {
      x: radius * Math.sin(tr),
      y: radius * Math.cos(tr),
    }
  })
            
}

here we go again! 10 minutes to realize WeChat "exploding shit" battle

Then we draw according to this idea, draw 6 cakes, and then translate 150 to the x-axis and y-axis respectively.

randomPosition(6).map(item =&gt; ({ x: item.x + 150, y: item.y + 150 })) // here you also define more than 6

here we go again! 10 minutes to realize WeChat "exploding shit" battle

It seems a bit that smelly, but all of them are the same size, so we need to deal with it. We scale the size according to the distance from the center, and roughly write one, because the radius of the circle is 80, and each increase of 80 will change the size of the cake to 2/3 of the original.

const dis = Math. sqrt((end.x - 150) * (end.x - 150) + (end.y - 150) * (end.y - 150)); // Since it has been translated by 150 at this point, so Need to calculate the distance from the center point
const r = Math.pow(2/3, dis / length); // ratio to scale

here we go again! 10 minutes to realize WeChat "exploding shit" battle

However, in the real scene, our placement will be more random, so I added a random value to the position of each Baba, and the center Baba will be more inclined to the upper left corner, and a certain random value.

function randomPosition(num) {
...
return new Array(num).fill(0).map((item, index) => {
  const r = (index * step + radian)
  const tr = r > Math.PI * 2 ? r - Math.PI * 2 : r < 0 ? r + Math.PI * 2 : r;
  return {
    // increment random value
    x: length * Math.sin(tr) + (Math.random() > 0.5 ? 1 : -1) * 10 * Math.random(),
    y: length * Math.cos(tr) + (Math.random() > 0.5 ? 1 : -1) * 10 * Math.random(),
  }
})
}

here we go again! 10 minutes to realize WeChat "exploding shit" battle

3.3 Angle

Finally, we only need to decorate the angle of each Baba.

function createfeces(scale) {
  const fece = document.createElement('div');
  fece.className = 'feces';
  const symbol = Math.random() &gt; 0.5 ? 1 : -1; // generate a random angle between -20 ~ 20
  fece.style.transform = `scale(${scale}) rotate(${symbol * 20 * Math.random()}deg)`
  fece.style.opacity = '0';
  return fece;
}

here we go again! 10 minutes to realize WeChat "exploding shit" battle

3.4 Animation

Since this is similar to dropping bombs, I won't go into details. It should be mentioned that, since Baba comes out of the bomb position first, and then slows down, we need to use two Tween animations here.

// The animation at the beginning of the appearance, rushing out of the explosion
function initFece(end) {
    ...
  const start = { x: 0, y: 100, z: 0 }; // blast port
  const tween = new TWEEN.Tween(start)
  .to({ ...end, z: 1 }, 100)
  .easing(TWEEN.Easing.Linear.None)
  .onUpdate(function () {
    fece.style.setProperty('top', `${start.y}px`);
    fece.style.setProperty('left', `${start.x}px`);
    fece.style.setProperty('opacity', `${start.z}`);
  })
  .onComplete(function () {
    initDown(start, fece).start(); // The rush out is completed, and the falling transparent animation is performed
  })
  return tween;
}
// Fall and become transparent animation at the same time
function initDown(start, fece) {
  const s = {
    y: start.y,
    o: 1,
  };
  const e = { y: start.y + 80, o: 0 };
  const tween = new TWEEN.Tween(s)
  .to(e, 2000 + 500 * Math.random())
  .easing(TWEEN.Easing.Quadratic.In)
  .onUpdate(function () {
    fece.style.setProperty('top', `${s.y}px`);
    fece.style.setProperty('opacity', `${s.o}`);
  })
  .onComplete(function () {
  })
  return tween;
}

final effect

here we go again! 10 minutes to realize WeChat "exploding shit" battle

The complete code of this section:https://github.com/hua1995116…

3.5 Summary

Since this section is long, summarize the knowledge

  • use first1 = x² + y²Characteristics of circular trajectories, establishing preliminary positions
  • Then by adding random values, the entire distribution is made slightly less regular
  • Add random angles to Baba
  • Make the center Baba more prone to the explosion
  • Added chain animation appearing and falling

4. Everyone shakes

This function can be completed with simple css animation and will not be described in detail here. Interested friends can implement it and put it in the comments~

end

This time is purely a curious exploration of this effect, not a 100% restoration of the animation. I am not a writer specializing in animation. The above library is also used for the first time, and the writing may not be so professional (if you have any questions, please feel free to point out errors in the comment area). But I hope it can provide you with a fun idea, which can be used when doing animation.lottieandtweenTwo libraries, as well as simplifying complex problems, turning irregular things into regular things, turning complex things into simple things, and finally deepening them step by step. Also thanksNanxiProofreading this article.

Looking back at the author's previous high praise articles, you may be able to gain more!

Epilogue

❤️Follow + Like + Favorite + Comment + Forward ❤️, originality is not easy, encourage the author to create better articles

Pay attention to the public accountautumn wind notes, a front-end public account focusing on front-end interviews, engineering, and open source

here we go again! 10 minutes to realize WeChat "exploding shit" battle