PK Creative Spring Festival, I am participating in the “Spring Festival Creative Submission contest”, please see:Spring Festival creative Submission contest
preface
Firecrackers in New Year’s Eve, spring breeze into tu Su;
Thousands of eyes pupil day, always put the new peach in the old symbol.
— Wang Anshi, Yuanri
introduce
The Spring Festival is just around the corner. In this issue, we will use canvas to make a background wall full of wishes for the Spring Festival. I wish you all a prosperous and prosperous Year of the Tiger. Come to kangkang effect first how:
Or pretty simple bar, itself also did not reference the third party library, the red background is drawn by CSS, the other are mainly pure JS to complete, which you can learn or find some about JS animation, screen adaptation skills, etc., what we are about to start
The body of the
1. Infrastructure
Our case is built with Vite, so we use module mode in Script.
<canvas id="canvas"></canvas>
<script type="module" src="./app.js"></script>
Copy the code
body {
background-image: repeating-radial-gradient(circle at center center, transparent 0px, transparent 8px.rgba(255.255.255.0.05) 8px.rgba(255.255.255.0.05) 11px, transparent 11px, transparent 17px.rgba(255.255.255.0.05) 17px.rgba(255.255.255.0.05) 25px, transparent 25px, transparent 38px.rgba(255.255.255.0.05) 38px.rgba(255.255.255.0.05) 42px),
repeating-radial-gradient(circle at center center, rgb(170.0.0) 0px.rgb(170.0.0) 11px.rgb(170.0.0) 11px.rgb(170.0.0) 19px.rgb(170.0.0) 19px.rgb(170.0.0) 24px.rgb(170.0.0) 24px.rgb(170.0.0) 33px.rgb(170.0.0) 33px.rgb(170.0.0) 44px.rgb(170.0.0) 44px.rgb(170.0.0) 46px);
background-size: 60px 60px;
}
Copy the code
Here we use the repeating-radial-gradient of CSS to draw a festive background.
2. Prepare a message
// app.js
const txt = ` monkey rat hai-zhu (lucky congratulations ) wish you happiness not wide Dragon to make Mr Sheep in the tiger year xu-gou Snake auspicious life wishing you see him as a dog Happy harmonious unitary horse and Ann are the chicken Big woman body kang horse warmth and JiPingJian a sound family more harmonic every year More than big fukang together into a bonanza The joy and good happy good luck `
Copy the code
We need to write some strings, some blessing words into it, and then mixed with some irrelevant words, so that users do not know at first glance.
3. Logical structure
// app.js
class Application {
constructor() {
this.canvas = null;
this.ctx = null;
this.w = 1600;
this.h = 1200;
this.color = "Rgba (33,33,33. 3)"
this.activeColor = "RGB (253190, 0)"
this.activeIndex = -1;
this.charNum = 12;
this.fontSize = 12;
this.charList = Array.from(txt.trim()).filter(char= >char.trim() ! ="");
this.word = ["May you"."In the Year of the Tiger."."Work well."."Get what you want."."Bonanza"."Good luck"."Lucky star."."The whole family."."Happy and happy"."Good luck"."In good health"."All the best."];
this.duration = 800;
this.nTime = 0;
this.pTime = 0;
this.fontScale = 1;
this.init();
}
init() {
this.canvas = document.getElementById("canvas");
this.ctx = this.canvas.getContext("2d");
window.addEventListener("resize".this.reset.bind(this));
this.reset();
this.step();
}
reset() {
this.canvas.width = this.ctx.width = this.w;
this.canvas.height = this.ctx.height = this.h;
this.fontSize = this.w / this.charNum;
let W = window.innerWidth;
let H = window.innerHeight;
let v = this.w / this.h;
if (W > H) W = H * v;
else H = W / v;
this.canvas.style.width = `${W}px`
this.canvas.style.height = `${H}px`
this.render();
}
render(delta = 0) {
this.clear();
const { charList} = this;
let activeIndexs = [];
charList.forEach((char, index) = > {
this.drawTxt(char, index, activeIndexs); })}drawTxt(char, index, activeIndexs) {
const { ctx, fontSize, color, charNum, activeColor, fontScale } = this;
let active = [].includes.call(activeIndexs, index)
let _fontScale = 0.65;
if (active) {
_fontScale = 0.65 * fontScale;
}
ctx.save();
ctx.font = `bold ${_fontScale * fontSize}px fangsong`;
ctx.fillStyle = ctx.shadowColor = active ? activeColor : color;
ctx.shadowBlur = active ? 15 : 3;
ctx.textAlign = "center"
ctx.textBaseline = "middle"
ctx.translate(~~(index % charNum) * fontSize * 1, ~~(index / charNum) * fontSize * 975.);
ctx.fillText(char, fontSize / 2, fontSize * 6.);
ctx.restore();
}
clear() {
const { w, h, ctx } = this;
ctx.clearRect(0.0, w, h);
}
step(delta) {
requestAnimationFrame(this.step.bind(this));
this.render(delta);
if (this.nTime - this.pTime > this.duration) {
this.activeIndex += 1;
this.activeIndex %= this.word.length;
this.pTime = delta;
this.fontScale = 1;
}
this.nTime = delta; }}window.onload = new Application();
Copy the code
Here are a few things we did:
- Duration specifies the number of seconds that each word should appear, and the number of seconds that each word should appear.
- Reset method to do screen adaptation, always make the canvas display on the screen more complete.
- Render and drawTxt methods, is to render and draw text, is currently simple to draw, activeIndexs is empty array is not found matching activation blessing, behind we will do how to find the location of these blessing.
- Of course, the drawTxt method has to write the active styles, such as fill color and size changes.
- The step method is to let this logic execute continuously, and then let its activeIndex change every duration period to activate another set of blessings.
4. Search for blessings
class Application {
// ...
render(delta = 0) {
this.clear();
const { activeIndex, charList, word } = this;
let activeIndexs = activeIndex >= 0 ? this.getTxtIndexs(word[activeIndex]) : [];
this.fontScale += (delta - this.nTime) * 001.;
if (this.fontScale) {
this.fontScale = Math.max(1.Math.min(1.5.this.fontScale))
}
else {
this.fontScale = 1;
}
charList.forEach((char, index) = > {
this.drawTxt(char, index, activeIndexs); })}findIndex(str, list, arr, tagIndex = 0, index = 0) {
if (index >= list.length) return arr;
if(str[tagIndex] ! = list[index].value) {return this.findIndex(str, list, arr, tagIndex, index + 1)
}
arr.push(list[index])
return this.findIndex(str, list, arr, tagIndex + 1, index + 1)}getTxtIndexs(str) {
const { charList } = this;
let _list = charList.map((char, index) = > {
if(str.indexOf(char) ! = -1) return {
value: charList[index],
index
}
}).filter(value= > value);
_list = this.findIndex(str, _list, [])
return _list.map(item= > item.index);
}
// ...
}
window.onload = new Application();
Copy the code
Here to do is every day to replace activeIndexs from inside to find blessing, find the blessing, you have to know these blessings in the inside of the position, and because a lot of blessings have the same text, we can not put the activation of the text all to find out, here in findIndex recursion query with consistency of the text, And then come back out. Then modify the Render method to fill activeIndexs with the information needed to activate the text, and the effect will appear in the traversal.
conclusion
Online demo, source and demo in codepen, although is a very simple little effect, but this blessing is sincere, dry technology is not easy all the time and be constantly learning progress, and to all aspects of pressure is very big also, tomorrow is New Year’s eve, New Year I wish you all the work is smooth, healthy body.