年前,粒子動畫席卷了網絡,并成功地為自己開辟了一個利基市場。當前對具有高科技氛圍和幾何裝飾的設計的巨大癡迷使它們成為當今更受歡迎的解決方案之一。
使用粒子動畫給人留下深刻印象
隨著時間的推移,技術成熟了。從散落在畫布上的雜亂無章的小白點,它變成了一種潛力巨大的工具。這不是什么特別的東西,但它有一定的令人驚嘆的因素。此外,它完美地為高科技、幾何和商務美學做出了貢獻——自然而然地完成了它們。
前提是:粒子動畫要給人留下深刻印象。而且,開發人員始終堅持這一假設,充分利用它。讓我們考慮一下這個解決方案的真正粉絲創建的一些驚人的代碼片段。
NO.1 Justin Windle 的 30,000 個粒子
這里的標題不言自明。船上有 30,000 個粒子,您會期待一些宏偉的東西。賈斯汀溫德爾當然達到了我們的期望。他的概念令人難以置信。用你的鼠標到處玩。物理學只是例外。這個版本的粒子動畫在開發者中很受歡迎,盡管規模沒有那么大。
NO.2 Alex Safayan 在水中的魚
Alex Safayan 提出了幾乎相同的解決方案,但在這種情況下,粒子越來越大。鼠標光標也將這些點推開,形成帶有微妙漣漪效果的痕跡。動畫的行為讓人想起魚靠近水面時的運動。注意物理學:點之間的相互作用是經過深思熟慮的。
獲得 2017 年度最受關注項目獎的 Plankton 無疑是值得關注的。該項目不僅著迷于想法,還著迷于實現。從像手套一樣適合這里的微妙色彩到看起來令人難以置信的自然的華麗行為,Marco Dell'Anna 對細節有著敏銳的洞察力。
我喜歡這里華麗的復古氛圍、霓虹燈和華麗的色彩。很難把你的眼睛從它身上移開。Stardust 是設計和編碼的共生體,是一部鼓舞人心的杰作。
Akimitsu Hamamuro 邀請您在他的游樂場添加所謂的“重力點”。它們侵入點的混亂運動,像磁鐵一樣拉動它們。雖然它們不扮演軌道中心的角色;然而,它們形成了迫使粒子向其方向移動的焦點。
如今,球體是英雄區域非常流行的風格選擇。Nate Willey 對這一趨勢的看法令人印象深刻。由于微小的顆粒,球體看起來很脆弱,同時由于經過深思熟慮的行為而堅固。他分解和重新形成球體的程序非常棒。
Kevin Rajarm 汲取了粒子動畫的美麗和優雅,并用Three.js的強大來增強它,帶來了一個精致但真正復雜的概念。令人驚嘆的海浪景色讓人感覺未來主義、人工和迷人。
還有更令人印象深刻的使用粒子動畫的方法。讓我們走出常規,開箱即用地思考:這種方法很容易使標識和字母等元素受益。
Interactive Particle Logo 就是一個典型的例子。它看起來像是上面提到的 Justin Windle 片段的重新設想的解決方案。雖然沒有 30,000 個點,但它由數量驚人的粒子組成,巧妙地組成了“CODEPEN”這個詞。這是該概念找到實際用途的案例之一。
Louis Hoebregts 在這支筆中提供了先前解決方案的彩色版本。這里的文本是由一千個彩色實心圓圈組成的,這些圓圈通過與上一個示例相同的交互性來豐富。
雖然這不是一個戲劇性的入口,但它有一些令人著迷的東西。流暢的動畫慢慢揭開人物的面紗,點燃我們的興趣。這個概念有某種神秘的風格,類似于“陌生人”的介紹。
這是Marco Dell'Anna的又一杰作。這一次,粒子動畫參與塑造了著名的耐克標志。從晦澀、半透明到明快、立體,動畫逐漸暴露了標志,不顯眼地抓住了整體的注意力。
粒子動畫是越小越好的情況之一。點越小,可以實現的效果就越令人印象深刻。一方面,由于涉及幾何和物理,它看起來很復雜。另一方面,由于精致的形狀,它看起來脆弱而微妙。這種獨特的融合使粒子動畫與眾不同且引人注目。
粒子動畫在企業網站建設中的運用案例
圖片來源:素馬設計
習canvas,javascript的小伙伴,可以跟著我這篇文章的思路一起做一個小效果出來,代碼都齊全了。
這里還是要說一下我的前端學習群:230354270,從我一個到現在的都是看我每一篇文章來的,可以說都是我們大前端的學霸啊,不定期分享干貨。想學到東西的都可以來,歡迎初學和進階中的小伙伴
首先看一下源圖和轉換成粒子效果的對比圖:
左側圖片為源圖,右側圖片為粒子效果圖。該效果是在Canvas畫布上制作的。將圖片制作成粒子效果相對而言是比較簡單的。重點了解兩個知識點即可
1:圖片是通過image對象形式繪制在畫布上的,然后使用Canvas的getImageData接口,獲取圖像的像素信息。
var imageData=ctx.getImageData(x, y, width, height);
參數說明:x,y為畫布上的x和y坐標
width,height為獲取指定區域圖像的信息
返回值說明:imageData為返回值,它是一個對象,包含三個屬性
2:了解像素區域數據的排布說明,以上獲取的圖片數據像素信息(imageData對象中的data屬性)為RGBA整型的一維數組數據。一個像素是有4個值(R,G,B,A)組成的。也就是說,數組信息每四個為一個像素點。因此,有以下規則,
第一個像素信息為:RGBA(data[0],data[1],data[2],data[3])
第二個像素信息為:RGBA(data[4],data[5],data[6],data[7])
.....
第N個像素信息為: RGBA(data[(n-1)*4],data[(n-1)*4+1],data[(n-1)*4+2],data[(n-1)*4+3])
.....
另外,像素區域既然是一個區域,它是有寬和高的。上面的推算公式適合單獨一行使用定位一個像素點。所以計算像素點時要考慮到在整個圖像區域內定位:
以上圖為例。圖像的寬和高都為200,如果按照每一個像素為一行一列時。則該圖像共有200行,200列。所以要取得 i 行第 j 列的像素初始位置信息為:
var pos =[( i-1 )*200]+( j-1 )]*4;
其中,公式中的 i 表示行數,j 表示列數。200為圖像的寬度。
demo代碼:
上面如果不理解, 對照代碼運行一下試試理解吧:
這次沒能為粒子加上炫酷的動態效果~~下次補上,找一些算法就可以粒子動起來的,有興趣可以做做看~
以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助
整個效果的功能都完成了
如果大家想學習canvas,JavaScript,可以加群:230354270 群里面有每天都會上傳視頻供大家學習,歡迎學習交流的小伙伴過來一起學習交流!
前幾天在整理書簽時,發現收藏了好多寶藏網站,寶藏項目,就光說文字效果,就讓諸位大佬玩出了一萬個花樣,所以小包準備跟大家一起來分享和學習這些異彩紛呈的創意和寫法。
該文作為《文字到底能玩出多少花樣》的第一篇文章,首先來帶大家學習 文字粒子 的實現。
文字粒子這個創意最先源自于哪位大佬我也不知道,但我最早發現這個效果是 kennethcachia 寫的巨炫酷的文字粒子效果,每次我打開這個 demo ,我都感覺我是個審美笨比,大佬做的真炫酷,真漂亮。
下面是 shape-shifter 效果的 github 地址和 demo 演示界面:
不多說了,一起進入阿包的文字粒子效果吧。
文章最開始之前,先帶大家了解兩個 canvas 函數
語法
ctx.fillText(text, x, y, [maxWidth]);
復制代碼
參數
可以通過 font 屬性來定義字體和字號,fillStyle 屬性來定義字體顏色。
語法
ctx.getImageData(sx, sy, sw, sh);
復制代碼
參數
返回值
在基礎知識方面,我首先介紹了兩個方法: fillText 和 getImageData 。 fillText 可以在畫布上繪制文字,getImageData 可以提取畫布上一定矩形區域的像素點。也就是說,通過這兩個方法就可以提取到我們繪制的文字的像素數據。那剩下的工作就是怎么處理這些像素數據,繪制對應運動粒子就可以。
下面來分析一下具體實現思路:
設立配置項 options 和 textOptions ,分別存放畫布的寬高、速度等信息和副畫布文字的配置。
const options = {
width: 400,
height: 400,
speed: 10
};
const textOptions = {
words: "戰場小包",
font: "200px fangsong",
};
復制代碼
主畫布已經通過 標簽添加至頁面中,因此只需要配置它的 width 與 height ,為了方便展示,將 canvas 寬高設置為瀏覽器寬高
function pointCanvas(canvas, { width, height }) {
canvas.width = width;
canvas.height = height;
ctx = canvas.getContext("2d");
return ctx;
}
// pointCavas(canvas, options)
復制代碼
副畫布的創建也非常簡單,只需要通過 JavaScript 創建一個 canvas 節點,配置副畫布的寬高(與主畫布相同),不需要添加到 dom 中。
副畫布與主畫布的寬高保持一致,這樣副畫布中的像素點,就可以對應到主畫布中的像素位置,無需進行轉換
function createVitualCvs({ width, height }) {
const vitualCvs = document.createElement("canvas");
vitualCvs.width = width;
vitualCvs.height = height;
let vitualCxt = vitualCvs.getContext("2d");
initCanvas(vitualCxt, options, textOptions);
return getFontInfo(vitualCxt, options);
}
復制代碼
設置文字屬性,通過 fillText 繪制文字。通過 (canvas.width - measure.width) / 2 保證在畫布中間繪制文字。
measureText 可以獲取到文字的寬高,更詳細的參考鏈接: measureText
function initCanvas(ctx, { width, height }, { font, words }) {
ctx.font = font;
const measure = ctx.measureText(words);
ctx.fillText(words, (width - measure.width) / 2, height / 2);
}
復制代碼
每個粒子有以下屬性:
同時還具備兩個方法:
這里給出 draw 和 update 方法代碼
draw() {
ctx.beginPath();
ctx.fillStyle = this.color;
ctx.arc(this.mx, this.my, this.radius, 0, Math.PI * 2, false);
ctx.fill();
this.update();
}
// 我這里的 update 比較簡單,如果想要更復雜更炫酷的效果,可以使用貝塞爾曲線
update() {
this.mx = this.mx + (this.x - this.mx) / this.speed;
this.my = this.my + (this.y - this.my) / this.speed;
}
復制代碼
通過 getImageData 獲取副畫布的像素信息,getImageData 返回值中對每個像素點存儲 RGBA 四方面信息,因此每四個數組元素代表一個像素點,可以通過 Alpha 來判斷該像素點是否存在文字。
function getWordPxInfo(ctx, { width, height }) {
let imageData = ctx.getImageData(0, 0, width, height).data;
const particles = [];
for (let x = 0; x < width; x += 4) {
// 為了粒子效果出現,間隔選點
for (let y = 0; y < height; y += 4) {
// 判斷當前像素點是否有文字
const pxAlphaIndex = (x + y * width) * 4 + 3;
if (imageData[pxAlphaIndex] > 0) {
particles.push(
new Particle({
x,
y,
})
);
}
}
}
return particles;
}
復制代碼
動畫是通過 requestAnimationFrame 實現,每一幀清空畫布,重新繪制所有的粒子。
requestAnimationFrame學習: 【今天你更博學了么】一個神奇的前端動畫 API requestAnimationFrame
function init(points, { width, height }) {
ctx.clearRect(0, 0, width, height);
points.forEach((value) => {
value.draw();
});
const timer = window.requestAnimationFrame(function () {
init(points, options);
});
}
復制代碼
大功告成,摸魚成功。
傳送門: 文字粒子
*請認真填寫需求信息,我們會在24小時內與您取得聯系。