此博客不再维护,博客已迁移至 https://github.com/purplebamboo/blog/issues
文章目录
  1. 1. 思考-如何实现弹幕
  2. 2. 开始动手实现
  3. 3. 结语

好久不写博客了,罪过罪过,这几个月真是忙成狗了。最近做业务的时候需要实现个简单的弹幕效果,发现一些比较有意思的玩法,这边记录一下。

思考-如何实现弹幕

我们先抛开弹幕,来看看现实生活中的一个场景。

什么场景呢,就是一台舞台剧的拍摄过程。

我们先看看拍一个舞台剧需要准备哪些东西:

  • 首先需要一个舞台
  • 还需要有个剧本,剧本规定了这个剧该怎么演
  • 然后需要一大堆演员,每个演员要自己化妆,确定自己什么时候上场
  • 再然后需要个导演,导演负责整个流程的控制叫演员上场表演

首先我们需要知道,一场舞台剧是分好几个场次的。有的演员在第一场,有的演员在第二场,每个演员的身份装扮也都是不同的。

在开场之前,需要做些前期准备,比如舞台装扮,还有跟演员说戏。
什么是说戏呢?
导演会先让演员看剧本,先装扮好。然后跟演员说:那个xxx你是第二场上,xxx第一场。到时我会提醒你们第几场开始了,你们要注意听。

说完戏之后,舞台剧就开始演了。

每开始一个场次,导演就喊:第xx场开始了,这个场次的演员注意上场。然后演员听到后就会找到时机上场。

整个舞台剧就这样按流程表演了。

为什么要说这个例子呢,因为我发现,弹幕跟这个就是一回事。

每一条弹幕其实就是一个演员,我们再搞一个调度者导演,来控制弹幕的出场。导演的说戏其实就是每个演员添加针对导演的事件监听。

开始动手实现

为了方便,下面所有代码基于jQuery实现

我们先确定需要的元素:

1.我们需要个舞台

1
2
3
4
5
6
7
8
<div id="J_stage"></div>

<script type="text/javascript">

//舞台是全局变量
var stage = $('#J_stage');

</script>

2.我们需要个剧本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
var playList = [{
    //从何时开始
    time:0,
    //经过的时间
    duration:4292,
    //舞台偏移的高度
    top:10,
    //弹幕文字大小
    size:16,
    //弹幕颜色
    color:'#000',
    //内容
    text:'前方高能注意'
},{
    //从何时开始
    time:100,
    //经过的时间
    duration:4192,
    //舞台偏移的高度
    top:100,
    //弹幕文字大小
    size:14,
    //弹幕颜色
    color:'#333',
    //内容
    text:'我就是路过看看。。'
},{
    //从何时开始
    time:170,
    //经过的时间
    duration:6192,
    //舞台偏移的高度
    top:130,
    //弹幕文字大小
    size:16,
    //弹幕颜色
    color:'#00ff00',
    //内容
    text:'我就静静的看着你装逼。。'
},{
    //从何时开始
    time:1000,
    //经过的时间
    duration:5992,
    //舞台偏移的高度
    top:150,
    //弹幕文字大小
    size:20,
    //弹幕颜色
    color:'#ff0000',
    //内容
    text:'我和我的小伙伴都惊呆了~~'
}]

//弹幕的总时间(演出总时间)
var Time = 9000;
//检测时间间隔(每一场的时间)
var CheckTime = 1000;
//总场数
var PlayCount = Math.ceil(Time / CheckTime);

剧本很简单,包括演出的总时间,每一场的时间,还有具体的每个演员的表演内容,规定了每个演员的入场时间(time),表演的时间(duration),还有入场的位置(top),还有演员的妆容(size,color,text)

3.我们还需要演员
作为一名合格的演员,需要具备那些素质呢?
我们创建个演员的类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//构造函数,传递一个剧本片段
var Actor = function(play){
    //保存剧本的副本
    this.play = play;
    //给自己化妆
    this.appearance = this.makeUp();
    //自己走上舞台旁边准备上场
    this.appearance.hide().appendTo(stage);
}

//演员化妆,也就是最终呈现的样子
Actor.prototype.makeUp = function() {
    var appearance = $('<div style="min-width:400px;font-size:'+this.play.size +';color:'+this.play.color+';">'+this.play.text+'</div>');
    return appearance;
}

//演员上场飘过
Actor.prototype.animate = function() {
    var that = this;
    var appearance = that.appearance;
    var mywidth = appearance.width();
    //使用动画控制left
    appearance.animate({
        left:-mywidth
    }, that.play.duration,'swing',function(){
        appearance.hide();
    });
}

//演员开始表演
Actor.prototype.perform = function() {
    var that = this;
    var appearance = that.appearance;

    //准备入场,先隐藏在幕布后面
    appearance.css({
        position:'absolute',
        left: stage.width()+'px',
        top:that.play.top||0,
        zIndex:10,
        display:'block'
    });
    //确定入场偏移时间,入场表演
    //导演只会说第几场开始了,可不会还帮你具体到某个时间点,所以需要你自己计算好入场的时间。
    var delayTime = that.play.time - (that.play.session-1) * CheckTime;
    //演员需要修正自己上场的时间
    setTimeout(function(){
        that.animate();
    },delayTime)

}

演员类还是比较简单,构造函数调用后演员自己会化好妆等待入场。并且暴露出表演的方法perform。每个演员需要监听导演。当导演说了某个场次开始后,记得关注,入场表演即可。

4.好了我们还需要个导演,非常重要的调度者

导演需要具有事件机制,也就是我们常说的观察者模式,因为我们使用了jQuery,所以有现成的可以用:

1
2
//这样我们就得到了一个支持事件机制的对象。
var director = $({});

这样所有的元素都已经齐全了,下面我们开始进行戏剧的前期准备过程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

//准备舞台(这个上面其实已经说了)
var stage = $('#J_stage');
stage.css({
    position:'relative',
    overflow:'hidden'
})

//导演开始说戏过剧本
//整理playList列表,组装事件
$.each(playList,function(k,play){
    //确定演员,确定场次
    var session = Math.ceil(play.time / CheckTime);
    play.session = session;
    //剧本拿给演员,召唤一个演员
    var actor = new Actor(play);
    //演员针对导演添加监听。
    //等导演说了这个场次后,就开始叫演员表演
    director.on(session+'start',function(){
        actor.perform();
    })
})

说戏也说完了,下面就开始正式表演啦:

1
2
3
4
5
6
7
8
9
10
11
12
13
currentSession = 0;

setInterval(function(){
    //第xx场开始表演
    director.trigger(currentSession+'start');
    //从头再来一遍
    if (currentSession === PlayCount) {
        currentSession = 0;
    }else{
        currentSession++;
    }

},CheckTime);

最终结果如下:

结语

其实可做的事情还很多,后来还增加了不少功能,比如弹幕的停止,继续。以及其他一些高级功能,但是受限于篇幅,就不往下扩展了。写在端午节晚上,明天还要继续苦逼的加班,anyway端午节快乐。

文章目录
  1. 1. 思考-如何实现弹幕
  2. 2. 开始动手实现
  3. 3. 结语