Skip to content

Commit

Permalink
feat: 新增弹幕头像的功能
Browse files Browse the repository at this point in the history
  • Loading branch information
pengan authored and pengan committed Jun 17, 2019
1 parent 5196287 commit f47c78c
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 28 deletions.
12 changes: 9 additions & 3 deletions docs/document/dataset.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ title: 弹幕数据
fontFamily: 'SimSun',
fontSize: 32,
color: 'yellow',
avatar: '/images/avatar.png',
avatarSize: 32,
avatarMarginRight: 8,
}
```

Expand All @@ -25,9 +28,12 @@ title: 弹幕数据
* time - 弹幕的动画时间 (**必须**)
* text - 弹幕文本内容 (**必须**)
* key - 数据的唯一标示 (**推荐**)
* fontFamily - 弹幕文本的字体 (可选)
* fontSize - 弹幕文本字号大小,单位:像素 (可选)
* color - 弹幕文本的颜色 (可选)
* fontFamily - 弹幕文本的字体,默认值:`'Microsoft Yahei'` (可选)
* fontSize - 弹幕文本字号大小,单位:像素,默认值:`24` (可选)
* color - 弹幕文本的颜色,默认值:`'#fff'` (可选)
* avatar - 头像的 url,须为正方形图片,不支持跨域,默认值:`null` (可选)
* avatarSize - 头像的大小,单位:像素,默认值为字号大小的 1.2 倍 (可选)
* avatarMarginRight - 头像与文本的间距,单位:像素,默认值为字号大小的 0.2 倍 (可选)
:::

::: warning 关于 key
Expand Down
29 changes: 22 additions & 7 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
requestAnimationFrame,
cancelAnimationFrame,
loadImage,
makeImageElement,
MIN_SEP,
layout,
insertItem,
Expand Down Expand Up @@ -254,18 +255,32 @@ export default class Barrage {
context.shadowOffsetY = 0;
context.shadowBlur = this.config.textShadowBlur * 2;
context.textBaseline = 'top';

dataShown.forEach(d => {
const left =
d.left -
(translateX +
this.canvas.width *
d.randomRatio *
2 *
MIN_SEP *
Math.sin((Math.PI * translateX) / this.canvas.width));

if (d.avatar && typeof d.avatar === 'string') {
context.drawImage(
makeImageElement(d.avatar),
left,
d.top - (d.avatarSize - d.fontSize) / 2,
d.avatarSize,
d.avatarSize
);
}

context.font = `${d.fontSize}px ${d.fontFamily}`;
context.fillStyle = d.color;
context.fillText(
d.text,
d.left -
(translateX +
this.canvas.width *
d.randomRatio *
2 *
MIN_SEP *
Math.sin((Math.PI * translateX) / this.canvas.width)),
left + d.avatarSize + d.avatarMarginRight,
d.top
);
});
Expand Down
79 changes: 61 additions & 18 deletions utils.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,68 @@
// 异步加载图片
export const loadImage = url => {
const picture = new Image();
picture.src = url;

return new Promise((resolve, reject) => {
picture.onload = () => {
resolve(picture);
};
picture.onerror = () => {
reject();
};
// 异步加载图片(若图片已加载,则使用缓存)
const loadImageCache = {};
export const loadImage = url =>
new Promise((resolve, reject) => {
if (loadImageCache[url]) {
resolve(loadImageCache[url]);
} else {
const picture = new Image();
picture.src = url;

picture.onload = () => {
loadImageCache[url] = picture;
resolve(picture);
};

picture.onerror = () => {
reject();
};
}
});
};

// 异步获取图像信息
export const getImageData = (url, renderWidth, renderHeight, dx, dy, dw, dh) =>
loadImage(url).then(picture => {
// 异步获取图像信息(若图片已加载,则使用缓存)
const imageDataCache = {};
export const getImageData = (
url,
renderWidth,
renderHeight,
dx,
dy,
dw,
dh
) => {
if (imageDataCache[url]) {
return Promise.resolve(imageDataCache[url]);
}

return loadImage(url).then(picture => {
const imgViewer = document.createElement('canvas');
imgViewer.width = renderWidth || picture.width;
imgViewer.height = renderHeight || picture.height;
const context = imgViewer.getContext('2d');

context.drawImage(picture, 0, 0, imgViewer.width, imgViewer.height);
return context.getImageData(
imageDataCache[url] = context.getImageData(
dx || 0,
dy || 0,
dw || imgViewer.width,
dh || imgViewer.height
);

return imageDataCache[url];
});
};

// 生成图片的 HTMLImageElement (若图片已存在,则使用缓存)
const imageElementCache = {};
export const makeImageElement = (url, alt) => {
if (!imageElementCache[url]) {
imageElementCache[url] = document.createElement('img');
imageElementCache[url].src = url;
imageElementCache[url].alt = alt || '';
}

return imageElementCache[url];
};

// 考虑浏览器兼容的 requestAnimationFrame 方法
export const requestAnimationFrame =
Expand Down Expand Up @@ -65,13 +99,19 @@ export const layout = ({ config, canvas, data, avoidOverlap = false }) => {
fontFamily = config.fontFamily,
color = config.defaultColor,
createdAt = new Date().toISOString(),
avatar,
avatarSize,
avatarMarginRight,
}) => {
// 计算文本宽度
const { width } = canvasContext.measureText(text);

return {
const details = {
key,
time,
avatar: avatar || null,
avatarSize: avatarSize || (avatar ? 1.2 * fontSize : 0),
avatarMarginRight: avatarMarginRight || (avatar ? 0.2 * fontSize : 0),
text,
fontSize,
fontFamily,
Expand All @@ -83,6 +123,9 @@ export const layout = ({ config, canvas, data, avoidOverlap = false }) => {
randomRatio: Math.random(),
visible: false,
};
details.width += details.avatarSize + details.avatarMarginRight;

return details;
}
);

Expand Down

0 comments on commit f47c78c

Please sign in to comment.