Hello, everyone, I am Qiu Feng. Recently, wechat has released new functions (updated to wechat 8.0.6). The most hot non – “fried shit” function is, a variety of groups have played the function of fried shit.

I don’t know if you have ever experienced such a time. When you were young, you would also see your neighbor’s kids doing this kind of bad fun during the Spring Festival. I didn’t expect wechat to make an online version of it. This feature invention, even the creator of the product also made fun of. But can do a function to let the people play happy, also does not waste the significance of the emergence of the product.

Before the wechat 8.0 update, I also wrote a “teach you to achieve wechat 8.0” burst “fireworks emoji effects. In the last article, I used Canvas. At the end of the last article, someone commented that Lottie could be used to achieve a similar function. In fact, I am interested in Lottie, but I have never tried it.

Effect experience:

Example. Qiufeng. Blue/wechat – fece…

Making address:

Github.com/hua1995116/…

Steps and dismantling

Every object is made up of smaller objects, so we have to do it step by step. I’ve roughly broken down the above functions into the following four steps. Every one of them will not be too difficult, so to speak, the front end of the small white can be easily achieved.

1. Throw bombs

In this step, we can use our knowledge of quadratic functions to write a trajectory path (like y = x2x^2×2) and then tween it with tween.js.

2. Bomb explosion

Use Lottie to animate.

3. The baba is exploding

Using CSS animation implementation

4. Everyone shakes

Using CSS animation implementation

conclusion

These are the general ideas that we want to talk about, and maybe you’re already familiar with some of these implementations, so you can skip some of them. With that thought in mind, it’s time to put it into practice.

The specific implementation

1. Throw bombs

If we look at it closely, we can actually see that the trajectory of the bomb is actually a parabola. We want to implement this function, and it’s easy to think of quadratic functions.

First of all, let’s look at the definition of quadratic functions.

In general, a function of the form y=ax²+bx+c (a≠0) where a, b, and c are constants is called a quadratic function.

That’s what it looks like graphically.

This is obviously very similar to the trajectory we want.

Because the normal Cartesian coordinate system is the Y-axis going up, and the X-axis going right. For dom positioning, the upper left is (0,0), the horizontal right is the X-axis, and the vertical downward is the Y-axis. I just flipped the frame around the X-axis.

So all we have to do is identify a quadratic function, and we get the trajectory. Since the general term of a quadratic function has three unknowns, we only need to know three points to determine a quadratic function. Let’s assume that our quadratic function looks something like this.

Our 3 points are (0,H), (H,0) and (3H, 3H) respectively. By substituting the general term, we can get the following formula:

And then work out

Get:

So, all we need to do is figure out how far away the highest point of the bomb is from the shit, and we can plot the entire trajectory.

Now suppose our bomb is a small square of 10px by 10px, and we set the starting point at (300,300) and the ending point at (0,100) H=100. At this point, we get the quadratic function as follows:

We get the following track animation:

To render each frame, we use the famous Tween library tween.js Tween is a concept that allows you to change the properties of an object in a smooth way. You just tell it what properties to change, what final values they should have when tween finishes running, and how long that takes, and the tween engine will compute the values from the starting point to the ending point.

var coords = { x: 300 };  // Start at x = 300
var tween = new TWEEN.Tween(coords)
	.to({ x: 0  }, 1000) // The endpoint is x = 0, and the action will be completed in 1 second
  .easing(TWEEN.Easing.Linear.None)	/ / uniform
Copy the code

So with that definition, we can get the x value of each change in onUpdate, get the y value from the quadratic function above, and then update the little 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)');
})
Copy the code

At this point, there is still something missing in the finished effect, just like painting, we only drew the skeleton, we need to color the packaging, then we just need to do the following two things, and then we can see the effect ~

1. Replace the block with a bomb. The bomb is very simple and can be pulled out of the layer by photoshop.

2. Modify the Angle at which it moves.

Complete code for this section: github.com/hua1995116/…

2. Bomb explosion

Then talk about the effect of the bomb explosion. I want to use Lottie to write the animation. What is Lottie?

Lottie is a library that parses animations made with AE (which need to be exported to JSON format with BodyMovin) for web, ios, Android, and React Native. On the Web side, the Lottie-Web library can parse the exported animated JSON file and draw it to our pages in SVG or canvas mode.

Then I went to Lottiefiles.com/ and found a JSON explosion effects file.

It’s very simple to write, just introduce Lottie and call the bodyMovin.loadAnimation method.

<script src="https://cdn.bootcdn.net/ajax/libs/lottie-web/5.7.8/lottie.min.js"></script>
</head>
<body>
<div class="bodymovin"></div>
<script>
    const animation = window.bodymovin.loadAnimation({
        container: document.querySelector('.bodymovin'), // The DOM element to include for the animation
        renderer: 'svg'.// Rendering mode: SVG, Canvas, HTML (lightweight version only SVG rendering)
        loop: true.// Whether to loop
        autoplay: true.// Whether to play automatically
        path: './bomb.json'.// Animated JSON file path
    });
</script>
Copy the code

So we just need to call the explosion immediately after the parabola completes, and tween.js gives me the event method onComplete. We just need to start the explosion animation in the onComplete callback.

tween.onComplete(function () {
  // Write the explosion animation
})
Copy the code

