Skip to content

用于创建简单弹幕的JavaScript库 / SomeBottle's Danmaku Library

License

Notifications You must be signed in to change notification settings

SomeBottle/N.js

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

N.js

Banner

这是啥子嘞?

这是一个简单的、用于创建弹幕的浏览器JavaScript组件。咱绞尽脑汁想出的特色如下:

  • 弹幕时间支持到毫秒级别
  • 支持在屏幕中间的弹幕
  • 尽量高的弹幕可自定义度
  • 自带弹幕碰撞判断,充分利用屏幕空间
  • 链式语法
  • 自带简单的弹幕列表,可按时刻装载/创建弹幕

目录

Demo

https://ndanmaku.xbottle.top

使用它吧!

浏览器端

  1. 引入N.min.js

    在页面中引用位于本仓库dist/目录下的 N.min.js 文件。

    <script src='./N.min.js'></script>  

    或者如果jsdelivr仍然能使用的话:

    <script src='https://cdn.jsdelivr.net/npm/n-danmaku@latest/dist/N.min.js'></script>  
  2. 创建NDanmaku对象

    构造方法:

    new NDanmaku(container, prefix = '', zIndex = 'auto')
    • container - 弹幕容器元素,可以是一个字符串(元素的id),也可以是一个DOM元素对象

    • prefix - 容器弹幕的前缀,默认为空。

    • zIndex - 上述容器将被设置的z-index值,默认为auto

    详情见构造方法文档


    这里就说一下第一个参数container,这个参数代表的DOM元素就是弹幕的容器,弹幕将会在其中被创建。

    1. 你可以这样创建对象:

      const danmaku = new NDanmaku('test');

      在创建对象的时候,程序会寻找idtest的DOM元素。

    2. 你也可以这样写:

      const danmaku = new NDanmaku(document.querySelector('.test'));

      这样就是直接将一个DOM元素对象传给构造方法。

    注意:在创建对象后,上面传入的DOM元素的样式的定位属性position会被自动设置为relative

  3. 调用NDanmaku方法

    你可以调用NDanmaku对象的create()方法来创建一条弹幕:

    // danmaku就是上面创建的`NDanmaku`对象
    danmaku.create('Hello N.js!');

    💡 其他更多方法详见下方~

与模块打包器一起使用

  1. 通过npm安装

    npm install n-danmaku --save
  2. 在运用模块打包器(如webpack)的工程中使用:

    import NDanmaku from 'n-danmaku';
    
    const danmaku = new NDanmaku(container);

关于弹幕

弹幕属性

弹幕在创建的时候都会应用当前设置的弹幕属性。

现有的弹幕属性及其默认值如下:

属性键 默认值 说明
color 'white' 弹幕颜色,和CSS中的color一致
size null 弹幕字体大小,和CSS中的font-size一致,为null则程序自行计算
scale 1 弹幕基于size的缩放倍数 (比如0.5, 2) ,仅在sizenull时有效
opacity 100 弹幕透明度 (百分数)
weight normal 弹幕字体粗细,和CSS中的font-weight一致
bottom_space 2 弹幕纵向上的间距,单位是px
outline true 是否给弹幕描黑边
reverse false 弹幕是否逆向滚动,仅对滚动类弹幕有效
type 'scroll' 弹幕类型,详见这里
life 5000 弹幕生命时间,单位是ms
pointer_events true 弹幕是否接受鼠标事件
custom_css {} 自定义弹幕CSS样式
carry_sheet '' 弹幕随身携带<style>元素包含的CSS样式内容,留空则弹幕不会随身携带样式元素

custom_csscarry_sheet不同的地方就在于,custom_css是直接应用到弹幕DOM元素上的;而carry_sheet是在弹幕DOM元素中创建了一个子元素<style>,并将CSS样式内容写入到该子元素中。

关于carry_sheet

carry_sheetcustom_css的区别上面已经提到了。这里提一下carry_sheet中的特殊占位字符串。

创建对象时设置了prefix的前提下,carry_sheet中所有的占位:

[selfId]

都会被替换为弹幕DOM元素的id

举个栗子:

const danmaku = new NDanmaku(container, 'vid'); // prefix为vid
danmaku.attrs('carry_sheet',`
    #[selfId] {
        color: red!important;
    }
`);
// 比如这条弹幕DOM元素的id是 N-danmaku-vid-0
danmaku.create('test'); 

实际上这里的CSS样式文本会被替换为:

#N-danmaku-vid-0 {
    color: red!important;
}

设置属性的方法详见下方~

弹幕类型

Demo中有相应的示例

注:对于滚动弹幕来说,滚动方向的正方向是自右向左

弹幕类型 说明 是否参与碰撞检测
scroll 普通滚动弹幕 参与
midscroll 在中间滚动的弹幕 不参与
random 随机高度的滚动弹幕 不参与
top 顶部悬停弹幕 参与
bottom 底部悬停弹幕 参与
midhang 在中间悬停的弹幕 不参与
free 自由弹幕 不参与

关于自由弹幕

自由弹幕与其他类型弹幕最大的不同就在于,自由弹幕除了弹幕属性的配置之外,不会被附上任何其他样式(如animationtransformtopbottom等)。

你可以结合custom_csscarry_sheet自由发挥。

注:所有弹幕元素全都是absolute绝对定位。自由弹幕的生命期仍然受属性life控制。

对象的方法和属性

