談談文字圖片粒子化


  之前寫了談談文字圖片像素化,主要是為了將文字和圖片像素化后的坐標提取出來,而本篇所講即為像素化后的粒子化過程。

  先上一個簡單的demo -> 粒子化demo,本篇的目的就是為了講解怎樣做這樣的簡單demo(大牛請無視);同時會介紹一些優秀的demo供大家參考。

 

主要思路

  首先我們談談粒子化的主要思路。

  像素化后(不知道怎樣像素化,參考談談文字圖片像素化),我們得到了所需圖像或者文字的具體坐標,我們將它們形象地用一個個的粒子表示(這里用了圓形),得到的坐標即是粒子的最終位置。粒子的初始位置在哪里?粒子從初始位置到最終位置的運動又是如何?這些是我們可以自由發揮的。所以粒子化過程究其根本,就是怎樣表示粒子的運動過程。

 

基本准備

  • canvas自適應電腦屏幕(不出現滾條):

css部分:

body {margin:0; padding:0; wdith:100%; height: 100%}
canvas {display:block; background-color:#000}

js部分:

window.canvas = document.createElement('canvas'); 
document.body.appendChild(window.canvas); 
canvas.height = window.height = window.innerHeight;
canvas.width = window.width = window.innerWidth;

 

  • 關於像素化再補充幾句:

  像素化過程簡單描述就是將所需的文字fillText到畫布上或者將圖片drawImage到畫布上(設置一個離屏的canvas),然后利用getImagedata這個api將像素點提取出來。值得注意的是getImagedata並不會獲取背景點的像素,所以canvas的背景使用怎樣的顏色並不會影響像素點的提取。

  一般像素點的提取是根據某個像素點rgba的a值進行判斷,a值的取值是0~255(rgba當做顏色屬性賦值時a的取值是0~1),通常做法是判斷a值非0或者半透(>125)。這里我也做了個簡單的測試,當color值取black或者#000時,a值如下:

           

 

  • 關於陰影

  粒子化效果一般在黑夜最漂亮,所以背景我一般設置成黑色。如果要更帶感,需要一點陰影效果。

  其實很簡單,調整一下透明度即可。比如這樣:

  當然用globalAlpha也是一樣的。
 
  • 粒子具有的屬性:
  將粒子放入運動場中,我們可以賦予它一些屬性,比如速度,加速度,位移等等,而這些屬性都可以用矢量來表示。
 

粒子運動

  之前我說過,以上皆是鋪墊,運動才是粒子化的關鍵。因為粒子最終要匯聚成一定的形狀,所以運動的某一段的終點已知,那么粒子怎樣能運動到對應的位置?

  我們從最簡單的直線運動說起。

 

  • 直線運動:

  談談文字圖片像素化中用的demo就是直線運動 -> 像素化

  如何用js描述一個直線運動?首先我們要明白在怎樣的情況下物體會做直線運動?學過物理我們知道速度和加速度在一條直線時,物體做直線運動。

  那么很簡單,已知粒子的終點,隨機粒子的起點,速度方向就確定了(起點指向終點),如果有必要,還可以設置加速度。
 
  • 曲線運動:
  僅僅做直線運動或許視覺效果太差,曲線運動會不會產生更好的視覺效果?
  什么情況下物體會做曲線運動?速度和加速度不在一條直線時,比如拋物運動。
  先看這個demo: demoHome(W·Axes) 我們取它的第一個過程進行分析,實際上就是一個二維的曲線運動。和拋物運動的不同之處是,加速度方向指向粒子的終點,為的是能夠准確達到終點位置。W.Axes的另一個粒子demo也大同小異: 粒子化,相比於前一個demo只是改變了粒子的初始位置和初始速度,以及粒子運動順序。
  我們嘗試着來完成一個demo。
  前面說到,為了能使粒子能到達指定的位置,我們給了粒子一個指向指定位置的加速度,在粒子的每一幀運動中,可以將該加速度分解到x和y軸分別進行計算。比如這樣:
update: function() {
  var v = this.pos2.minusNew(this.now);
  var angle = v.getAngle();
  this.v.x = (this.v.x + this.a * Math.cos(angle) / 1000 * 60) * 0.96;
  this.v.y = (this.v.y + this.a * Math.sin(angle) / 1000 * 60) * 0.96;
  this.now.x += this.v.x;
  this.now.y += this.v.y;
}

  a表示粒子的加速度值,/1000*60表示每幀的速度增加,*0.96模擬能量損失。這樣的運動的話粒子通過曲線運動就能到達指定位置。

  模擬屏幕左上角到屏幕中心的曲線運動:

  當然你也可以自己設置運動函數,不過我覺得這樣比較方便而已。
 
  
  • 關於緩動:
  有時為了效果我們需要設計一個緩動,什么是緩動?就是速度越來越小的運動。
  或許涉及到x和y軸同時變化的運動太過復雜,我們假設一個物體沿着x軸正方向運動,並且物體運動速度越來越小,即為緩動。
  最簡單的緩動如下:
update: function() {
  var v = this.pos2.minusNew(this.now);
  v.scale(0.05);
  this.now.add(v);
}
  稍微復雜點的緩動v-s圖像可以設計成二次函數或者三角函數,因為某點的切線的斜率即為速度,而切線斜率越來越小即為速度越來越小。
  更多可以參考岑安的文章 ->  【前端應該知道的那些事兒】運動學基礎
 
  • 二維三維:
  三維和二維環境下的粒子化其實大同小異,不了解三維的話可以參考 rotate 3d基礎試着實現一個球體的3d旋轉demo。
 

關於創意

  其實粒子化本身並不難,難的是創意。這里稍微介紹幾個有創意的demo。

  codepen上的一個demo,代碼很長,其實實現思路也大同小異,就是變着花樣的粒子的運動。

 

  同樣只是粒子的運動,只是多了點創意,構造了動態文字效果。

 

總結

  文字圖片粒子化其實就是粒子系統的一部分,不妨可以從最簡單的一個粒子系統開始,一步步實現一個簡單的粒子化demo。

  覺得不盡興,可以參考下面更多文章:

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM