可以隨心所欲的canvas粒子特效

可以隨心所欲的canvas粒子特效

遊離在平面中的像素

我們把所有的運動公式都封裝在了dot類中,雖說實現了我們的當時需求,但是如果引申到一些方向性的東西的時候,就會顯得蒼白而無力。

相信很多自學的小夥伴都想學習web前端,可以關注小編後私信【學習】可以免費領取學習地址/案例教程/2018最新的一套學習教程,讓學習有方向。

平面中的指向標(vector2)

向量確實是一個神奇的東西,當座標系確定了之後,向量不僅僅可以看作是一個座標點,還可以看做是一段距離,同時還具有方向性,這就對於我們在平面中的定向操作就提供了很大的幫助。

  1. 定義一個二維向量類
function vector2(x,y) {
//當前的座標的x,y
this.x=x;
this.y=y;
}
  1. 向量的移動

當x2與y2都為0的時候,也就是存在於座標原點時,相減之後還會是(x1,y1),這也是為什麼我說它不僅可以代表一個座標,還可以代表一段距離

vector2.prototype.move = function(vec2) {
this.x+=vec2.x;
this.y+=vec2.y;
};
  1. 把向量單位化
  2. 單位向量,可以理解成在一段向量上,長度為1的向量
vector2.prototype.normalize = function(vec2) {
var x=vec2.x-this.x;
var y=vec2.y-this.y;
//以上是為了將當前座標轉換為原點,從而生成一段新的向量
return {
//返回一個單位向量
x:x/Math.sqrt(x*x+y*y),
y:y/Math.sqrt(x*x+y*y)
}
};

如果對於向量不熟悉的可以去看一看向量的公式,也許你看著會有一點暈,那麼我來舉一個例子。

(1,1)這是一個二維的向量,我可以用它來代表一個座標,也可以代表它到原點的距離,同時也可以代表從原點到該點的方向。

到目前,一個簡單的向量類就已經足夠我們去了解向量在圖形中的運用了。

擁有向量的粒子類

現在,我們就可以對之前的粒子類進行重寫

  1. 當粒子遇上向量
function dot(x,y,ax=0,ay=0,color="black") {
//用向量來替代之前的純座標
this.site=new vector2(x,y);
//初始時的目標座標向量既是當前座標向量
this.end=new vector2(x,y);
//速度全部交由系統來調整
this.vx=0;
this.vy=0;
//加速度受外界力影響
this.ax=ax;
this.ay=ay;
this.color=color;
//設置水平與豎直方向的值,具體作用下面有講
this.direction={
hor:0,
ver:0
}
this.ctx={};
}

  1. 在實現的時候,我們需要知道什麼是受我們直接影響的,什麼是受我們間接影響的,這樣可以可以在實現的實現的時候更具有聯動性,把更多的計算交由計算機去處理,可以大大避免一些不必要的誤操作。
  2. 最終點的設置
dot.prototype.setEnd = function(vec2) {
this.end=vec2;
this.vx=this.site.normalize(this.end).x;
this.vy=this.site.normalize(this.end).y;
if(vec2.x>this.site.x){this.direction.hor=1}
if(vec2.x if(vec2.y>this.site.y){this.direction.ver=-1}
if(vec2.y};

這裡會發現我們的方向速度量是取的位移向量的單位向量,這裡的原因是X=VT,當時間一定時,速度可以視作位移上的單位距離,然後將其方向化,也就獲得了方向速度。

這裡我將粒子的初始位置與目標位置做了對比,獲得了相對而言的上下或者左右,並且使用1或者-1來分別代替下右跟上左,有部分人不知道這裡為什麼是下右跟上左,這是因為在屏幕上的y軸的計算是以下方問正方向的,這也為什麼我們在繪製的時候是用(100,100)而不是(100,-100)

可以隨心所欲的canvas粒子特效

粒子的移動

dot.prototype.move = function() {
this.vy+=this.ay*t;
this.vx+=this.ax*t;
var hor="";
var ver="";
//對取整的方式進行判斷
switch (this.direction.hor) {
case 1:
hor='floor';
break;
case 0:
hor='floor';
break;
case -1:
hor='ceil';
default:

break;
}
switch (this.direction.ver) {
case 1:
ver='ceil';
break;
case 0:
ver='floor';
break;
case -1:
ver='floor';
default:

break;
}
if(Math[hor](this.site.x)!=this.end.x||Math[ver](this.site.y)!=this.end.y){
this.site.move(new vector2(this.vx,this.vy));
}
};

移動的基本公式上一節也有基礎的介紹,這裡直接用的是帶加速度的,v=v0+at(v0是初速度,v是勻變速t時間之後的速度)在位置判斷的時候我使用了向下取整的方法,是因為在做單位向量的時候會出現帶根號的數,為了便於判斷,我們就需要對位置的座標進行取整,這個時候,我們就需要根據粒子點在目標點的方位來決定是向上還是向下取整。取整之後就可以進行判斷是否達到目標位置,如果沒有就會繼續調用move的命令來不斷更新座標位置。

相信很多自學的小夥伴都想學習web前端,可以關注小編後私信【學習】可以免費領取學習地址/案例教程/2018最新的一套學習教程,讓學習有方向。

  1. 注意:
  2. 需要注意的是,我進行了取整,這也就意味著目標值要是整數,像素不存在小數位的像素,但是計算機在渲染如1.5px的時候,還是渲染出一些奇怪的東西,可以用以下的代碼做一下測試,你就清楚那不存在的小數位像素到底是什麼。
ctx.fillStyle='red';
ctx.fillRect(1,2,1,1);
ctx.fillRect(1,1,1.5,1);
ctx.fillRect(1,3,1.2,1);
ctx.fill();
  1. 後續工作

到目前為止,我們已經實現的粒子特效中最主要的部分,我們可以利用這個粒子類來實現粒子幾乎常見運動,如 勻速運動 勻變速/非勻變速運動 圓周運動 甚至是軌跡運動,是不是感覺那些看起來飛來飛去的特效開始有邏輯可循了


分享到:


相關文章: