Skip to content

Latest commit

 

History

History
439 lines (306 loc) · 12.2 KB

list.md

File metadata and controls

439 lines (306 loc) · 12.2 KB

List对象的相关方法

List对象的方法调用暂不支持链式语法。

目录

Demo

示例:弹幕-时刻列表

创建列表

danmaku.list.new(listName)
  • listName - 待创建的列表名称

要使用列表,需要先创建列表,不是嘛!


删除列表

danmaku.list.del(listName)
  • listName - 待删除的列表名称

列表不要了就用这个方法删了罢


切换到某个列表

danmaku.list.use(listName)
  • listName - 待切换的列表名称

接下来的方法都必须要先通过此方法“切换到”列表中才能使用。

借用一下数据库管理系统的use


向当前列表中添加弹幕

danmaku.list.addDm(dmData, time)
  • dmData - 待添加的弹幕数据

  • time - 弹幕出现的时刻,单位为毫秒(ms)

  • 返回值:弹幕在列表中代号danmakuSerial

使用前提:使用use()方法切换到了列表中

dmData

取值为一个对象,包含一条弹幕的数据。

示例对象:

{
    text: '', // 弹幕内容
    reset_styles: false, // 是否在设置样式前重置样式,否则继承之前的样式
    styles: {...}, // 弹幕样式
    created: null // 同danmaku.create的创建后回调created()
    callback: null // 同danmaku.create的弹幕结束后回调callback()
}

time

取值为一个整数,单位为毫秒(ms),代表弹幕出现的时刻。

示例

比如在955ms处插入一条蓝色弹幕,并在创建该弹幕时重置样式:

danmaku.list.addDm({
    text: '这是一条逆向滚动弹幕',
    reset_styles: true,
    styles: {
        color: 'blue'
    }
}, 955);

从当前列表中移除弹幕

danmaku.list.delDm(danmakuSerial)
  • danmakuSerial - 待从当前列表中移除的弹幕代号

  • 返回值:布尔值true/false,代表是/否移除成功

使用前提:使用use()方法切换到了列表中

danmakuSerial

取值为一个字符串,代表当前列表中某条弹幕的代号。

弹幕代号在用addDm()方法添加弹幕时会返回。


根据时刻从当前列表中创建弹幕

danmaku.list.tick(time)
  • time - 需要检查的时刻,单位为毫秒(ms)

使用前提:使用use()方法切换到了列表中

光在列表中添加了弹幕,该怎么让这些弹幕被创建出来捏?这就不得不提到咱们的tick()方法了!

通过调用该方法,程序会在列表中寻找在time时刻(或附近)的弹幕,并创建命中的弹幕。

为什么还加了一小句“或附近”呢?看接下来这一个方法吧!


调整当前列表的时刻不确定度

danmaku.list.uncertainty(time)
  • time - 不确定时间段,单位为毫秒(ms)

  • 每一个列表默认时刻不确定度200ms

使用前提:使用use()方法切换到了列表中

上面的tick()方法会搜索某一时刻的弹幕并加以创建。

实际使用中,媒体的时间精确度可能达不到毫秒级,但弹幕时刻精确到了毫秒,这就导致如果tick(媒体时刻)的话,可能有些弹幕不会被创建出来。

因此引入了时刻不确定度。

图解

danmaku.list.uncertainty(0);
danmaku.list.tick(200);

这个时候仅搜索在时刻200ms处的弹幕,图中的弹幕2会被创建:

danmakuTickUncertainty1-2022-08-19


danmaku.list.uncertainty(45);
danmaku.list.tick(200);

这个时候搜索的是一段时间范围内200 ± 45 ms )的弹幕,图中的弹幕2弹幕3会被创建:

danmakuTickUncertainty2-2022-08-19


顾虑

骚年,你是否在顾虑这种情况?

searchRangeOverlap1-2022-08-20

我超,两次tick过近了,但uncertainty指定的弹幕搜索范围比较大,两次的搜索范围发送了重叠!这怎么整?

哈哈,实际上咱考虑到了这点,发生重叠情况的时候会自动调整搜索范围,所以不用担心的啦~

searchRangeOverlap2-2022-08-20

建议

在网页媒体中使用弹幕列表时,你可能会用到timeupdate事件:

video.addEventListener('timeupdate', function(e) {
    let currentMilli = Math.round(e.target.currentTime * 1000);
    danmaku.list.tick(currentMilli);
});

按照MDN文档的说明,基本上能保证该事件每秒被触发4-66次,大概每两次事件触发之间是15ms-250ms的时间间隔。

因此咱建议在这里设置时刻不确定度为300ms-500ms,这样能最大程度上保证弹幕的创建。

如果timeupdate实在不确定性太大了,你其实可以使用setInterval()定时tick(),只不过需要手动处理暂停/播放相关的事件。


往当前列表中载入一批弹幕

