您好,登錄后才能下訂單哦!
這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)碛嘘P(guān)使用jQuery怎么實(shí)現(xiàn)一個(gè)彈幕效果,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
/** * 彈幕 */ $(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è)庫挺厲害的,大家可以去看看。
BarrageCollection 中的方法:
add : 添加彈幕
remove: 移除彈幕
BarrageCollection 中的方法其實(shí)就是對(duì)數(shù)據(jù)進(jìn)行了一層包裝操作而已,其實(shí)也可以不要這一層。代碼也相對(duì)簡單,我就不多說了(嘻嘻,大家現(xiàn)在水平都不錯(cuò),一眼就能看明白對(duì)吧)。
Barrage 中的方法:
init : 初始化參數(shù)
start: 開啟彈幕移動(dòng)的動(dòng)畫
move: 執(zhí)行彈幕移動(dòng)動(dòng)畫
其實(shí)Barrage中的方法也相對(duì)簡單,首先在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í)長 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方法來實(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中移除。整體的思路也就是這樣,是不是很簡單,不過在這里我對(duì)start方法中的這段代碼進(jìn)行說明一下:
bc.mq.splice(index , 1);
上述就是小編為大家分享的使用jQuery怎么實(shí)現(xiàn)一個(gè)彈幕效果了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。