亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

一步步實(shí)現(xiàn)nest粒子特效

ky0ncheng / 1887人閱讀

摘要:嘗試實(shí)現(xiàn)畫出一個(gè)彈射的小球很簡(jiǎn)單,那怎么用多個(gè)小球?qū)崿F(xiàn)這樣的效果呢。

本文首發(fā)于我的博客,這是我的github,歡迎star。

??這篇博客是模仿nest.js實(shí)現(xiàn)一個(gè)demo,由簡(jiǎn)單到復(fù)雜,來一步步的實(shí)現(xiàn)它。這里是效果預(yù)覽。我的github里邊還有很多別的前端的demo,喜歡的話可以點(diǎn)個(gè)star,你的支持就是我的動(dòng)力。

從一道面試題開始
實(shí)現(xiàn)一個(gè)半徑10px的小球在500px*500px的方塊中做直線運(yùn)動(dòng),初始方向隨機(jī),速度保持不變,碰撞到墻壁后反彈。

??看下效果,思路很簡(jiǎn)單,將小球定位在方塊中,設(shè)置xy方向上的速度,每幀動(dòng)畫給小球定位的值加上對(duì)應(yīng)方向的速度值,在檢測(cè)到小球碰撞墻壁的時(shí)候,將對(duì)應(yīng)方向的速度置為反方向就可以了。這里是實(shí)現(xiàn)的代碼,沒有用到canvas,但是思路一致。

嘗試實(shí)現(xiàn)

??畫出一個(gè)彈射的小球很簡(jiǎn)單,那怎么用多個(gè)小球?qū)崿F(xiàn)nest.js這樣的效果呢。這樣的特效肯定不能用Dom直接做,太耗費(fèi)性能,也做不出來,這時(shí)就顯露出canvas的強(qiáng)大之處了。
??同樣的,用canvas生成多個(gè)彈來彈去的小球。首先不要管鼠標(biāo)如何吸附這些小圓點(diǎn),只做小球之間的連線。在每次繪制小球之前,判斷一下它和之前的小球的距離是不是小于極限距離,小于就以它倆為端點(diǎn)繪制一條線。代碼如下,思路都寫在注釋里:

const theCanvas = document.getElementById("theCanvas"),
  ctx = theCanvas.getContext("2d"),
  mix = 6000;   //會(huì)產(chǎn)生連線的極限距離的平方

//將canvas鋪滿瀏覽器
let canvas_width = theCanvas.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
  canvas_height = theCanvas.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight,
  points = [];
theCanvas.style = "position: fixed; top: 0px; left: 0px;";

//繪制函數(shù),用requestAnimationFrame調(diào)用實(shí)現(xiàn)動(dòng)畫
function draw() {
  //清屏
  ctx.clearRect(0, 0, canvas_width, canvas_height);
  let i,pi,x_dist,y_dist;

  //遍歷點(diǎn)集合繪制線條
  points.forEach((p, index) => {
    p.x += p.xa,        //按指定速度移動(dòng)
    p.y += p.ya,
    p.xa *= p.x > canvas_width || p.x < 0 ? -1 : 1,
    p.ya *= p.y > canvas_height || p.y < 0 ? -1 : 1,
    ctx.fillRect(p.x - 0.5, p.y - 0.5, 1, 1);        //繪制點(diǎn),其實(shí)是小方塊

    //類似于握手問題,兩個(gè)點(diǎn)之間只繪制一次線
    for(i = index + 1; i < points.length; i++) {
      pi = points[i];
      x_dist = p.x - pi.x;
      y_dist = p.y - pi.y;
      dist = x_dist * x_dist + y_dist * y_dist;
      //判斷點(diǎn)之間的距離是否小于極限距離
      if(dist < mix) {
        ctx.beginPath();
        ctx.moveTo(p.x, p.y);
        ctx.lineTo(pi.x, pi.y);
        ctx.stroke();
      }
    }
  }),requestAnimationFrame(draw);
}

//隨機(jī)生成100個(gè)點(diǎn)
for(let i = 0; i < 100; i++ ) {

  let    x = Math.random() * canvas_width,    //初始坐標(biāo)
    y = Math.random() * canvas_height,
    xa = 2 * Math.random() - 1,            //x速度
    ya = 2 * Math.random() - 1;            //y速度

  points[i] = {x, y, xa, ya};
}

draw();

??看下效果,丑陋,和人家的不一樣,很生硬。因?yàn)檫B線不是突然出現(xiàn)突然消失的,點(diǎn)和點(diǎn)之間的連線是漸漸的出現(xiàn),然后漸漸消失的。給連線添加動(dòng)態(tài)的屬性,用點(diǎn)和點(diǎn)的之間的距離來計(jì)算連線的粗細(xì)、透明度,在兩點(diǎn)距離比較遠(yuǎn)的時(shí)候線會(huì)變淡,這樣看起來就舒服多了。

for(i = index + 1; i < points.length; i++) {
  pi = points[i];
  x_dist = p.x - pi.x;
  y_dist = p.y - pi.y;
  dist = x_dist * x_dist + y_dist * y_dist;
  //根據(jù)兩點(diǎn)距離得到一個(gè)參數(shù)w
  w = (mix - dist) / mix;
  //判斷點(diǎn)之間的距離是否小于極限距離
  if(dist < mix) {
    ctx.beginPath();
    //根據(jù)參數(shù)w設(shè)置連線寬度和透明度
    ctx.lineWidth = w / 2;
    ctx.strokeStyle = `rgba(110,110,110,${w + 0.2})`;
    ctx.moveTo(p.x, p.y);
    ctx.lineTo(pi.x, pi.y);
    ctx.stroke();
  }
}
添加鼠標(biāo)事件

