[Pixi] super beautiful! How to make mid autumn festival scene level animation!!

jsmask 2021-09-15 04:18:30
pixi super beautiful make autumn


I'm participating in the Mid Autumn Festival Creative submission competition , Details please see : Mid Autumn Festival Creative submission contest

Preface

The moon sinks into the blue sea and looks at the heavy building , Who put the light on to provoke sleepwalking .

——《 eight-line poem with seven characters to a line and a strict tonal pattern and rhyme scheme · Kongming latern 》

Introduce

In this issue, we begin to use pixi.js Lightweight h5 The game engine , To develop a complete scene level animation of the mid autumn night sky . This is a practical case of temporary creation , Hope you enjoy it , There is a bright starry sky , There is a charming full moon , The fragrance of sweet scented osmanthus , There are also Kongming lamps that repose our good wishes ..

VID_20210907_134552.gif

Text

1. Analyze requirements

  • Initialize the engine and image loading and texture generation
  • Static rendering of stars and moon
  • The effect of the breeze blowing over the sweet scented osmanthus branches
  • The formation and scattering of petals
  • Kongming lamp is near big and far small , Rise and interaction

That's what we've done , Let's prepare four pictures first , Then the infrastructure will be built first .

 Wechat screenshot _20210907141902.png

2. infrastructure

<body>
<div id="app"></div>
<script type="module" src="./app.js"></script>
</body>
 Copy code 
* {
padding: 0;
margin: 0;
}
html,
body {
width: 100%;
height: 100vh;
position: relative;
overflow: hidden;
background-color: #999;
}
#app {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
 Copy code 

Because we cooperate this time vite Do the project construction, so use module Pattern , It is convenient to introduce the module in the back .

