JS 的平凡之路 學習人氣眼中的效果(中)

2021-09-11 09:56:27 字數 3244 閱讀 3565

這一節簡單的模仿一下人氣眼中的無重疊彈幕效果,也不賣關子了,下一節模仿頭部的標籤切換效果

一談到彈幕相信大家多不陌生,平時看直播,那彈幕可是看的很歡啊。

人氣眼中的彈幕可能數量比較少的原因,是一種不重疊的彈幕。先看一下實現的效果:

無重疊彈幕效果

當你決定看下文之前,你需要注意幾點:

在canvas的api中並沒有圓角矩形的繪製方法,所以我們得自己寫乙個繪製圓角矩形的方法,一說到圓角矩形,對於我們前端可以說是小菜一碟了,border-radius早就用爛了:

矩形的圓角

由上面這幅圖,想必繪製圓角矩形的思路已經有了。這裡我們可以通過canvas中的弧線和直線組合成圓角矩形(這裡我就不過多的設定各個角的半徑了):

// ********************=

// canvas 圓角矩形的繪製

// ********************=

// @param x 左上角的x座標

// @param y 左上角的y座標

// @param w 寬度

// @param h 高度

// @param r 圓角半徑

// @param bg 背景顏色

barrage.prototype.drawroundrect = function(options) = options;

const context = this.context;

context.beginpath();

context.fillstyle = bg;

//左上角

context.arc(x + r, y + r, r, math.pi, math.pi * 3 / 2);

context.lineto(x + w - r, y);

//右上角

context.arc(x + w - r, y + r, r, math.pi * 3 / 2, 0);

context.lineto(x + w, y + h - r);

//右下角

context.arc(x + w - r, y + h - r, r, 0, math.pi / 2);

context.lineto(x + r, y + h);

//左下角

context.arc(x + r, y + h - r, r, math.pi / 2, math.pi);

context.lineto(x, y + r);

context.fill();

}複製**

這裡需要注意的是beginpath方法,這通常是新手的乙個坑:

這裡你可以實驗一下下面的例子:

context.strokestyle = "#fff";

context.rect(10,10,100,100);

context.stroke();

context.beginpath(); //去掉這段** 會導致重複繪製上面生成的四個子路徑

context.strokestyle = "#000";

context.rect(200, 200, 100, 100);

context.stroke();複製**

很巧的是,在canvas中提供計算文字寬度的方法,需要注意的是:

// ***************====

// 計算文字寬度

// ***************====

barrage.prototype.gettextwidth = function(font, text) 複製**

很遺憾的是,這裡並沒有獲取高度的屬性。。。。

上面我們已經知道了繪製圓角矩形和測量文字的寬度了,這裡我們只需要繪製文字即可,而你需要注意的是合理的利用textalign和textbaseline將文字調整到合適的位置,這裡我將文字居中於圓角矩形內部:

context.textbaseline = "middle";

context.textalign = "center";

context.filltext(text, x + width / 2, y + h / 2);複製**

對於這一條,我們一步步來:

1、初始化資料的基本資訊

初始化每個資料的字型、位置、速度等基本資訊,接下來繪製多需要這些引數,這些資料存放在data陣列中。

2、劃分車道

無重疊彈幕和道路上行駛的車輛類似,我們需要劃分車道,讓它們有序的運作在各自的車道中:

const pathheight = 10 + vp * 2 + size,

pathnumber = math.floor(h / pathheight);複製**

3、彈幕的狀態區分

彈幕我們可以區分為待顯示的彈幕、即將顯示的彈幕、未完全顯示的彈幕、完全顯示的彈幕和顯示完成的彈幕。這裡我們還需要宣告activearray儲存未完全顯示的彈幕和完全實現的彈幕,nextbarrage儲存即將顯示的彈幕。

4、待顯示彈幕

我們的彈幕是從左邊發射的,所以當乙個彈幕完全顯示出來,這個「車道」應該就要新增新的彈幕了:

// 部分**

if (item.x + item.w < width && item.status === 0) 複製**

5、新增待顯示彈幕

動畫執行的每一幀我們需要將待顯示彈幕加入到activearray陣列當中:

if (next.length > 0 && data.length > 0) 複製**
這裡的200並不是乙個隨意的數,因為我們在設定速度時,是設定1~1.25的隨機數,所以你建立乙個方程也就解出兩個彈幕之間的最小安全距離了。

6、動畫的暫停和恢復

暫停和恢復的根本就是要儲存暫停的繪製狀態,這裡可以通過canvas的getimagedata和putimagedata實現:

// **********====

// 動畫暫停與恢復

// **********====

barrage.prototype.pause = function () else

}複製**

到這裡,簡單的彈幕功能就完成了。

參考書籍: 《html5 canvas核心技術》

源**

重構構建的平凡之路

剛開始做前端的時候,一直以為切好頁面是重構的全部職責,在切好頁面的前提,增加頁面互動,這樣已經能到重構的頂峰。直到進入公司後發現參與的專案都有兩個特點,專案複雜和參與人數的多,發現傳統的方法已經不適用。主要介紹自己重構構建經歷,如有問題歡迎指教!乀 乀 這裡介紹自己以往傳統重構的方法容易暴露的缺點。...

重構構建的平凡之路

剛開始做前端的時候,一直以為切好頁面是重構的全部職責,在切好頁面的前提,增加頁面互動,這樣已經能到重構的頂峰。直到進入公司後發現參與的專案都有兩個特點,專案複雜和參與人數的多,發現傳統的方法已經不適用。主要介紹自己重構構建經歷,如有問題歡迎指教!乀 乀 這裡介紹自己以往傳統重構的方法容易暴露的缺點。...

十年牧碼,我的平凡之路

我是乙個有著十年碼齡的無證程式設計師,如果算上996那就更長了。我有讀故事的喜好,別人的艱辛 遭遇 苦難,往往能化為我生活的勇氣和前進的動力。今天我想講講自己的故事,它雖不夠精彩和離奇,但卻如同那一行行 平淡 樸素而真實。平凡人的奮鬥 掙扎 彷徨,往往最能打動人心,因為有自己生活的影子。本人80後,...