This is the 25th day of my participation in the August Genwen Challenge.More challenges in August
β οΈ preface
- The thing is, some time ago, I got the company’s data large screen prototype drawing and asked me to make a whole page in one day.
- A quick look at it, it’s one
3840
*1840
The big screen and then a few lists and a few legends don’t look too complicated. - Swish! I worked a little overtime and got the whole page ready and showed it to the product manager with confidence.
- Product manager frowned: you this word cloud won’t move??
π€οΈ before the effect
- Hearing this, I realized that the situation was wrong. I thought that the word cloud of the prototype diagram could not tell that he had not asked me to move, and it was clear that what I did would move.
π’ diagram
- I started with
echarts
thegraph
Diagrams, which have the characteristic of having some dynamic effect at the beginning because the repulsive forces of each word are separated from each other, but do not continue to move because the force-guided layout stabilizes after several iterations.
- I: be I didn’t cheat people? It does move.
- Product manager: This effect is not good, there is no sense of science and technology, and I want the font size of each is different, tomorrow I will show the customer a version, it is urgent, forget it, you do not move let him word cloud fill up and then the size of each word is not the same.
π word cloud
- Do not do the verb cloud that is not easy, directly use
echarts
thewordCloud
Figure ah, direct shua Shua configuration is good.
- Product manager: The customer finished reading it, the whole is good, but I still want it to move the word cloud, so, you think of a way.
π Write by yourself
- I was really obsessed with this word cloud at first and decided to use it
echarts
To do it, but actuallywordCloud
The official website also does not provide information, there really seems to be no way to get it moving. - Think for a moment…. Wait, the word cloud has to be different sizes and colors and then it has to move around the region randomly, since I’m not familiar with it
canvas
I wonder if I can use itjs
andcss
To write a2d
To put it bluntly, it is a word in a container of random movement and then each word move to sa, as if can go…. Open dry.
π ToDoList
- Prepare containers and required configuration items
- Generate all static word clouds
- Get the word cloud moving
π Just Do It
- Because my tech stack is
vue 2.x
So we’re going to usevue 2.x
Syntax to share, but actually convert to nativejs
There is no difficulty, I believe we can accept.
π Prepare containers and configuration items
- We start by building a container around which to wrap our word cloud, and we do all the rest of our operations around this container.
<template>
<div class="wordCloud" ref="wordCloud">
</div>
</template>
Copy the code
- Because our word cloud needs to have different colors, we need to implement a word list and a color list, and prepare an empty array to store the words generated later.
. data () {return {
hotWord: ['All the best'.'Everything goes well'.'Everything goes well'.'Smooth sailing'.'All is well'.'Good luck'.'Up the ladder'.'Step by step'.'Three Sheep kaitai'.'In one's element'.'Money is coming in'.'Tao is not comparable'.'Happy Family'.'Spirit of Dragon horse'].color: [
'#a18cd1'.'#fad0c4'.'#ff8177'.'#fecfef'.'#fda085'.'#f5576c'.'# 330867'.'#30cfd0'.'#38f9d7'].wordArr: []}; }...Copy the code
- Prepared these words are to read the article now you say ~ if you think I said right might as well after reading the article to give a
praise
~ - All joking aside, now that the preparation is complete, start generating our word cloud.
π Generates all static word clouds
- If we want to fill a container with words, according to the normal logic of our diagram, one for each word
span
So that’s equivalent to onediv
There is an
(hotWord
There is a corresponding quantity in a containerspan
Labels are ok. - If you need different colors and sizes, pair them separately
span
Add different styles to the tags.
. mounted () {this.init();
},
methods: {
init () {
this.dealSpan();
},
dealSpan () {
const wordArr = [];
this.hotWord.forEach((value) = > {
// Set font color and size according to the number of span generated by the word cloud
const spanDom = document.createElement('span');
spanDom.style.position = 'relative';
spanDom.style.display = "inline-block";
spanDom.style.color = this.randomColor();
spanDom.style.fontSize = this.randomNumber(15.25) + 'px';
spanDom.innerHTML = value;
this.$refs.wordCloud.appendChild(spanDom);
wordArr.push(spanDom);
});
this.wordArr = wordArr;
},
randomColor () {
// Get a random color
var colorIndex = Math.floor(this.color.length * Math.random());
return this.color[colorIndex];
},
randomNumber (lowerInteger, upperInteger) {
// Get a random number between minimum and maximum.
const choices = upperInteger - lowerInteger + 1;
return Math.floor(Math.random() * choices + lowerInteger); }}...Copy the code
- We have to
hotWord
The hot word list is iterated, generating one every time there is a wordspan
Label, used separatelyrandomColor()
andrandomSize()
Set different random colors and sizes. - And then I’m going to do this
span
All in turndiv
In the container, so when we’re done, it looks like this.
π get the word cloud moving
- The words are added, and then we need to make them move, so how do we move them
transform
thetranslateX
andtranslateY
Properties, we need to make one word work first, and then apply it to everything else.
Let’s move the X-axis
- How do I move it? What we’re going to do here is an infinite loop thing, which is an element that moves indefinitely, since it’s infinite, in
js
Can you do it with a timer? It’s possible, but it’s going to get stuck, in case your computer explodes with too many words, on the other hand the key to writing animation loops is to know how long the delay is appropriate, if it’s too long or too short it’s not appropriate so don’t use timers. - And then I found out by accident
window.requestAnimationFrame
thisAPI
.requestAnimationFrame
There is no need to set the interval.
RequestAnimationFrame brings together all DOM operations in each frame in a single redraw or reflow that closely tracks the browser refresh rate, which is typically 60 frames per second.
- That is, when we loop through infinity let an element in
x
Axis ory
Axis shift, let’s say it moves to the right every second10px
So it’stranslateX
Is the cumulative10px
That’s true for every element so we need to givespan
Element adds an attribute to represent its position.
data () {
return{...timer: null.resetTime: 0. }; }methods: {
init () {
this.dealSpan();
this.render();
},
dealSpan () {
const wordArr = [];
this.hotWord.forEach((value) = >{... spanDom.local = {position: {
x: 0.y: 0}}; . });this.wordArr = wordArr;
},
render () {
if (this.resetTime < 100) {
// Prevent stack overflow
this.resetTime = this.resetTime + 1;
this.timer = requestAnimationFrame(this.render.bind(this));
this.resetTime = 0;
}
this.wordFly();
},
wordFly () {
this.wordArr.forEach((value) = > {
// Incrementing each loop by 1
value.local.position.x += 1;
// Animate the transition for each word
value.style.transform = 'translateX(' + value.local.position.x + 'px)';
});
},
},
destroyed () {
// Component destruction, disable timed execution
cancelAnimationFrame(this.timer);
},
Copy the code
- At this point, we add one to each element
local
It’s in the propertyThe initial position
Every time we execute itrequestAnimationFrame
When it wasThe initial position
all+ 1
And give this value totranslateX
So we’re moving every time we go around1px
Now let’s look at the effect.
Adjusting range
- Hey! Boy, there was movement, but how did it go too far?
- We found that every time
translateX
all+ 1
But there is no stopping range for him, so we need to give him one to start at the edge of the containerTurn around
The steps. - So how do we get him to turn around? Since we can make him move to the right every time
1px
So we can’t detect when it’sx
When the axis position is greater than the container positionx
If the axis position is less than the container position and it’s good to change the direction and change the direction we just useIs a negative number
To judge.
init () {
this.dealSpan();
this.initWordPos();
this.render();
},
dealSpan () {
const wordArr = [];
this.hotWord.forEach((value) = >{... spanDom.local = {position: {
/ / position
x: 0.y: 0
},
direction: {
// Positive goes to the right and negative goes to the left
x: 1.y: 1}}; . });this.wordArr = wordArr;
},
wordFly () {
this.wordArr.forEach((value) = > {
// Set the direction of movement to change direction when greater than or less than the boundary
if (value.local.realPos.minx + value.local.position.x < this.ContainerSize.leftPos.x) {
value.local.direction.x = -value.local.direction.x;
}
if (value.local.realPos.maxx + value.local.position.x > this.ContainerSize.rightPos.x) {
value.local.direction.x = -value.local.direction.x;
}
// Each time we move 1 to the right we move -1 to the left when it's negative
value.local.position.x += 1 * value.local.direction.x;
// Animate the transition for each word
value.style.transform = 'translateX(' + value.local.position.x + 'px)';
});
},
initWordPos () {
// Calculate the actual position of each word and the container position
this.wordArr.forEach((value) = > {
value.local.realPos = {
minx: value.offsetLeft,
maxx: value.offsetLeft + value.offsetWidth
};
});
this.ContainerSize = this.getContainerSize();
},
getContainerSize () {
// determine the container size to control the word cloud position
const el = this.$refs.wordCloud;
return {
leftPos: {
// The left side of the container and the top side
x: el.offsetLeft,
y: el.offsetTop
},
rightPos: {
// The position of the right side of the container and the position of the bottom
x: el.offsetLeft + el.offsetWidth,
y: el.offsetTop + el.offsetHeight
}
};
}
Copy the code
- Let’s start with one
initWordPos
To calculate the current position of each word and save its position for usegetContainerSize
Get the left, right, top and bottom positions of our outer container and save them. - Give us every
span
Add a propertydirection
The direction of
If it’s negative, it goes to the left, and if it’s regular, it goes to the right, and I wrote this comment in the code, so you can read it if you don’t clear it. - That means our word cloud will bounce around the container repeatedly, so let’s see what happens.
Random displacement
- Very good, is what we want!!
- Of course, we can’t write down every displacement
1px
And to do that, we need to do a random shift. - So how do we do random displacement? You can see that we’re talking about constant motion in a straight line and remember the formula for constant motion in a straight line?
- If you don’t remember, I suggest you go back to your physics book ~ the displacement formula of uniform linear motion is
x=vt
- this
x
That’s the displacement we need, and thist
We don’t have to worry about that because I said that up thererequestAnimationFrame
Will help us set the time, so we just need to control thisv
The initial velocity is just random.
dealSpan () {
const wordArr = [];
this.hotWord.forEach((value) = >{... spanDom.local = {velocity: {
// The initial velocity of each displacement
x: -0.5 + Math.random(),
y: -0.5 + Math.random() }, }; . });this.wordArr = wordArr;
},
wordFly () {
this.wordArr.forEach((value) = >{...//ε©η¨ε
¬εΌ x=vtvalue.local.position.x += value.local.velocity.x * value.local.direction.x; . }); },Copy the code
- We give each word
span
Element an initial velocity, and this initial velocity can be zero-
Will be able to+
It means move to the left or move to the right, when we deal with thistranslateX
And now let’s see what happens.
Improve y
- now
x
The axis is done exactly as we want it to beThe word cloud
Up, down, left, and right so we need to followx
So let’s do it the axis wayy
Axis. - Due to the length of the code I will not put out, I will give the source code below, you can go to download and have a look ~ we directly to see the finished product! Thank you for reading, and I wish you here:
- So far a simple word cloud animation is over, the specific source code I put here.
π is at the end
- First of all, thank you for reading here. In fact, there are many different solutions for different effects. You should not be too rigid in one plug-in or method.
- The front-end world is so wonderful that only careful people can find it interesting. I hope I can help those in need.
- If you feel that this article has helped to your words might as well π attention + likes + favorites + comments + forward π support yo ~~π your support is the biggest power OF my update.
π past wonderful
Fix echarts map rotation highlighting β‘
Read still not clear redraw and rearrangement come over beat me π, I say!!
How to elegantly write component examples using Vuepress (1) π
How to elegantly write component examples using Vuepress (below) π
How hard is style naming? Discussion on BEM naming conventions β‘