Barrage UI

Best and lightest barrage component for web UI.

Lightweight bullet-screen components for Web side user interfaces and players

use

  • Mount barrage animations for your video player, image browser, etc
  • Used to achieve B station (bilibili.com) style mask barrage effect

The installation

yarn add barrage-ui
Copy the code

or

npm install --save barrage-ui
Copy the code

Quick start

import Barrage from 'barrage-ui';
import example from 'barrage-ui/example.json'; // Sample data provided by the component

// Load the barrage
const barrage = new Barrage({
  container: 'barrage'.// Parent container or ID
  data: example, // Barrage data
  config: {
    // Global configuration item
    duration: 20000.// Barrage cycle (in milliseconds)
    fontFamily: 'Microsoft Yahei'.// Default font
    defaultColor: '#fff'.// The default color of the barrage}});// Add a new barrage
barrage.add({
  key: 'fctc651a9pm2j20bia8j'.// The unique identifier of the barrage
  time: 1000.// The time when the barrage appears (in milliseconds)
  text: 'This is a new barrage.'.// Barrage text content
  fontSize: 24.// The font size of this barrage (in pixels) overwrites the global setting
  color: '#0ff'.// The color of this barrage overrides the global Settings
});

// Play the barrage
barrage.play();
Copy the code

Initialization parameter

To create an instance of a barrage, pass in the following initialization parameters:

parameter The data type The default value instructions
container string/element Mandatory, no default value Mount point of barrage
data array [] Barrage of data
config object For details, see Global Configuration Items As shown in theGlobal configuration item
mask string/ImageData string/ImageData Mask map image, used to realize the mask barrage effect, seeThe mask barrage
beforeRender function (ctx, progress, animState) => {} The callback before rendering the frame is used as:

ctxCanvas The context of the canvas

progressAnimation playback progress in milliseconds

animStateAnimation state: ‘paused’ or ‘playing’
afterRender function (ctx, progress, animState) => {} Frame render callback with arguments as follows:

ctxCanvas The context of the canvas

progressAnimation playback progress in milliseconds

animStateAnimation state: ‘paused’ or ‘playing’
overlapOptimized boolean false Whether to enable layout optimization during barrage loading to avoid overlapping of barrage at adjacent times as much as possible

The Container parameter is mandatory during instance initialization, and other parameters are optional. The data types and default values are described in the preceding table.

Global configuration item

Configuration items and default values

All global configuration items and default values of the barrage are as follows:

{
  duration: - 1.// The cycle period of the barrage animation. -1 indicates that no cycle is played
  speed: 100.// The movement speed of the barrage
  fontSize: 24.// Text size, in pixels
  fontFamily: 'Microsoft Yahei'.// Font, default: Microsoft Yahei
  textShadowBlur: 1.0.// Font shadow spread, valid value >= 0
  opacity: 1.0.// Transparency, valid value 0-1
  defaultColor: '#fff'.// The default color, consistent with the CSS color attribute
}
Copy the code

Updating configuration Items

If your barrage instance has been created or is playing, you can update it in real time with the.setconfig () method:

// Update global transparency
barrage.setConfig({ opacity: 0.5 });
Copy the code

Barrage of data

Structure and content

The barrage dataset is an array of objects. Each array element corresponds to a barrage record, its structure is as follows:

{
  key: 'fctc651a9pm2j20bia8j'.createdAt: 'the 2019-01-13 T13:34:47. 126 z'.time: 1200.text: 'I'm inflated.'.fontFamily: 'SimSun'.fontSize: 32.color: 'yellow',}Copy the code

The data fields

  • CreatedAt – When the barrage was created (mandatory)
  • Time – The animation time of the barrage (mandatory)
  • Text – Barrage text content (mandatory)
  • Key – Unique identification of data (recommended)
  • FontFamily – Font for barrage text (optional)
  • FontSize – Bullet screen text size, in pixels (optional)
  • Color – The color of the barrage text (optional)

About the key

This field is recommended when the data set needs to be updated during animation.

When a data set is dynamically updated, there may be some same data in the data set before and after the update for the continuity of the animation. The Barrage assembly internally compares the data keys before and after the update and only incrementally renders the new data without changing the existing Barrage layout.

To sum up, the value of field key should be stable and unique. For the same barrage, the value of key should remain the same.

Loading barrage

There are two ways to load a barrage:

Method 1: Pass in data during initialization

const barrage = new Barrage({
  container: 'barrage'.data: JSON_DATA, // JSON_DATA -> Your barrage data
});
Copy the code

Method 2: Update data after initialization

const barrage = new Barrage({
  container: 'barrage'}); barrage.setData(JSON_DATA);// JSON_DATA -> Your barrage data
Copy the code

New barrage

If your barrage instance is already created or playing, you can add a new record using the.add() method:

barrage.add({
  key: 'fctc651a9pm2j20bia8j'.time: 1000.text: 'This is a new barrage.'.fontSize: 26.color: '#0ff'});Copy the code

The.add() method is typically used with data submission/request operations for real-world online applications.

Application scenario: Real-time barrage with multi-terminal synchronization

  1. A user submits a bullet screen to the server on the client
  2. The server stores and distributes the data to the client in session
  3. After the client receives the data, use.add()Method to update data

Animation control interface

barrage.play()

describe

Used to play animations. If the current state is paused, the playback continues from the current progress

Use cases

barrage.play();
Copy the code

barrage.pause()

describe

Used to pause animation

Use cases

barrage.pause();
Copy the code

barrage.replay()

describe

Used to restart the animation

Use cases

barrage.replay();
Copy the code

barrage.goto(progress)

describe

Used to jump the playback progress. This method works both when the animation is playing and when the animation is paused

parameter

Progress – Progress to be jumped. The value is a millisecond, indicating the millisecond to jump to the animation

Use cases

barrage.goto(15000); // Jump to 15 seconds
Copy the code

Animation state properties

barrage.progress

meaning

The progress of the current animation

type

Describes the number of milliseconds of playback progress

barrage.animState

meaning

The playing state of the current animation

type

A string describing the state of playback:

  • ‘Ready’ – Ready. That is: The Barrage instance was created but never played
  • ‘Paused’. – Paused
  • ‘Playing’ – playing

Other interfaces & properties

barrage.setMask(mask)

describe

Used to set the mask map image. The concept of a mask map is shown below

parameter

Mask-map URL or ImageData

Use cases

barrage.setMask('mask.png'); // Use the image URL to set the mask image

barrage.setMask(imageData); // Set data of type ImageData directly
Copy the code

barrage.clearMask()

describe

Used to clear the current map. If you do not reset the mask after clearing, the animation will no longer have the mask effect

Use cases

barrage.clearMask();
Copy the code

barrage.canvas

meaning

Render the canvas canvas of the barrage

barrage.ctx

meaning

The context of the canvas, equivalent to barrage. Canvas. GetContext (‘ 2 d)

The mask barrage

The Barrage kit provides the possibility of implementing mask Barrage effects. The demo effect based on this component is as follows:

What is a “masked barrage”

Masked bullet screen is a kind of rendering effect introduced by bilibili, a well-known video website of bullet screen, in the middle of 2018, which can effectively reduce the interference of bullet screen text to the main information of video.

Details can be found in Bilibili’s related article:

Sunscreen project 10 mask, have you heard of it?

Get out of your face and look! B station black technology mask barrage revealed

Realize the principle of

If you’re familiar with Adobe Photoshop, the most famous image processing software, then you’re probably familiar with the concept of “mask”, which works in a similar way: “hide” part of an image.

The Mask component’s initialization parameter is used to handle the mask effect. For the effect in the screenshot above, the mask image effect used is as follows:

When rendering, it will remove the “hollow” part of the mask map image (pixel 0 in the Alpha channel of the image RGBA channel), so as to achieve the effect of “masked barrage”.

Simple mask barrage implementation

The barrage effect can be masked by setting a mask for the Barrage instance.

  • By initializing the parametersmaskIncoming Map image:
import Barrage from 'barrage-ui';
import example from 'barrage-ui/example.json';

const barrage = new Barrage({
  container: 'barrage'.data: example,
  mask: 'mask.png'.// Pass in the mask map url
});
Copy the code
  • It can also be passed after the barrage is initialized.setMask()Methods Real-time update:
import Barrage from 'barrage-ui';
import example from 'barrage-ui/example.json';

const barrage = new Barrage({
  container: 'barrage'.data: example,
});

// Set the mask image
barrage.setMask('mask.png'); // Pass in the mask map url
Copy the code

Pay attention to

The mask parameter is of the same type as the.setmask () method and can receive the URL or ImageData of the image

Real-time rendering

The above example can only render one frame of the mask image (only set the mask once without updating it in real time). In order to achieve the real-time mask effect (such as the mask effect synchronized with the video in real time), it is necessary to process every frame of the barrage animation.

Using the beforeRender hook function provided by the component, you can easily implement:

import Barrage from 'barrage-ui';
import example from 'barrage-ui/example.json';

const barrage = new Barrage({
  container: 'barrage'.data: example,
  beforeRender: (ctx, progress) = > {
    const imageData = getMask(progress); // The method used to get the mask corresponding to the current progressbarrage.setMask(imageData); }});Copy the code

Of course, beforeRender hooks can also be mounted after the barrage is initialized:

import Barrage from 'barrage-ui';
import example from 'barrage-ui/example.json';

const barrage = new Barrage({
  container: 'barrage'.data: example,
});

barrage.beforeRender = (ctx, progress) = > {
  const imageData = getMask(progress); // The method used to get the mask corresponding to the current progress
  barrage.setMask(imageData);
};
Copy the code