At first, I thought of using CSS3 animation to realize it. Later, I felt that the performance was not very good. After checking the materials, I found that canvas could be used to realize it, so I fumbled and wrote a simple bullet screen.

Barrage function

  1. Supports dynamic adding of bullets
  2. Barrage does not overlap
  3. Custom barrage color

rendering

demo 

The source address



The familiar vuEJS is chosen for the front-end framework

The basic idea of bullet screen rolling is to constantly change the position of bullet screen through timer and redraw cloth from time to time.

Implementation steps

First add a canvas tag, there is a point to note, the effect of the device pixel ratio on the canvas, there will be drawing blur.

Canvas drawing blur problem

<canvas width="600" height="600"></canvas> // If you simply write like this, canvas will appear blurred <canvas width="600" height="600" style="width: 300px; height: 300px"></canvas> // In order to avoid ambiguity, it is necessary to set the CSS width and height of canvas to 1/devicePixelRatio of the context width and height. This paper is set for devicePixelRatio:2. This value can be obtained from window.devicepixelRatio. <canvas ref="hiddenCanvas" width="0" height="0" style="display: none"></canvas> // will be used laterCopy the code

We first define an array to store the barrage data, a barrage information, including text content, X and Y coordinate position, color and speed (can be random or fixed, for the sake of simple calculation, we use the fixed speed here).

var dmArr = []; var gap = 80; Var hiddenCanvas = this$refs.hiddenCanvas; // How to add barragefunction pushDm(text, color) {
    lety = getY(); // Determine the runway firstletx = 600; // The initial x-coordinate is the right edge of the canvasletdelayWidth = 0; / / with the runwayfor (let i = 0, len = dmArr.length; i < len; i++) {
        let dm = dmArr[i];
        if(y === dm.y) {// If it is the same runway, set a certain interval to the rear row, to ensure that the barrage will not overlap; delayWidth += Math.floor(hiddenCanvas.getContext('2d').measureText(dm.text).width * 4 + 50); } } dmArr.push({ text: text, x: x + delayWidth, y: y, speed: 8, color: color || getColor() }); } // Get the y coordinate randomlyfunction getY() {
    letrange = Math.floor(600 / gap); // Number of runwaysreturnMath.floor(Math.random() * range + 1) * gap; } // Get the color randomlyfunction getColor() {
    return `${Math.floor(Math.random() * 16777215).toString(16)}`; } // Write oneforLoop, initialize 30 barragefor (let i = 0; i < 30; i++) {
    pushDm(`It's barrage ${i}`);
}

Copy the code

Next, set a timer of 20ms to achieve the effect of bullet screen rolling

var timer = null;
var ctx = this.$refs.canvas.getContext('2d');
function start(){
  timer = setInterval(() => { ctx.clearRect(0, 0, 600, 600); // Each time you need to empty the canvas ctx.save(); ctx.font ='30px Microsoft YaHei'; // Set the font size to 2 times the CSS size (devicePixelRatio is 2)if(! dmArr.length) stop(); // If there are no more bullets, stop the timerfor (let i = 0, len = this.dmArr.length; i < len; i++) {
        let dm = dmArr[i];
        let overRange = -ctx.measureText(dm.text).width * 2;
        dm.x -= dm.speed;
        if(dm.x < overRange) { dmArr.splice(i, 1); // Remove the item from the array when the barrage is not visible on the canvascontinue;
        }
        ctx.fillStyle = `#${dm.color}`;
        ctx.fillText(dm.text, dm.x, dm.y);
    }
    ctx.restore();
  }, 20);
}
function stop() {
    clearInterval(timer);
    ctx.clearRect(0, 0, 600, 600);
}Copy the code

We also need an input box to implement the function of adding bullets manually

<input type="text" @keyup.enter="sent" v-model="dmInput" maxlength="20">
<button type="button" @click="sent"</button> var dmInput =' ';
var color = ' '; // You can customize the color of the barragefunction sent() {
    if(! dmInput)return;
    stop();
    pushDm(dmInput, color);
    start();
    dmInput = ' ';
}Copy the code

Areas for improvement and questions?

  1. How to keep the barrage from overlapping when the velocity is not constant
  2. Video barrage is to locate each frame of the video according to the time point of sending the barrage. How to do that?