danmaku.list.load(danmakuArr)
  • danmakuArr - 待载入的包含弹幕数据的数组

  • 返回值:布尔值true/false,代表是/否载入成功

使用前提:使用use()方法切换到了列表中

当弹幕数量很大时,使用addDm()方法一条一条地添加弹幕到列表中实在是太麻烦了,因此有了这个load()方法,将一批弹幕一次性添加到列表中。

danmakuArr

取值为一个数组,这个数组的每一个元素是一个弹幕数据对象

弹幕数据对象示例如下:

{
    time: 0, // 弹幕出现的时刻,单位为毫秒(ms)
    text: '', // 弹幕内容
    reset_styles: false, // 是否在设置样式前重置样式,否则继承之前的样式
    styles: {...}, // 弹幕样式
    created: null // 同danmaku.create的创建后回调created()
    callback: null // 同danmaku.create的弹幕结束后回调callback()
}

danmakuArr数组示例:

[
    {
        time: 1098,
        text: '这是一条无描边,底部悬停的绿色弹幕',
        styles: {
            color: 'green',
            life: 4000,
            outline: false,
            type: 'bottom',
            'bottom_space': 30
        }
    },
    {
        time: 1072,
        text: '这是一条随机黄色弹幕',
        styles: {
            color: 'yellow',
            life: 4000,
            outline: false,
            type: 'random',
            'bottom_space': 2
        }
    }
]

使用技巧:载入弹幕js文件

创建一个JavaScript文件作为弹幕数据文件,可以这样写:

const myList = [ // 这里咱就放两条测试弹幕
    {
        time: 2000,
        text: '测试弹幕1'
    },
    {
        time: 1002,
        text: '测试弹幕2'
    }
]

将这个文件命名为myList.js

在页面中载入这个文件中的弹幕数据,可以这样写:

<div id="danmaku-container"><!--弹幕容器--></div>
<script src="./myList.js"></script> <!--此时myList变量暴露到全局-->
<script src="./N.min.js"></script> 
<script>
const danmaku = new NDanmaku('danmaku-container');
danmaku.list.new('test'); // 新建列表test
danmaku.list.use('test'); // 切换到列表test
danmaku.list.load(myList); // 载入myList到列表test中
</script>

使用技巧:载入弹幕json文件

创建一个JSON文件作为弹幕数据文件,可以这样写:

[ // 这里咱就放两条测试弹幕
    {
        "time": 2000,
        "text": "测试弹幕1"
    },
    {
        "time": 1002,
        "text": "测试弹幕2"
    }
]

将这个文件命名为myList.json

在页面中载入这个文件中的弹幕数据,可以这样写:

<div id="danmaku-container"><!--弹幕容器--></div>
<script src="./myList.js"></script> <!--此时myList变量暴露到全局-->
<script src="./N.min.js"></script> 
<script>
const danmaku = new NDanmaku('danmaku-container');
danmaku.list.new('test'); // 新建列表test
danmaku.list.use('test'); // 切换到列表test
fetch('./myList.json')
    .then(res => res.json())
    .then(data => danmaku.list.load(data)); // 载入myList到列表test中
</script>

导出当前列表

danmaku.list.export(outputName, fileType = 'js', download = false)
  • outputName - 输出的列表名,同时也是不包括扩展名的文件名

  • fileType - 输出的文件类型,可选值为jsjson,默认为js

  • download - 是否触发浏览器文件下载,默认为false

  • 返回值:文件内容字符串,如果失败了则为空字符串''

使用前提:使用use()方法切换到了列表中

这个方法可以说和load()是反着来的,它可以将当前列表导出为字符串/文件。

outputName

取值为一串字符串,代表输出的列表名

值得注意的是,传入这个参数时有一定限制:传入的字符串必须满足JavaScript的变量命名规则

简单说来,就是:字符串每个字符只能是字母、数字、美元符号$、下划线_,且首个字符不能是数字。

fileType

  • 默认值: 'js'

  • 可选值: 'js''json'

取值为一串字符串,代表导出的文件类型。根据文件类型不同,最终程序生成的文件内容也不同。

对于.js文件来说,导出的时候支持导出列表中弹幕的回调函数;但是对于.json文件来说是肯定不支持这点的。

download

  • 默认值: false (默认不触发下载)

取值为一个布尔值true/false

如果为true,程序会将文件内容写入文件,并触发浏览器下载。文件名为 outputName + 后缀。

展示:导出的js文件内容

const testDm = [
    {
        "text": "这是一条蓝色弹幕",
        "styles": {
                "life": 7000,
                "color": "blue",
                "reverse": false,
                "bottom_space": 2,
                "type": "scroll",
        },
        // 如果导出.js文件,是支持导出回调函数的!
        "created": (element, id) => { 
            element.onmouseover = () => {
                dmCon.pause(id);
            }
            element.onmouseout = () => {
                dmCon.resume(id);
            }
        },
        "time": 1001,
    },
    {
        "text": "测试弹幕2",
        "time": 2002,
    },
]