最近聽女神說想談戀愛了,✧(≖ ◡ ≖) 嘿嘿,一定不能放過這個機會,給她來個不一樣的表白。
那麼咱們就一起來把這個粒子系統玩出花來吧
如何將一系列的粒子組成一句表白呢?
實現原理其實很簡單,canvas 中有個 getimagedata 的方法,可以得到乙個矩形範圍所有畫素點資料。那麼我們就試試來獲取乙個文字的形狀吧。
第一步,用 measuretext 的方法來計算出文字適當的尺寸和位置。
// 建立乙個跟畫布等比例的 canvas
const width = 100;
const height = ~~(width * this.height / this.width); // this.width , this.height 說整個畫布的尺寸
const offscreencanvas =document.createelement('canvas');
const offscreencanvasctx =offscreencanvas.getcontext('2d');
offscreencanvas.setattribute('width', width);
offscreencanvas.setattribute('height', height);
// 在這離屏 canvas 中將我們想要的文字 textall 繪製出來後,再計算它合適的尺寸
offscreencanvasctx.fillstyle = '#000';
offscreencanvasctx.font = 'bold 10px arial';
constmeasure=offscreencanvasctx.measuretext(textall); // 測量文字,用來獲取寬度
const size = 0.8;
// 寬高分別達到螢幕0.8時的size
const fsize=math.min(height * size * 10 / lineheight, width * size * 10 / measure.width); // 10畫素字型行高 lineheight=7 magic
offscreencanvasctx.font = `bold $px arial`;
// 根據計算後的字型大小,在將文字擺放到適合的位置,文字的座標起始位置在左下方
const measureresize =offscreencanvasctx.measuretext(textall);
// 文字起始位置在左下方
同學們注意,我要開始變形了 [推眼鏡] 。
getimagedata 獲取的畫素資料是乙個 uint8clampedarray (值是 0 - 255 的陣列),4 個數一組分別對應乙個畫素點的 r g b a 值。我們只需要判斷 i * 4 + 3 不為 0 就可以得到需要的字型形狀資料了。
// texts 所有的單詞分別獲取 data ,上文的 textall 是 texts 加一起
object.values(texts).foreach(item => );}}
// 儲存到乙個物件,用於後面的繪製
geometry.push();
})
制定場景,繪製圖形文字圖形的獲取方式以及搞定了,那麼咱們就可以把內容整體輸出了。咱們定義乙個簡單的指令碼格式。
// hsla 格式方便以後做色彩變化的擴充套件
const color1 = ;
const color2 = ;
// lifetime 禎數
const actions = [
]},
]},
], ,,,
, ]},
];
根據預設的指令碼解析出每個場景的圖形,加乙個 tick 判斷是否到了 lifetime 切換到下乙個圖形重新繪製圖形。
function draw()
this.clear();
this.renderparticles(); // 繪製點
this.raf = requestanimationframe(this.draw);
} function nextaction()
這樣咱們基本的功能已經完成了。
能不能再給力一點
說好的粒子系統,現在只是 context.arc 簡單的畫了一點。那咱們就來加個粒子系統吧。
class particle
// 設定這些粒子需要運動到的終點(下乙個位置)
setaxis(axis)
step()
getaxis2d() ;}}
大功告成!既然是 3d 的粒子,其實這上面還有不是文章可做,同學們可以發揮想象力來點更酷炫的。
還有什麼好玩的
上面是將粒子擺成文字。那咱們當然也可以直接寫公式擺出個造型。
// actions 中用 func 代替 texts
; }
}
再把剛才文字轉換形狀的方法用一下
);}}
}const p= points[~~(math.random() * points.length)]
const radius = math.min(width * 0.8, height * 0.8);
return ;}}
完美 ?
然後咱也可以用 drawimage 繪製來代替 arc 畫點。
等等!!前面的效果總覺得**不對勁,好像有些卡 。
優化小提示
1、分層。如果還需要增加一些其他的內容到 canvas 中的話,可以考慮拆出多個 canvas 來做。
2、減少屬性設定。包括 linewidth、fillstyle 等等。canvas 上下文是很複雜的乙個物件,當你調它的一些屬性設定時消耗的效能還是不少的。arc 之類的畫圖方法也要減少。
3、離屏繪製。不用 arc 畫點,要怎麼辦。上面的延遲其實就是每次畫點時都呼叫了一遍 fillstyle、arc。但是當我們繪製 drawimage 時,效能明顯會好上很多。drawimage 除了直接繪外,還能繪製另乙個 canvas,所以我們提前將這些點畫到乙個不在螢幕上的 canvas 裡就可以了。
4、減少 js 計算,避免堵塞程序,可以使用 web worker。當然咱們目前的計算完全用不上這個
我這使用了 3000 個粒子,對比下使用離屏繪製前後的幀率。
總結
現在唯一限制你的就是想象力了。大家一起去征服老闆,征服女神!
參考:
技術 外掛程式精選 炫酷粒子特效 下)
些奇妙的效果都是通過遊戲引擎中的粒子系統所創作的。製作精美,消耗低廉,帶給玩家最為震撼的視覺體驗。粒子系統常被用來製作遊戲場景中的火焰,效果,雷射束,玻璃碎片,及法術等特效。再配合以合適的音效,讓玩家擁有最為真實的遊戲感受。polyfied出品的particle playground 什麼是粒子系統...
vue 炫酷登入 vue粒子效果的登入頁實現
hello,親愛的兄弟姐妹們,時隔幾天在工作之餘,終於把登入頁面寫出來了 暫不考慮資料互動 說起這幾天的學習經歷,那真是一把鼻涕一把淚。今天我就把開發過程中用到的知識點,和踩得坑 跟小夥伴們分享一下,也給想自己動手實現乙個炫酷效果的小夥伴乙個指引。下面講下我是如何實現的。開始之前最好先理清乙個概念,...