Hello everyone, I am Qiufeng. Recently, WeChat released a new feature (updated to WeChat 8.0.6). The most popular non-"blowing shit" function is none other than the function of bombing shit one after another in various groups.
I don’t know if you have experienced such a time, when you were young, you would see the children next door doing this kind of evil fun during the New Year. 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 being able to make a function to let the whole people have fun is not in vain of the meaning of the product's appearance.
When updating WeChat 8.0 before, I also wrote an article "Teach you to realize the special effects of 8.0 "Blast" Fireworks Emoji" 160b99e4b99969. In the previous article, I used canvas
to achieve this. Last time, someone commented at the end of the article lottie
. In fact, I am still very interested in this, but I have not tried it. This time I thought Through the new way lottie
to realize this function.
Effect experience:
https://example.qiufeng.blue/wechat-feces/3-2-feces.html
Github address:
https://github.com/hua1995116/node-demo/tree/master/wechat-feces
Step dismantling
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. Every one of them is not too difficult, it can be said that the front-end Xiaobai can easily implement it.
1. Drop bomb
In this step, we can use the knowledge of the quadratic function to write a trajectory path (similar to y = $x^2$ ), and then use tween.js
to do the tween animation.
2. Bomb explosion
Use lottie
to realize animation.
3. Baba was blasted
Use css
animation to achieve
4. Everyone shakes
Use css
animation to achieve
summary
The above ideas we want to talk about, maybe you are already familiar with the realization of some of them based on the ideas, then you can skip part of it. With the above ideas, then we will start practicing with real swords and guns.
Implementation
1. Throw a bomb
We can actually see through careful observation that the trajectory of the bomb is actually a parabola. If we want to achieve this function, we can easily think of a quadratic function.
First, let's take a look at the definition of the quadratic function.
Generally, as the shape Y = ax² + BX + C (A ≠ 0) (A, B, C is constant ) of function called a quadratic function.
This is how it is expressed from images.
Obviously this is very similar to the trajectory we want.
Because the normal Cartesian coordinate system takes the vertical upward as the positive y axis, and the horizontal right as the positive x axis. For dom positioning, the upper left is (0,0) and the horizontal to the right is the positive x axis, and the vertical downward is the positive y axis. It's just that the coordinate system is flipped along the x-axis.
Therefore, as long as we determine a quadratic function, we can get the trajectory. Since the general term of the quadratic function has 3 unknowns, we only need to know 3 points to determine a quadratic function. Let us first assume that our quadratic function is like this.
Our 3 points are (0,H), (H,0), (3H, 3H). We can get the following formula by substituting the general term:
Then solve
get:
Therefore, we only need to get the height of the highest point of the bomb from the "shit" to draw the entire trajectory.
Now suppose our bomb is a 10px * 10px small square, set the starting point to (300, 300) and the end point to (0, 100) H=100. At this time, the quadratic function we get is:
We can get the following trajectory animation:
To render each frame of animation, we use the famous tween animation library Tween.js (animation) is a concept that allows you to change the properties of the object in a smooth manner. You only need to tell it which properties you want to change, what final values they should have when the tweening ends, and how long it will take, and the tweening engine will be responsible for calculating the values from the start point to the end point.
var coords = { x: 300 }; // 起始点 为 x = 300
var tween = new TWEEN.Tween(coords)
.to({ x: 0 }, 1000) // 终点为 x = 0, 并且这个动作将在1秒内完成
.easing(TWEEN.Easing.Linear.None) // 匀速
By the above definition, we can onUpdate
, the change to get each x
value, then y obtained by the above quadratic function, then the small block is updated.
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 finished is still missing something. Just like drawing, we only drew his bones, 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 square with a bomb. The shape of the bomb is very simple. We can cut it out of the layer through ps.
2. Modify the angle when it moves.
The complete code of this section: https://github.com/hua1995116/node-demo/blob/master/wechat-feces/1-2-animation.html
2. The bomb exploded
Then I will talk about the effect of the bomb explosion. As mentioned above, I want to change to lottie
to write animations, so what is lottie
?
Lottie is a library that can parse animations made with AE (need to export 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 went to https://lottiefiles.com/ to find a special effect file of json
And its writing method is very simple, only need to introduce lottie
, and then 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'), // 要包含该动画的dom元素
renderer: 'svg', // 渲染方式,svg、canvas、html(轻量版仅svg渲染)
loop: true, // 是否循环播放
autoplay: true, // 是否自动播放
path: './bomb.json', // 动画json文件路径
});
</script>
Therefore, we only need to call the explosion effect immediately after the parabola is completed, and tween.js
also provided me with the event method onComplete
. We only need to start the explosion animation onComplete
tween.onComplete(function () {
// 写爆炸动画
})
The complete code of this section: https://github.com/hua1995116/node-demo/blob/master/wechat-feces/2-2-lottie.html
3. Baba was exploded
3.1 Shape
In the same way, Bomb used PS Cutout to cut out "Baba" into a transparent layer, just like this. (It’s okay to have a little burr, the actual papa is not so big, so it’s not easy to see the burr, you can also fix it 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;
}
// 创建一个粑粑元素
function createfeces(scale = 1) {
const fece = document.createElement('div');
fece.className = 'feces';
// 由于粑粑有大有小,有方向,因此预留了值。
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
We can see that the papa flew out from the bursting place, and there were mainly 7 papas flying out, the middle of which was the largest, and the others became smaller as they were farther from the center. The arrangement is similar to a circle, but It's not so regular.
So we can do it in the simplest way first, which is to surround it in a circle. A circle is 360 °, we only need to divide it into 6 equal parts. We are surrounded by a total of 6 papas, so each is 60° between them.
Since our bomb above is roughly a 300 * 300 area, so I set the coordinates of the center of ) 160b99e4b9a23d, and then randomly generate a 70 ~ 230 x point, you can calculate the y value, and determine the first After a point, according to the angle between each point is 60°, the remaining 5 points can be calculated.
Since the center point is (150,150) as the center of the circle calculation 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.
// 计算要生成的多个粑粑的位置
// 传入的参数num为要生成的粑粑的数量
function randomPosition(num) {
const radius = 80; // 圆半径
const randomX = Math.random() * radius // 任取0到半径中的任意一个x
const y = Math.round(Math.sqrt(radius * radius - randomX * randomX)); // 确定一个第一象限在圆上的点
const radian = Math.atan(y / randomX); // 这个点的弧度值
const step = Math.PI * 2 / num; // 每坨屎间距的弧度值
return new Array(num).fill(0).map((item, index) => {
const r = (index * step + radian)
// 将弧度为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),
}
})
}
Then we draw according to this idea, draw 6 papas, and then translate 150 to the x-axis and y-axis respectively.
randomPosition(6).map(item => ({ x: item.x + 150, y: item.y + 150 })) // 此处你也定义多于6个
It seems a bit awkward, but all of them are the same size, so we need to deal with it. 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 baba 2/3 of the original.
const dis = Math.sqrt((end.x - 150) * (end.x - 150) + (end.y - 150) * (end.y - 150)); // 由于此时已经平移 150 ,因此需要计算距离中心点的距离
const r = Math.pow(2/3, dis / length); // 要缩放的比例
However, in the real scene, our placement will be more random, so I added a random value to the position of each papa, and the center papa will be more biased towards 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 {
// 增加随机值
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(),
}
})
}
3.3 Angle
In the end, we only need to embellish the angle of each papa.
function createfeces(scale) {
const fece = document.createElement('div');
fece.className = 'feces';
const symbol = Math.random() > 0.5 ? 1 : -1; // 生成 -20 ~ 20 之间的随机角度
fece.style.transform = `scale(${scale}) rotate(${symbol * 20 * Math.random()}deg)`
fece.style.opacity = '0';
return fece;
}
3.4 Animation
Since this is similar to dropping a bomb, I won't go into details. What needs to be mentioned is that since Baba comes out of the bomb position first and then slows down, here we need to use two Tween tween animations.
// 一开始的出现时候的动画,从爆炸口冲出来
function initFece(end) {
...
const start = { x: 0, y: 100, z: 0 }; // 爆炸口
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(); // 冲出完成,进行下落透明动画
})
return tween;
}
// 下落同时变透明动画
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
The complete code of this section: https://github.com/hua1995116/node-demo/blob/master/wechat-feces/3-2-feces.html
3.5 Summary
Since this section is relatively long, summarize the knowledge
- First use
1 = x² + y²
circular trajectory to establish a preliminary position - Then by adding random values, the entire distribution is slightly less regular
- Add random angles to Baba
- Let the central baba tend to explode
- Add chain animation to appear and fall
4. Everyone shakes
This function can be completed with simple css animation, so I won’t go into details 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% reduction animation. I don't write animation specifically, and the above library is also the first time I have used it. The writing may not be so professional (if you have any questions, please point out the error in the comment area). But I hope to provide you with a fun idea. When making animations, you can use the lottie
and tween
, as well as simplifying complex problems, turning irregular things into regular things, and turning complex things into simple Yes, and finally deepen it step by step. Also thank Nanxi for proofreading this article.
back at the author’s previous highly praised articles, maybe you can get more!
- 2021 front-end learning path book list-the road to self-growth :
570+
likes - teaches you to realize the 🎉 emoji special effects of 8.0 "Blast" 160b99e4b9a7b5:
400+
- Talk about the front-end watermark from cracking a design website (detailed tutorial) :
790+
- The front-end novice guidelines I learned from the glory of the king :
260+
- article takes you to unlock the mystery of "File Download" :
140+
likes - 10 kinds of cross-domain solutions (with ultimate big move) :
940+
likes
Concluding remarks
+ like + favorite + comment + forward , original is not easy, encourage the author to create better articles
Pay attention to the notes of the Qiufeng, a front-end public account that focuses on front-end interviews, engineering, and open source
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。