jQuery實(shí)現(xiàn)簡(jiǎn)單彈幕效果
本文實(shí)例為大家分享了jQuery實(shí)現(xiàn)彈幕效果的具體代碼,供大家參考,具體內(nèi)容如下
話不多說吧,直接看效果吧:

主要思路
其實(shí)彈幕的主要思路很簡(jiǎn)單,就是將div從右向左移動(dòng),直到完全移除屏幕之后,將當(dāng)前div從body中移除,這里我采用了面向?qū)ο蟮乃枷雭?lái)處理,具體js代碼如下:
JS
/**
* 彈幕
*/
$(function () {
function BarrageManager (options) {
this.opts = {
url : './res/danmu.json',
loadDelay : 5000 , // 輪詢時(shí)間間隔
}
$.extend( this.opts , options);
this.bc = new BarrageCollection();
}
BarrageManager.prototype.load = function () {
var self = this ;
$.getJSON(self.opts.url , function (data) {
if(data.data.length > 0) {
for(var i = 0 ; i < data.data.length ; i++) {
var item = data.data[i] ;
self.bc.add(new Barrage({
id:item.id,
name:item.fromUserName,
text:item.content,
icon:item.fromUserIcon ? item.fromUserIcon : './images/head-icon.png'
}));
}
self.loop();
}
});
}
BarrageManager.prototype.loop = function () {
var len = this.bc.mq.length , self = this ;
while (len--) {
this.bc.mq[len].start(this.bc , len);
}
setTimeout(function () {
self.load();
} , this.opts.loadDelay);
}
function BarrageCollection () {
this.mq = [] ;
}
BarrageCollection.prototype.add = function (barrage) {
this.mq.push(barrage);
}
BarrageCollection.prototype.remove = function (barrage) {
var index = this.mq.findIndex(function (item) {
return barrage.opts.id == item.opts.id ;
});
if(index != -1) {
this.mq.splice(index , 1);
}
barrage.opts.$el.remove();
}
function Barrage (options) {
this.opts = {
$el : null ,
left : 0 ,
bgColor : [Math.floor(Math.random()*255),Math.floor(Math.random()*255),Math.floor(Math.random()*255)] ,
offset : 50 , // 使彈幕完全移出屏幕外
duration : 10000 , // 彈幕從右往左移動(dòng)的時(shí)間
delayTime : 1000 , // 彈幕延遲移動(dòng)時(shí)間
};
$.extend( this.opts , options);
this.init();
}
Barrage.prototype.init = function () {
this.opts.$el = $("<span><img src="+this.opts.icon+"><em>"+this.opts.name+":</em>"+this.opts.text+"</span>");
var top = Math.ceil(Math.random() * 10 );
this.opts.$el.css({
top:top * 40 +'px',
backgroundColor:"rgb("+this.opts.bgColor.join(",")+")"
});
var delay = Math.ceil(Math.random()*10);
this.opts.delayTime *= Math.abs(delay - 5);
var dur = Math.ceil(Math.random() * 10);
this.opts.duration += dur * 1000 ;
$('#barrage-wrapper').append(this.opts.$el);
this.opts.left = -this.opts.$el.width() - this.opts.offset ;
}
Barrage.prototype.start = function (bc , index) {
var self = this ;
bc.mq.splice(index , 1);
setTimeout(function () {
self.move(bc);
}, this.opts.delayTime);
}
Barrage.prototype.move = function (bc) {
var self = this ;
this.opts.$el.animate({
left:this.opts.left+'px'
} , this.opts.duration ,"linear" , function () {
bc.remove(self);
});
}
new BarrageManager().load();
});
代碼分析
首先我定義了3個(gè)類
- BarrageManager : 彈幕管理類
- BarrageCollection :彈幕集合類
- Barrage : 彈幕類
BarrageManager 中的方法:
- load : 加載彈幕數(shù)據(jù)
- loop: 間隔指定時(shí)間循環(huán)加載數(shù)據(jù)
load 方法就不加以說明了,主要講一下 loop方法:
BarrageManager.prototype.loop = function () {
var len = this.bc.mq.length , self = this ;
while (len--) {
this.bc.mq[len].start(this.bc , len);
}
setTimeout(function () {
self.load();
} , this.opts.loadDelay);
}
通過while循環(huán),將彈幕集合中所有彈幕對(duì)象取出,并調(diào)用他的start方法,開啟彈幕動(dòng)畫,然后每間隔指定時(shí)間再去調(diào)用一次load方法,生成新的彈幕對(duì)象,并添加到彈幕結(jié)合中。
PS: 這里其實(shí)最好使用socket,然服務(wù)端主動(dòng)推送,而不是客戶端通過http進(jìn)行輪詢,我這里主要講解實(shí)現(xiàn)彈幕的思路,至于怎么獲取數(shù)據(jù),這個(gè)大家可以去優(yōu)化,不過我可以推薦一個(gè)socket第三方包 socket.io 這個(gè)庫(kù)挺厲害的,大家可以去看看。
BarrageCollection 中的方法:
- add : 添加彈幕
- remove: 移除彈幕
BarrageCollection 中的方法其實(shí)就是對(duì)數(shù)據(jù)進(jìn)行了一層包裝操作而已,其實(shí)也可以不要這一層。代碼也相對(duì)簡(jiǎn)單,我就不多說了(嘻嘻,大家現(xiàn)在水平都不錯(cuò),一眼就能看明白對(duì)吧)。
Barrage 中的方法:
- init : 初始化參數(shù)
- start: 開啟彈幕移動(dòng)的動(dòng)畫
- move: 執(zhí)行彈幕移動(dòng)動(dòng)畫
其實(shí)Barrage中的方法也相對(duì)簡(jiǎn)單,首先在Barrage中定義了它所需要的屬性,在new Barrage() 的時(shí)候,傳遞參數(shù),然后調(diào)用init方法進(jìn)初始化,生成dom,設(shè)置彈幕塊當(dāng)前的背景顏色,以及屏幕的垂直位置如下:
var top = Math.ceil(Math.random() * 10 );
this.opts.$el.css({
top:top * 40 +'px',
backgroundColor:"rgb("+this.opts.bgColor.join(",")+")"
});
隨機(jī)生成top值,為了避免彈幕塊在同一垂直位置出現(xiàn)。
然后設(shè)置彈幕塊從右往左移動(dòng)時(shí)所需要的時(shí)間,以及延遲開始移動(dòng)的時(shí)間
// 設(shè)置彈幕塊延遲移動(dòng)的時(shí)間 var delay = Math.ceil(Math.random()*10); this.opts.delayTime *= Math.abs(delay - 5); // 設(shè)置彈幕塊移動(dòng)的時(shí)長(zhǎng) var dur = Math.ceil(Math.random() * 10); this.opts.duration += dur * 1000 ;
設(shè)置這兩個(gè)參數(shù),是為了不讓彈幕塊在進(jìn)入屏幕的時(shí)候同時(shí)出現(xiàn),并且如果移動(dòng)速度相同,就感覺整體在一起移動(dòng),效果不太好。
最后將彈幕塊的dom添加在html中,并計(jì)算出left值
$('#barrage-wrapper').append(this.opts.$el);
this.opts.left = -this.opts.$el.width() - this.opts.offset ;
left值也就是彈幕塊要移動(dòng)的距離,這里我加了一個(gè)偏移量offset(這個(gè)隨意),可能我css設(shè)置有點(diǎn)問題,如果不加這個(gè),彈幕塊在還沒完全移出屏幕的時(shí)候就從html中移除了,會(huì)突然變沒,有點(diǎn)突兀,因此加了一個(gè)偏移量,保證彈幕塊完全移出屏幕
當(dāng)彈幕塊都初始化完成了之后,調(diào)用start方法,開始移動(dòng)
Barrage.prototype.start = function (bc , index) {
var self = this ;
bc.mq.splice(index , 1);
setTimeout(function () {
self.move(bc);
}, this.opts.delayTime);
}
move方法則是使用jq的animate方法來(lái)實(shí)現(xiàn)dom的移動(dòng)動(dòng)畫
Barrage.prototype.move = function (bc) {
var self = this ;
this.opts.$el.animate({
left:this.opts.left+'px'
} , this.opts.duration ,"linear" , function () {
bc.remove(self);
});
}
在彈幕完全移出屏幕時(shí),也就是動(dòng)畫結(jié)束時(shí),將當(dāng)前彈幕dom從html中移除。整體的思路也就是這樣,是不是很簡(jiǎn)單,不過在這里我對(duì)start方法中的這段代碼進(jìn)行說明一下:
bc.mq.splice(index , 1);
我在開始動(dòng)畫之前,首先將當(dāng)前彈幕對(duì)象從BarrageCollection 中移出了,按理說應(yīng)該在彈幕完全移出屏幕時(shí)才執(zhí)行這個(gè)操作才對(duì),其實(shí)是因?yàn)椋?dāng)我們?cè)谡{(diào)用 BarrageManager 中的loop方法循環(huán)獲取彈幕數(shù)據(jù)的時(shí)候,會(huì)改變BarrageCollection 中彈幕集合的長(zhǎng)度,這時(shí)候會(huì)造成傳遞到 start方法中的index值可能會(huì)大于集合的長(zhǎng)度,從而報(bào)錯(cuò),因此我在每次調(diào)用start的時(shí)候就將當(dāng)前彈幕對(duì)象從集合中移除,確保集合每次都是空的,從而不會(huì)有其他影響。
源碼下載:jQuery實(shí)現(xiàn)簡(jiǎn)單彈幕效果
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
使用jQuery監(jiān)聽掃碼槍輸入并禁止手動(dòng)輸入的實(shí)現(xiàn)方法(推薦)
基于jQuery的掃碼槍監(jiān)聽。如果只是想實(shí)現(xiàn)監(jiān)聽獲取條碼掃碼信息,可以直接拿來(lái)使用,如果有更多的條碼判斷處理邏輯需要自己擴(kuò)展哦2017-03-03
基于jquery實(shí)現(xiàn)的表格分頁(yè)實(shí)現(xiàn)代碼
該方法的運(yùn)用是從后臺(tái)數(shù)據(jù)庫(kù)中一次性取出所有的數(shù)據(jù),運(yùn)用Jquery把一部分?jǐn)?shù)據(jù)隱藏起來(lái),事實(shí)上數(shù)據(jù)還是全部在html頁(yè)面中2011-06-06
基于jQuery和hwSlider實(shí)現(xiàn)內(nèi)容左右滑動(dòng)切換效果附源碼下載(一)
本文結(jié)合實(shí)例給大家介紹如何實(shí)現(xiàn)內(nèi)容滑動(dòng)切換的效果,包括左右箭頭切換,無(wú)限無(wú)縫滾動(dòng),圓點(diǎn)按鈕切換,動(dòng)畫效果,自動(dòng)切換效果,效果非常不錯(cuò),感興趣的朋友前來(lái)參考實(shí)現(xiàn)代碼2016-06-06
jQuery插件實(shí)現(xiàn)靜態(tài)HTML驗(yàn)證碼校驗(yàn)
這篇文章主要介紹了jQuery插件實(shí)現(xiàn)靜態(tài)HTML驗(yàn)證碼校驗(yàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2015-11-11

