Recently, I have been doing year-end activities, hoping to make a wish in the form of bullets.

The following steps illustrate the logic of the barrage. In this paper, bullet barrage is relatively simple and focuses on explaining the logic of bullet barrage.

Display a barrage

Start with static text.

Very simple:

However, there is usually more than one bullet barrage in a row, so it definitely cannot be blocked. Therefore, the bullet-item here needs to be dealt with. I use the positioning method here (mainly for the future ballistic, which is more convenient for positioning).

<! -- app.vue --> <template lang="pug"> div# App div.bullet-wrap div.bullet-item weight loss success! </template> <style> body { margin: 0; } .bullet-wrap { height: 375px; background-color: #eee; position: relative; } .bullet-item { position: absolute; } </style>Copy the code

Keep the text out of the left screen

Make the text appear to disappear outside the left screen

.bullet-item {
  transform: translateX(-100%);
}
Copy the code

Keep the text out of the right screen

Make the text appear to disappear outside the right screen

.bullet-item {
  transform: translateX(100vw);
}
Copy the code

Move the text from the right screen to the left screen

Let the text move from the right screen to the left screen so that it appears to be born on the left and left on the right

.bullet-item {
  position: absolute;
  animation: rightToLeft 7s linear both;
}
@keyframes rightToLeft {
  0% {
    transform: translate(100vw);
  }
  100% {
    transform: translate(-100%); }}Copy the code

Multiple lines show

The feeling of the above barrage is already there. Next, look at the multi-line barrage.

The line of the barrage, or ballistics, is generally divided into several ballistics, like a track, and each athlete has his own track.

Two ballistic

In fact, the logic of the two ballistics lies in that the position of the ballistics is controlled by top, and the top of different ballistics is different

Div. Bullet-wrap div. Bullet-item (data-line="1") Div. Bullet - item (data - line = "2") has no bugs!Copy the code
.bullet-item[data-line="1"] {
  top: 0;
}
.bullet-item[data-line="2"] {
  top: 75px;
}
Copy the code

Multiple trajectories, off-peak operation

Multiple trajectories, which is just changing the top down, so I have 5 trajectories.

But because it’s all on at the same time, it’s kind of weird.

The logic of staggered peaks is as follows, which is also the core of this paper:

I’m going to break it up into two sets

  • Wait set: The set of bullets to be displayed
  • Display collection: a collection of bullets displayed on the screen. This is also a collection of page loops. When appearing in this collection, the bullets begin to scroll

Display barrage logic

  • Determine the trajectory, and the next barrage will appear within that trajectory
  • Fetch the first one from the wait set
  • Sets the trajectory of this barrage
  • This barrage into the display collection, the barrage begins to scroll

After a period of time, the bullet barrage will continue.

<template lang="pug"> div#app div.bullet-wrap div.bullet-item(v-for="item in showingBullets" :key="item.id" :data-line="item.line") {{item.name}} </template> <script> const getUUID = () => Math.random() + Math.random(); Export default {data() {return {// The queue to be displayed waitBullets: [{id: getUUID(), name: "a journey ", line: 0}, {id: GetUUID (), name: "end single dog ", line: 0}, {id: getUUID(), name:" stay with your parents ", line: 0}, {id: getUUID(), name: "Stay with your parents ", line: 0}, {id: getUUID(), name:" Stay with your parents ", line: 0} 0}, {id: getUUID(), name: "earn 100 million, buy a house ", line: 0}], showingBullets: [], lines: 5, currentLine: 1}; }, mounted() { this.showNextBullet(); setInterval(this.showNextBullet, 700); }, methods: { showNextBullet() { if (! this.waitBullets.length) { return; } this.currentLine = (this.currentLine % this.lines) + 1; CurrentBullet = this.waitBullets. Shift (); currentBullet = this.waitBullets. CurrentBullet. Line = this.currentLine; ShowingBullets. Push (currentBullet); }}}; </script> <style> html, body { min-height: 100%; overflow: hidden; } body { margin: 0; } .bullet-wrap { height: 375px; background-color: #eee; position: relative; } .bullet-item { position: absolute; animation: rightToleft 7s linear both; } .bullet-item[data-line="1"] { top: 0; } .bullet-item[data-line="2"] { top: 75px; } .bullet-item[data-line="3"] { top: 150px; } .bullet-item[data-line="4"] { top: 225px; } .bullet-item[data-line="5"] { top: 300px; } @keyframes rightToleft { 0% { transform: translate(100vw); } 100% { transform: translate(-100%); } } </style>Copy the code