import * as PIXI from "pixi.js";
const imgs = {
"sweet": "assets/sweet.png",
"lamp": "assets/lamp.png",
"moon": "assets/moon.png",
"petal": "assets/petal.png"
}
class Application {
constructor() {
this.app = null;
this.stage = null;
this.textures = null;
this.w = 800;
this.h = 600;
this.dt = 0;
this.init();
}
init() {
// initialization 
let el = document.getElementById("app")
this.app = new PIXI.Application({
resizeTo: el
});
this.w = this.app.view.width;
this.h = this.app.view.height;
this.stage = this.app.stage;
this.stage.sortableChildren = true;
el.appendChild(this.app.view);
this.loadTexture(imgs).then(data => {
this.textures = data;
window.addEventListener("resize", this.reset.bind(this))
this.render();
})
this.app.ticker.add(this.step.bind(this));
}
reset() {
// Reset 
this.w = this.app.view.width;
this.h = this.app.view.height;
this.stage.children.length = 0;
this.render()
}
loadTexture(imgs) {// Load picture texture }
render() {
this._renderSky();
this._renderMoon();
this._renderLamp();
this._renderSweet();
this._renderPetal();
}
_renderLamp() {// Render Kongming lamp }
_renderMoon() {// Render the full moon }
_renderPetal() {// Render petals }
_renderSweet() {// Render osmanthus branches }
_renderSky() {// Render the starry sky }
step() {
// frame 
this.dt++;
}
}
window.onload = new Application();
 Copy code 

What we do here is a full screen animation , therefore PIXI Directly adjust the width and height of all areas of the parent container for subsequent elements . also , What we expect is to load the texture, store the texture set, and then start rendering the elements . Next, write an image and load the generated texture loadTexture Function .

3. Resource loading

loadTexture(imgs) {
const textures = {};
return new Promise((reslove, reject) => {
let loader = this.app.loader;
for (const key in imgs) {
loader.add(key, imgs[key])
}
loader.load((info, resources) => {
for (const key in resources) {
let texture = PIXI.Texture.from(resources[key].data);
textures[key] = texture;
}
reslove(textures)
});
})
}
 Copy code 

We used pixi.js A self-contained loader , Load these pictures , After loading, we will turn it into texture one by one and store it in the object to facilitate its generation of sprites .

4. Full moon and starry sky

// full moon 
_renderMoon() {
const moon = PIXI.Sprite.from(this.textures["moon"]);
moon.scale.set(this.h / moon.height * 0.7, this.h / moon.height * 0.7);
moon.position.set(this.w - moon.width * 0.7, -moon.height * 0.3)
this.stage.addChild(moon);
}
 Copy code 
// Starry sky 
_renderSky() {
const sky = new PIXI.Container();
let color = this.createGradTexture();
for (let i = 0; i < this.w / 20; i++) {
const star = new PIXI.Sprite(color);
let scale = Math.random();
star.scale.set(scale, scale);
star.position.set(this.w * Math.random(), this.h * 0.7 * Math.random());
sky.addChild(star)
}
this.stage.addChild(sky)
}
createGradTexture() {
let canvas = document.createElement('canvas');
canvas.width = 8;
canvas.height = 8;
let context = canvas.getContext('2d');
let gradient = context.createRadialGradient(canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2);
gradient.addColorStop(0, 'rgba(255,255,255,1)');
gradient.addColorStop(0.3, 'rgba(255,255,255,1)');
gradient.addColorStop(0.45, 'rgba(0,0,128,1)');
gradient.addColorStop(1, 'rgba(0,0,0,1)');
context.fillStyle = gradient;
context.fillRect(0, 0, canvas.width, canvas.height);
return PIXI.Texture.from(canvas);
}
 Copy code 

The drawing of the moon will not be repeated , Is simply to generate the placement of the wizard .

Starry sky, we need to make a container first Container To collect stars , Then add this container to the scene . The number of stars is positively related to the screen size ,for Generate sprites one by one , But where did our elf texture come from , We expect the stars to be white hearts , There's a little blue light around , here , We can introduce another image to generate texture , perhaps , Just like me , stay createGradTexture Function use canvas api Draw a... With a circular gradient 8*8 Then generate a texture .

as for , The positions of the stars are randomly generated on the screen , Here I want only random to high 70% Quan man's words are a little contrary .

 Wechat screenshot _20210907144746.png

5. Cinnamon twigs flutter

_renderSweet(num = 10) {
const sweet = this.textures["sweet"];
const points = []
const ropeLength = sweet.width / num;
for (let i = 0; i < num; i++) {
points.push(new PIXI.Point(i * ropeLength, 0));
}
const strip = new PIXI.SimpleRope(sweet, points);
const stripContainer = new PIXI.Container();
stripContainer.addChild(strip);
stripContainer.position.set(10, -20);
stripContainer.scale.set(.5, .5);
stripContainer.rotation = Math.PI / 180 * 40;
stripContainer.zIndex = 10;
this.stage.addChild(stripContainer);
this.app.ticker.add(() => {
for (let i = 0; i < points.length; i++) {
points[i].y = Math.sin((i * 0.5) + this.dt * 0.1) * 2;
points[i].x = i * ropeLength + Math.cos((i * 0.3) + this.dt * 0.1) * 1;
}
})
}
 Copy code 

We don't do frame animation or bone animation here , Just use a static diagram to complete , Mainly used pixi.js Of SimpleRope, Turn the sweet scented osmanthus branch into a rope , In fact, I made some slices , Then change the position of each point when rendering updates , The effect of breeze floating can be realized .

VID_20210907_150040.gif

6. Petals falling

_renderPetal(num = 20) {
let petals = [...Array(num).values()];
petals = [].map.call(petals, petal => {
petal = PIXI.Sprite.from(this.textures["petal"]);
let scale = .1 + .2 * Math.random();
petal.scale.set(scale, scale);
petal.rotation = Math.PI / 180 * 360 * Math.random()
petal.position.set(this.w * Math.random(), this.h * Math.random());
petal.vy = Math.random() * 0.2 + 0.5;
petal.vx = Math.random() * 0.5 + 0.5;
petal.zIndex = 15 * Math.random();
this.stage.addChild(petal);
return petal;
})
this.app.ticker.add(() => {
petals.forEach(petal => {
petal.rotation += (0.025 * Math.random())
petal.alpha -= .0006;
petal.y += petal.vy;
petal.x += petal.vx;
if (petal.x > this.w + petal.width || petal.y > this.h + petal.height) {
petal.x = -this.w / 4 * Math.random()
petal.y = this.h * Math.random() - this.h / 2
petal.zIndex = 15 * Math.random();
petal.alpha = 1;
}
})
})
}
 Copy code 

Here our husband becomes 20 A petal wizard controls the displacement direction, size and other parameters , These parameters will be changed during rendering updates to achieve motion . however , When we update, we should pay attention to , Make boundary judgment , Once beyond the boundary , Let him reassign , Continuous reuse .

7. The sky lights are flying

_renderLamp(num = 12) {
let lamps = [...Array(num).values()];
lamps = [].map.call(lamps, lamp => {
lamp = PIXI.Sprite.from(this.textures["lamp"]);
let scale = .15 + .35 * Math.random();
lamp.scale.set(scale, scale);
lamp.position.set(this.w * Math.random(), this.h * Math.random());
lamp.vy = Math.random() * 0.36 + 0.2;
lamp.vx = 0.12 * Math.random();
lamp.zIndex = scale;
lamp.interactive = true;
lamp.on('pointerdown', this._pointerDown.bind(this, lamp));
lamp.on('pointerover', this._pointerOver.bind(this, lamp));
lamp.on('pointerout', this._pointerOut.bind(this, lamp));
const blurFilter = new PIXI.filters.BlurFilter();
lamp.filters = [blurFilter];
blurFilter.blur = (0.5 - scale) * 10;
this.stage.addChild(lamp);
return lamp;
});
this.app.ticker.add(() => {
lamps.forEach(lamp => {
lamp.y -= lamp.vy;
lamp.x += Math.sin(this.dt * lamp.vx) * 0.2;
if (lamp.y < -lamp.height) {
lamp.y = this.h;
lamp.w = this.w * Math.random();
lamp.vy = Math.random() * 0.36 + 0.2;
lamp.vx = 0.12 * Math.random();
}
})
})
}
_pointerDown(lamp) {
lamp.vy += .8;
}
_pointerOver(lamp) {
lamp.filters[0].blur = 0;
}
_pointerOut(lamp) {
lamp.filters[0].blur = (0.5 - lamp.scale.x) * 10;
}
 Copy code 

This is similar to the implementation of petal falling , But the direction is always upward , Because the Kongming lamp can't keep still after flying, so use trigonometric function sin To simulate his lateral periodic change . It's worth mentioning that there are many other , We randomly generate its size , Reuse zIndex Set priority according to size , It must be big in front , The small one is behind , And then use pixi.js The built-in filter does fuzzy processing , In this way, the Kongming lamp in the distance will become blurred , More real .

Next , Introduce pixi.js Three events :

  • pointerdown: An event is triggered when the pointer device button is pressed on the display object .

  • pointerover: An event is triggered when the pointing device moves onto the display object .

  • pointerout: An event is triggered when the pointing device moves out of the display object .

To receive the event, we need to send Kong Mingdeng's interactive Property on .

After clicking, the Kongming light will accelerate , Let's just change vy value , Moving in and out of blur dissipation is also simple .


Although there is some workload , But the difficulty is not so high , It's actually over here , The online demo

expand

We just used pixi.js The fur can build such a picture , I don't know what association you have after reading . Is to make a scene animation editor ? Or do you want to play rope games ? Or particle effects ? The essential purpose of our study is to explore , Criticize , Innovative ideas , So explore the world !


It's not easy to create , Your support is the driving force of my creation , Please comment on the collection with your praise , Three times with one click ~

版权声明
本文为[jsmask]所创,转载请带上原文链接,感谢
https://qdmana.com/2021/09/20210909111329213k.html

  1. Monthly salary 10K yard farmer, job hopping to 40K architect, summary of technical learning Roadmap
  2. Manually compile and deploy LNMP environment (centos7.5 + nginx-1.18.0 + mysql-5.7.30 + php-7.4.14)
  3. The drama "light" of the Republic of China premiered, with a dismal audience rating of less than 0.4, creating the worst audience rating of Hunan Satellite TV!
  4. It is said that Ericsson will cancel Nanjing R & D center
  5. Question d'entrevue commune de Spring Cloud, où est l'avenir de 2021 Java?
  6. Sharedpreferences Replacement - mmkv Integration and Principles, 27 years old Preschool Development
  7. Différence entre TCP et UDP, développement frontal mobile
  8. The whole process of mybatis dynamic proxy implementation of spring series? The correct answer rate is less than 1%
  9. Ajax Foundation
  10. Développement Android comprendre ces entrevues naturelles sans peur, Android Knowledge System
  11. L'expérience de l'entrevue d'embauche de l'école Java peut vous aider à obtenir une entrevue.
  12. Leetcode pinceau question 989 - simple - addition d'entiers sous forme de tableau
  13. Children of the Qiao family: after reading Qiao Zuwang's last selflessness, we can recognize his simple father's love
  14. Partager une petite expérience d'entrevue et obtenir un produit
  15. Solution de capture de paquets https sur la plate - forme Android et analyse des problèmes, Android développe un apprentissage complet
  16. Young people are the first choice for transportation. These hatchbacks suck countless powder. Is it your dish?
  17. "Net red granny" over 70 has countless circle powder by wearing, and is more fashionable than young people
  18. Méthodes de fonctionnement des tableaux couramment utilisées en javascript
  19. Summary of Vue knowledge points
  20. 10 septembre: deuxième visite d'une journée à Yantai, Shandong - vue nocturne de Chaoyang Street, Zhifu District
  21. Front and back end data interaction (V) -- what is Axios?
  22. Windows configures nginx to boot automatically
  23. Des questions d'entrevue communes à Tomcat pour discuter de votre compréhension de la technologie de verrouillage distribué,
  24. JS handscrap, Classic interview question, web front end Development Process
  25. Android 400 questions d'entrevue pour vous aider à entrer dans l'usine, un tour pour vous apprendre à comprendre netty
  26. Développement et projet d'application Web statique côté PC
  27. Recommandé pour le tutoriel Spring Framework, 2021 dernière question d'entrevue d'embauche de la société aiqiyi Java,
  28. La dernière revue scientifique de l'académicien Luo Liqun: architecture de la boucle neuronale pour stimuler la nouvelle Ia
  29. [partage d'expérience de travail], 2021 les dernières questions d'entrevue Java de Baidu, Headlines, etc.
  30. Lisez l'analyse de 497 questions pour l'entrevue d'ingénieur principal Android et vérifiez les lacunes.
  31. Grâce à cette collection de questions d'entrevue d'automne, le salaire de saut d'emploi et l'entrevue de développement audio et vidéo ont doublé.
  32. Prenez d'un coup l'offre de Tencent meituan et jetez un coup d'oeil à cette copie de l'entrevue de printemps!
  33. L'expérience et l'expérience d'un Maverick Java en matière d'entrevue sur les MTD, l'expérience de l'entrevue d'embauche du printemps Java en 2021,
  34. Vue中自定义列表复选框和全选框-案例
  35. Vue bidirectional binding (V-model bidirectional binding,. Sync bidirectional binding,. Sync transfer object)
  36. CSS text overflow ellipsis summary, as you wish
  37. C'est la mode la plus étrange que j'ai jamais vue.
  38. Cases à cocher et toutes les cases à cocher de la liste personnalisée en vue - CAS
  39. Vue bidirectional binding (V-model bidirectional binding,. Sync bidirectional binding,. Sync transfer object)
  40. Vue3.0 using Gaode map to obtain longitude and latitude information
  41. Front end interview daily 3 + 1 - day 877
  42. Vue bidirectional binding (V-model bidirectional binding,. Sync bidirectional binding,. Sync transfer object)
  43. React realizes the function of copying pictures with one click
  44. White space, word break and word wrap are the three most basic and confusing attributes in CSS - thoroughly understand
  45. Trois ans d'expérience d'entrevue avec une femme de programmation diplômée, une réflexion sur la cohérence de l'expiration des données de redis Master slave Node,
  46. Résumé de l'entrevue Android de Dachang, carte technique Android
  47. Un plan de carrière Java correct, découvrez les questions que vous devez poser lors de l'entrevue d'embauche du printemps Java de cette année.
  48. Le résumé de l'entrevue Android de Dachang est en retard
  49. Un article vous a appris à gérer les entrevues sur le Web, à partager 350 vraies questions d'entrevue Java,
  50. Jquery Tools Methodology collation, Sharing a little interview Experience
  51. Jquery plug - in urianchor, app front end Development
  52. $in jquery, Visualized Web Development Tool
  53. Le développement Java doit être fait. Les entrevues https demandent souvent une analyse complète.
  54. vue v-if未生效问题
  55. vue动态改变组件外部元素样式
  56. Jdk's Past Life: The Classic Features of Thin Number - java5 - - - 15 -, webfront Development
  57. Résumé des questions d'entrevue pour les ingénieurs en développement Java, analyse des questions d'entrevue à haute fréquence Dubbo,
  58. Who doesn't want to make a scratch music by himself? Scratch music is realized by native JS
  59. Learn XPath to help climb the data of major e-commerce platforms in the Mid Autumn Festival
  60. vue動態改變組件外部元素樣式