以下内容结合Demo食用更佳哦~(๑´ڡ`๑)

NDanmaku对象

  • 方法

    文档 涵盖的方法
    构造方法 constructor()
    弹幕创建方法 create()
    弹幕属性设置方法 attrs(), resetAttrs()
    弹幕生成范围设置方法 ranges(), resetRanges()
    弹幕运行状态控制方法 pause(), resume()
    弹幕清除相关方法 clear(), clearSome(), clearStyled()
    统计信息相关方法 resetStatistics()
  • 属性

    • danmaku.state

      一串字符串,代表容器全部弹幕的运行状态

      • 'paused' - 暂停状态
      • 'running' - 运行状态
    • danmaku.statistics

      相关方法能重置部分统计信息哦。

      一个对象,是容器中弹幕的统计信息。这里说明一下几个字段:

      属性 说明
      current 实时弹幕情况
      created 已经创建了多少弹幕
      global_state 全局弹幕状态(同danmaku.state
      total字样 某种弹幕的总数
      garbages字样 某种弹幕的垃圾总数
      reversed字样 某类滚动弹幕之中的逆向弹幕的总数

      garbages 垃圾数仅作参考。 弹幕元素在被删除后,程序中仍然会存留一些弹幕相关的对象,这些残留对象便被称为“垃圾”。 每次创建弹幕的时候都会触发垃圾回收器,无需担心。

      示例返回数据如下:

      点我展开示例
      {
          'created': { // 已经创建了的弹幕
              'total': 0, // 目前为止总创建弹幕数量
              'scrolling': {
                  'total': 0, // 目前为止创建的总滚动弹幕数量
                  'scroll': {
                      'total': 0, // 目前为止创建的总滚动弹幕数
                  },
                  'random': {
                      'total': 0, // 目前为止创建的总随机弹幕总数
                  },
                  'midscroll': {
                      'total': 0, // 目前为止创建的总中部滚动弹幕总数
                  }
              },
              'hanging': {
                  'total': 0, // 目前为止创建的总悬停弹幕数量
                  'top': {
                      'total': 0 // 目前为止创建的总顶部悬停弹幕数
                  },
                  'bottom': {
                      'total': 0 // 目前为止创建的总底部悬停弹幕数
                  },
                  'midhang': {
                      'total': 0 // 目前为止创建的总中部悬停弹幕数
                  }
              },
              'freeing': {
                  'total': 0, // 目前为止创建的总自由弹幕数量
              }
          },
          'current': { // 实时弹幕情况
              'total': 0, // 所有弹幕的总数
              'garbages': 0, // 所有弹幕垃圾的总数
              'global_state': 'running', // 全局弹幕状态(同danmaku.state)
              // 自由类弹幕
              'freeing': {
                  'total': 0, // 自由类弹幕数
                  'garbages': 0 // 自由类弹幕垃圾数
              },
              // 滚动类弹幕
              'scrolling': {
                  'total': 0, // 总滚动弹幕数
                  'reversed': 0, // 反向滚动弹幕数
                  'garbages': 0, // 滚动弹幕垃圾数
                  'scroll': {
                      'total': 0, // 滚动弹幕数
                      'reversed': 0, // 反向滚动弹幕数
                      'garbages': 0 // 反向滚动弹幕垃圾数
                  },
                  'random': {
                      'total': 0, // 随机弹幕总数
                      'reversed': 0, // 反向滚动随机弹幕数
                      'garbages': 0 // 反向滚动随机弹幕垃圾数
                  },
                  'midscroll': {
                      'total': 0, // 中部滚动弹幕总数
                      'reversed': 0, // 反向滚动中部滚动弹幕数
                      'garbages': 0 // 反向滚动中部滚动弹幕垃圾数
                  }
              },
              'hanging': {
                  'total': 0, // 总悬停弹幕数
                  'garbages': 0, // 悬停弹幕垃圾数
                  'top': {
                      'total': 0, // 顶部悬停弹幕数
                      'garbages': 0 // 顶部悬停弹幕垃圾数
                  },
                  'bottom': {
                      'total': 0, // 底部悬停弹幕数
                      'garbages': 0 // 底部悬停弹幕垃圾数
                  },
                  'midhang': {
                      'total': 0, // 中部悬停弹幕数
                      'garbages': 0 // 中部悬停弹幕垃圾数
                  }
              }
          }
      }

List对象

如果你想要将弹幕应用到视频、音频这些媒体上,用这个对象的方法准没错!

每个NDanmaku的对象中都自带一个List对象,包含着弹幕-时刻列表的相关操作:

danmaku.list

List对象的方法详见这个文档


FAQ

弹幕容器container中可以有其他DOM元素吗?

是可以有的,在创建对象的时候虽然传入了container对应的元素对象,但实际上程序会在这个元素中创建一个<div>元素作为弹幕层,所有弹幕都是在这个弹幕层内被创建的,因此并不会影响container中的其他元素。

值得注意的是,container对应的元素的定位属性会变更为relative(相对定位)。


如果container元素中有其他定位为absolute的元素遮挡了弹幕,怎么办?

你可以在创建对象的时候传入zIndex参数,调整弹幕层container元素内的层级,以避免这种情况。

详见构造方法的文档


每条弹幕对应的DOM元素都有独一无二的id属性吗?

有的!只不过需要在构造对象的时候指定一下prefix参数,详见构造方法的文档


如何获得弹幕自身的唯一id?

弹幕自身的唯一id(不是弹幕DOM元素的id属性)目前只能通过对象构造方法created回调函数来获得。

详见弹幕创建的文档


感谢

  • @板砖猫 - 提出了“中间”弹幕的想法

Copyright

Copyright © 2022 SomeBottle, under Apache-2.0 License.