Send a new barrage

Send a new barrage, actually nothing, send it to the waiting queue.

clickSend() {
    if (!this.newBullet) { return; } 
    const newBullet = { id: getUUID(), name: this.newBullet, line: 0 };
    this.waitBullets.push(newBullet);
}
Copy the code
Div. Input-wrap INPUT (v-model.trim="newBullet" type='text' maxLength =' 12'placeholder =' placeholder ') Button. The BTN (@ click = "clickSend")Copy the code

To optimize the

  • After the barrage disappears from the screen, it needs to be removed from the display queue
  • Clear timer before component destruction
  • To loop an infinite barrage list, you need to slip it back into the queue when the first one is pushed out
<template lang="pug"> div#app div.bullet-wrap div.bullet-item(v-for="item in showingBullets" @animationend='removeBullet' :key="item.id" :data-line="item.line") {{item.name}} div.input-wrap Input (v-model.trim="newBullet" type='text' maxLength =' 12'placeholder =' placeholder ') button.btn(@click="clickSend" </template> <script> const getUUID = () => Math.random() + Math.random(); Export default {data() {return {waitBullets: [{id: getUUID(), name: "Travel ", isWished: False, line: 0}, {id: getUUID(), id: getUUID(), name: IsWished: false, line: 0}, {id: getUUID(), name: "Accompany your parents ", isWished: false, line: 0}, {id: [], showingBullets: [], lines: 5, currentLine: 1, newBullet: [] "", isInfinite: true }; }, mounted() { this.showNextBullet(); const timer = setInterval(this.showNextBullet, 700); $once("hook:beforeDestroy", () => {clearInterval(timer); }); }, methods: { showNextBullet() { if (! this.waitBullets.length) { return; } this.currentLine = (this.currentLine % this.lines) + 1; CurrentBullet = this.waitBullets. Shift (); currentBullet = this.waitBullets. // This.isInfinite && this.WaitBullets. Push ({id: getUUID(), name: currentBullet. Name, isWished: false, line: 0}); CurrentBullet. Line = this.currentLine; ShowingBullets. Push (currentBullet); }, clickSend() { if (! this.newBullet) { return; } const newBullet = { id: getUUID(), name: this.newBullet, isWished: false, line: 0 }; this.waitBullets.push(newBullet); }, removeBullet() { this.showingBullets.shift(); console.log(this.showingBullets); }}}; </script> <style> html, body { min-height: 100%; overflow: hidden; } body { margin: 0; } .bullet-wrap { height: 375px; background-color: #eee; position: relative; } .bullet-item { position: absolute; animation: rightToleft 7s linear both; } .bullet-item[data-line="1"] { top: 0; } .bullet-item[data-line="2"] { top: 75px; } .bullet-item[data-line="3"] { top: 150px; } .bullet-item[data-line="4"] { top: 225px; } .bullet-item[data-line="5"] { top: 300px; } @keyframes rightToleft { 0% { transform: translate(100vw); } 100% { transform: translate(-100%); } } </style>Copy the code

insufficient

This kind is only suitable for simple barrage. If it is complicated, it is best to encapsulate the barrage. I am studying in my spare time. Later, when the product was added, I wanted to fill the screen with live screen as soon as I entered the page. After a moment’s thought, I configured the initial position and animation time of each of them in the display set. Because the logic was not complicated, I did not paste the code. If you’re interested, look at the code.

reference

  • Vue implements barrage effect