??先是加入對(duì)鼠標(biāo)的響應(yīng)。在鼠標(biāo)進(jìn)入瀏覽器時(shí)添加鼠標(biāo)這個(gè)點(diǎn),否則移除。

window.onmousemove = e => {
  e = e || window.event;
  current_point.x = e.clientX;
  current_point.y = e.clientY;
};
window.onmouseout = () => {
  current_point.x = null;
  current_point.y = null;
};
//將鼠標(biāo)的點(diǎn)添加至點(diǎn)集合中
all_points = [...random_points,current_point];

??要實(shí)現(xiàn)一個(gè)鼠標(biāo)吸附粒子的效果,思路就是粒子和鼠標(biāo)的距離在一定范圍內(nèi)時(shí),給粒子添加一個(gè)向著鼠標(biāo)的速度,結(jié)果就好像是粒子受到鼠標(biāo)的吸附一樣。這是一段鼠標(biāo)吸附效果的核心代碼:

//當(dāng)兩點(diǎn)距離小于極限距離時(shí)產(chǎn)生連線,當(dāng)?shù)诙€(gè)點(diǎn)是鼠標(biāo)所產(chǎn)生點(diǎn)時(shí),粒子如果在范圍內(nèi)就會(huì)產(chǎn)生向鼠標(biāo)點(diǎn)的速度,實(shí)現(xiàn)吸附效果
dist < pi.max && (pi === current_point && dist >= pi.max / 2 && (p.x -= 0.03 * x_dist, p.y -= 0.03 * y_dist));

??加入鼠標(biāo)的點(diǎn)之后再做一些調(diào)整,得到最終的代碼。

其他的粒子特效

??還可以利用canvasgetImageData屬性,將圖片粒子化,做成輪播圖,點(diǎn)擊這里預(yù)覽,主要思路是用getImageData取到圖片像素點(diǎn)的信息,每隔一段取一個(gè)樣本,以這個(gè)樣本繪制粒子,繪制出類似于馬賽克一樣的圖片,然后給粒子加上運(yùn)動(dòng)的效果就可以了,這里是具體的代碼實(shí)現(xiàn)。

這篇博客到這就結(jié)束了,這是我的github,歡迎來訪,歡迎star。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/92227.html

相關(guān)文章

  • 前端特效demo | 值得收藏的6個(gè) HTML5 Canvas 實(shí)用案例

    摘要:模擬飛機(jī)航班線路動(dòng)畫一款基于的飛機(jī)航班線路模擬動(dòng)畫,它模擬了許多航班在不同目的地的起飛降落數(shù)量。跳動(dòng)加載動(dòng)畫可調(diào)節(jié)參數(shù)這是一款基于的跳動(dòng)加載動(dòng)畫,它的另一個(gè)特點(diǎn)是可以動(dòng)態(tài)調(diào)節(jié)動(dòng)畫參數(shù)。 showImg(https://segmentfault.com/img/bVblze6?w=900&h=383); HTML5 動(dòng)畫在Canvas 上得到了充分的發(fā)揮,我們 VIP 視頻也分享過很多相...

    Chao 評(píng)論0 收藏0
  • 開源造輪子:個(gè)簡(jiǎn)潔,高效,輕量級(jí),酷炫的不要不要的canvas粒子運(yùn)動(dòng)插件庫(kù)

    摘要:一開篇哈哈哈,感謝標(biāo)題黨的蒞臨雖然標(biāo)題有點(diǎn)夸張的感覺,但實(shí)際上,插件庫(kù)確實(shí)是簡(jiǎn)潔,高效,輕量級(jí),酷炫酷炫的咯。當(dāng)然,配置不同的參數(shù)值,或許可以得到挺多不同的特效呢上面已經(jīng)演示過標(biāo)配的粒子無序運(yùn)動(dòng)啦,下面演示后面兩種。 一:開篇 哈哈哈,感謝標(biāo)題黨的蒞臨~ 雖然標(biāo)題有點(diǎn)夸張的感覺,但實(shí)際上,插件庫(kù)確實(shí)是簡(jiǎn)潔,高效,輕量級(jí),酷炫酷炫的咯。廢話不多說,先來看個(gè)標(biāo)配例子吧: http://co...

    Anonymous1 評(píng)論0 收藏0
  • JParticles 2.0 發(fā)布,打造炫酷的粒子特效

    摘要:我們一貫的理念我們我笑哭一貫的理念是信仰和。第一點(diǎn)視差粒子幾行代碼為了看起來更簡(jiǎn)潔,定義視差粒子層數(shù)的屬性就省略了,因?yàn)楸旧硭褪菍樱餐玫?。演示四層,為了讓大家能更了解屬性的使用方法。又高大上,又可以緩解加載的等待心情。 JParticles 2.0 發(fā)布,打造炫酷的粒子特效。不好意思哈,在這么繁花似錦的世界里,標(biāo)題不得不取得吸引眼球一點(diǎn)哈,不然...還是不啰嗦了,我們進(jìn)入正題吧s...

    tinna 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<