manager 方法
单位提示
所有参与计算的单位都允许通过表达式来计算,类似 CSS 的 calc
。
number
:默认单位为px
。string
:表达式计算。支持(+
,-
,*
,/
)数学计算,只支持%
和px
两种单位。
manager.setGap('(100% - 10px) / 5');
manager.canPush()
类型:(type: DanmakuType) => boolean
判断是否能够添加弹幕,超过内存限制阈值,渲染数量阈值会被阻止添加,你可以通过调用 manager.setLimits()
来更改。
// 判断当前能否 push 一个普通弹幕
manager.canPush('facile');
// 判断当前能否 push 一个高级弹幕
manager.canPush('flexible');
manager.push()
类型:(data: T, options?: PushOptions<T>) => boolean
发送一条弹幕,这条弹幕会被放在内存数组中等待被渲染,这不一定是即时响应渲染的,要看你设置的渲染算法,你可以通过调用 manager.setMode()
来更改,会触发 push
钩子。
注意
- 发送弹幕的时候,数据格式必须是
T
,至于T
的类型由你自己来控制,只要你能在渲染的时候能正确拿到就可以了,具体见下面的示例。 - 当第二个参数没有传递时,或者其中某些参数没有传递时,则会从
manager.options
里面取默认的值。
export interface PushOptions<T> {
id?: number | string;
rate?: number;
duration?: number;
plugin?: DanmakuPlugin<T>;
direction?: 'right' | 'left';
}
简单 case:
import { create } from 'danmu';
const manager = create<string>();
// 发送一条弹幕
// 时间,速率,方向等配置复用全局的也就是 create() 时传递的参数。
manager.push('弹幕内容');
完整 case:
import { create } from 'danmu';
const manager = create<{ content: string }>();
// 发送一条弹幕并添加插件处理,插件的作用域仅限当前 push 的这一条弹幕。
manager.push(
{ content: '弹幕内容' },
{
id: 1, // 如果你的弹幕有 id,可以添加到这里
rate: 1.5,
duration: 1000,
direction: 'left',
plugin: {
createNode(danmaku) {
const div = document.createElement('div');
div.innerHTML = danmaku.data.content; // 弹幕内容
danmaku.node.appendChild(div);
},
},
},
);
manager.unshift()
类型:(data: T, options?: PushOptions<T>) => boolean
push
方法是添加到内存数组后面,此方法会将弹幕添加到内存数组前面,当用户在输入了一条弹幕点击发送的时候,你应该使用此方法,以便于让弹幕在下次轮询的时候立即渲染,用法和 push
方法一样,会触发 push
钩子。
manager.pushFlexibleDanmaku()
类型:(data: T, options?: PushFlexOptions<T>) => boolean
发送一条高级弹幕,高级弹幕会在下次轮询的时候渲染,会触发 push
钩子。
高级弹幕说明
- 高级弹幕的
options
和普通弹幕的options
行为一样,如果不传会默认从manager.options
里面取默认值。 - 高级弹幕必须传递
position
来指定位置,如果需要指定在某个轨道渲染,可以借助getTrack().location
来做到。
import { create } from 'danmu';
interface Position {
x: number;
y: number;
}
interface PushFlexOptions {
id?: number | string;
rate?: number;
duration?: number;
plugin?: DanmakuPlugin<T>;
direction?: 'left' | 'right' | 'none'; // 普通弹幕没有 'none'
position:
| Position
| ((danmaku: Danmaku<T>, container: Container) => Position);
}
const manager = create<string>();
// 发送一条弹幕,在容器居中的位置,静止 5s
manager.pushFlexibleDanmaku('弹幕内容', {
duration: 5000,
direction: 'none',
position(danmaku, container) {
// 也可以通过字符串表达式来设置 `50% - (${danmaku.getWidth()} / 2)`
return {
x: (container.width - danmaku.getWidth()) * 0.5,
y: (container.height - danmaku.getHeight()) * 0.5,
};
},
});
manager.getTrack()
类型:(i: number) => Track<T>
获取某个具体的轨道,下标默认从 0
开始,如果下标为负数,则从后往前取,轨道的 API 见 轨道 API
。
// 获取第一条轨道
const track = manager.getTrack(0);
// 获取最后一条轨道
const track = manager.getTrack(-1);
manager.len()
类型:() => { stash: number; flexible: number; view: number; all: number }
返回当前渲染引擎的弹幕状态数量,这是实时变化的。
all
所有弹幕的数量,包括内存区,渲染中的弹幕。view
当前正在渲染的弹幕数量,包含普通弹幕和高级弹幕。stash
当前储存在内存区的普通弹幕数量。flexible
当前高级弹幕的数量,包含正在渲染的和在内存区的。
const { stash, flexible, view, all } = manager.len();
manager.each()
类型:(fn: (danmaku: Danmaku<T>) => boolean | void) => void
对当前正在渲染的弹幕做同步遍历,回调函数返回 false
的时候会终止遍历。
manager.asyncEach()
类型:(fn: (danmaku: Danmaku<T>) => boolean | void) => Promise<void>
对当前正在渲染的弹幕做异步遍历,回调函数返回 false
的时候会终止遍历。
与 `each` 的不同
asyncEach
方法会做时间切片,也就是说当你渲染的弹幕过多时,在遍历的时候由于代码运行时间过长,可能会对主线程造成一定阻塞,所以当有切片之后,则可以缓解这一现象。
manager.mount()
类型:(node?: HTMLElement | string, { clear?: boolean }) => void
将内核的弹幕容器挂载到一个 HTML 节点上,可以是一个 string
类型的 CSS
选择器,clear
参数可以用来清除之前渲染的弹幕,默认为 true
,如果你不想清除可以传 false
,挂载之后你可以通过 manager.container.parentNode
拿到这个节点。
和内核的容器节点的区别
内核的容器节点是所有弹幕渲染的节点,包括我们通过 manager.setArea()
来调整的时候也是更改的容器节点,但是容器节点需要挂载到一个具体的 DOM 上,所以这是他们之间的区别,容器节点的宽高都是 100%
。
manager.mount('#root');
// 或者
manager.mount('#root', { clear: false });
manager.unmount()
类型:() => void
将内核的弹幕容器从当前挂载的节点中卸载,卸载之后当你通过 manager.container.parentNode
获取时会得到 null
。
manager.unmount();
manager.clear()
类型:() => void
清空当前渲染和内存中的弹幕,会触发 clear
钩子。
manager.updateOptions()
类型:(newOptions: Partial<ManagerOptions>) => void
更新 manager.options
,如果涉及到一些间距和宽高的变化,会自动 format,会触发 updateOptions
钩子,你可以在这个钩子里面拿到需要更新的 options
。
manager.startPlaying()
类型:() => void
启动渲染引擎,内核会启动一个定时器轮询渲染。会触发 start
钩子。
manager.stopPlaying()
类型:() => void
关闭渲染引擎,内核的定时器也会被清除。会触发 stop
钩子。
manager.hide()
类型:() => Promise<Manager>
将当前渲染的弹幕隐藏起来,并且新渲染的弹幕也会被隐藏。会触发 hide
钩子。
manager.show()
类型:() => Promise<Manager>
将当前被隐藏的弹幕显示出来。会触发 show
钩子。
manager.nextFrame()
类型:(fn: FrameRequestCallback) => void
这是一个工具方法,回调函数会在下一帧触发。
manager.nextFrame(() => {
// .
});
manager.updateOccludedUrl()
类型:(url?: string, el?: string | HTMLElement) => void
给指定元素(默认是当前弹幕容器 manager.container.node
)添加蒙版,用来实现防遮挡功能,如果不传 url
,代表取消蒙层,你可以通过传递第二参数指定到你需要的 DOM 节点上。
注意事项
放遮挡功能需要你不停的调用 manager.updateOccludedUrl('url')
来实现蒙层的更新,蒙层照片一般基于业务后端返回(可能是通过 AI 技术来计算当前视频需要防遮挡的区域,实际情况还是要根据业务情况来实现)。
manager.render()
类型:() => void
跳过等到下次轮询,立即进行渲染,如果你发送了一个弹幕,不想等待下次轮询,想立即渲染,则可以使用此方法。
manager.unshift('弹幕内容');
// 立即渲染
manager.render();
manager.remove()
类型:(pluginName: string) => void
移除当前 manager
实例的某个插件,但是必须指定插件名字。
manager.use()
类型:(plugin: ManagerPlugin<T> | ((m: this) => ManagerPlugin<T>)) => ManagerPlugin<T>
给当前 manager
实例注册一个插件,返回插件实例,如果你在后续需要移除插件,可以保存插件的 name
,如果不传会默认分别一个 uuid
形式的 name
。
如果传递了 name
:
const plugin = manager.use({
name: 'test-plugin',
// .
});
console.log(plugin.name); // 'test-plugin'
如果不传 name
:
const plugin = manager.use({
// .
});
console.log(plugin.name); // uuid
manager.isShow()
类型:() => boolean
用来判断当前弹幕是否是在 显示
状态,通常当你调用 manager.show()
之后,调用此方法将会返回 true
。
manager.isFreeze()
类型:() => boolean
用来判断当前弹幕是否是在 冻结
状态,通常当你调用 manager.freeze()
之后,调用此方法将会返回 true
。
manager.isPlaying()
类型:() => boolean
用来判断当前渲染引擎是否正在渲染播放状态,当你调用 manager.stopPlaying()
后,会返回 false
。
manager.isDanmaku()
类型:(b: unknown) => b is Danmaku<T>
用来判断某个值是否是弹幕实例。
manager.setArea()
类型:(data: AreaOptions) => void
设置当前容器(manager.container.node
)的大小,会自动 format,使用方法可以参见 demo。
interface AreaOptions {
x?: {
start?: string | number;
end?: string | number;
};
y?: {
start?: string | number;
end?: string | number;
};
}
manager.setOpacity()
类型:(opacity: number | string) => void
设置当前弹幕和后续渲染的弹幕的透明度,如果参数是 string
,会默认转为 number
。
manager.setStyle()
类型:(key: StyleKey, val: CSSStyleDeclaration[StyleKey]) => void
设置当前弹幕和后续渲染的弹幕的 CSS 样式。
manager.setRate()
类型:(rate: number) => void
设置后续渲染的弹幕速率,是 manager.updateOptions()
的语法糖,会触发 updateOptions
钩子。
manager.setMode()
类型:(mode: 'none' | 'strict' | 'adaptive') => void
设置后续渲染的弹幕的碰撞检测算法,是 manager.updateOptions()
的语法糖,会触发 updateOptions
钩子。
manager.setGap()
类型:(gap: number | string) => void
设置后续渲染的弹幕之间的横向间距,是 manager.updateOptions()
的语法糖,会触发 updateOptions
钩子。
manager.setDurationRange()
类型:(durationRange: [number, number]) => void
设置后续渲染的弹幕之间的运动时间取值范围,是 manager.updateOptions()
的语法糖,会触发 updateOptions
钩子。
manager.setLimits()
类型:(limits: { view?: number; stash?: number }) => void
设置要限制的内存区和渲染区域弹幕数量,默认的 stash
数量是 Infinity
,也就是不限制,你可以设置为一个新的值来灵活调整。 是 manager.updateOptions()
的语法糖,会触发 updateOptions
钩子。
manager.setInterval()
类型:(interval: number) => void
设置渲染引擎的轮询时间,是 manager.updateOptions()
的语法糖,会触发 updateOptions
钩子。
manager.setDirection()
类型:(direction: 'left' | 'right') => void
设置后续渲染的方向,是 manager.updateOptions()
的语法糖,会触发 updateOptions
钩子。
manager.setTrackHeight()
类型:(trackHeight: number | string) => void
设置轨道高度。是 manager.updateOptions()
的语法糖,会触发 updateOptions
钩子。
轨道高度的设置规则
轨道高度一般要设置为大于等于弹幕高度,否则会有弹幕上下重叠的情况出现。
// 这只会存在三条轨道
manager.setTrackHeight('33%');
// 轨道高度为 100px,轨道的数目为 `容器高度 / 100px`
manager.setTrackHeight(100);