Complete code for this section: github.com/hua1995116/…

3. The baba is exploding

3.1 the shape

Similarly, the bomb uses Photoshop cutout to pull “Baba” out of a transparent layer, like this. (It’s ok to have a little burr, the actual baba is not that big, so it’s not easy to see the burr, but it can be fixed by fine tuning.)

.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;
}
Copy the code
// Create a baba element
function createfeces(scale = 1) {
  const fece = document.createElement('div');
  fece.className = 'feces';
  // Since baba has a large or small size and 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;
}
Copy the code

3.2 the position

We can see that there are mainly 7 baba flying out from the place where the baba is burst. Among them, the largest one is in the middle, while the others get smaller as they are farther away from the center. The arrangement is similar to a circle, but not so regular.

So we can do it the easiest way first, which is to surround it with a circle. A circle is 360 degrees, and we just have to divide it into 6 equal parts. We’re going around six of them, so there’s 60 degrees between each of them.

Since the bomb above is roughly a 300 * 300 region, I set the coordinate of the center as (150,150), and then randomly generate an x point between 70 and 230 to calculate the y value. After determining the first point, the remaining 5 points can be calculated according to the Angle between each point is 60°.

Since it is difficult to calculate the center of the circle with the center point (150,150), I moved the center point to (0, 0) for calculation, and then shifted all the calculated points to the X-axis and Y-axis by 150.

// Calculate the positions of multiple baba to be generated
// Pass num as the number of baba 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)); // Specify a point on the circle where the first quadrant is located
  const radian = Math.atan(y / randomX); // The radian value of this point

  const step = Math.PI * 2 / num; // The value of the radian distance between each piece of 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),
    }
  })
            
}
Copy the code

Then we follow this idea to draw 6 baba and then translate 150 to the X-axis and Y-axis respectively.

randomPosition(6).map(item= > ({ x: item.x + 150.y: item.y + 150 })) // Here you also define more than 6
Copy the code

It looks a little bit like that, but all of them are the same size, so we need to do something about that, and scale them according to how far they are from the center, roughly one, because the radius of the circle is 80, and every 80 increases the size of the pop by 2/3.

const dis = Math.sqrt((end.x - 150) * (end.x - 150) + (end.y - 150) * (end.y - 150)); // Since we have shifted by 150, we need to calculate the distance from the center point
const r = Math.pow(2/3, dis / length); // The scale to be scaled
Copy the code

However, in the real world, the placement would be more random, so I added a random value to the position of each baba, and the center baba would be more inclined to the upper left corner with 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 {
    // Increase the 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(),
  }
})
}
Copy the code

3.3 the Angle

At the end of the day, you just need to touch the Angle of each cake.

function createfeces(scale) {
  const fece = document.createElement('div');
  fece.className = 'feces';
  const symbol = Math.random() > 0.5 ? 1 : -1; // Generate a random Angle between -20 and 20
  fece.style.transform = `scale(${scale}) rotate(${symbol * 20 * Math.random()}deg)`
  fece.style.opacity = '0';
  return fece;
}
Copy the code

3.4 the animation

And since this is similar to dropping bombs, I won’t go into the details. It should be noted that since the poop is coming out of the bomb and then slowly coming down, we need to Tween it twice.

// At the beginning of the appearance of the animation, rushed out of the explosion
function initFece(end) {...const start = { x: 0.y: 100.z: 0 }; / / explosion
  const tween = newTWEEN.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(); // Dash out is complete, make the fall transparent animation
  })
  return tween;
}
// The animation becomes transparent while falling
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;
}
Copy the code

The final result

Complete code for this section: github.com/hua1995116/…

3.5 summarize

Since this is a long section, let’s summarize

  • First use of1 is equal to x squared plus y squaredThe characteristics of the circle trajectory, establish the initial position
  • And then by adding random values, you make the distribution a little less regular
  • Add random angles to the baba
  • Make the center more prone to the blast
  • Add chain animation to appear and fall

4. Everyone shakes

This function can be done with simple CSS animation. I won’t go into detail here, but if you are interested in it, please post it in the comments

At the end

This is purely a curious exploration of this effect, not a 100% animation. I am not a professional animation writer, and the above library is my first time to use, so I may not be so professional (feel free to point out any questions in the comments section). But I hope to provide you with an interesting idea. When making animations, you can use Lottie and Tween libraries to simplify complex problems, turn irregular things into regular things, and turn complex things into simple ones, and finally deepen them step by step. Thanks to Nan Xi for proofreading this article.

Look back at my previous highly praised articles, maybe you can harvest more oh!

  • 2021 Front Learning Path Booklist — Path to Self-growth: 570+ likes

  • Teach you to achieve wechat 8.0 “burst” 🎉 emoticons: 400+ thumbs up

  • From cracking a design website about front-end watermarking (detailed tutorial) : 790+ thumbs up

  • Front end novice guide I learned from King of Glory: 260+ likes

  • This article unlocks the secret of “file download” : 140+ likes

  • 10 cross-domain solutions (with the ultimate trick) : 940+ likes

conclusion

❤️ follow + like + collect + comment + forward ❤️, original is not easy, encourage the author to create better articles

Follow public AccountAutumn wind notes, a focus on the front-end interview, engineering, open source front-end public number