欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript利用canvas繪制流星雨效果

 更新時(shí)間:2022年10月17日 10:41:20   作者:前端南玖  
這篇文章主要為大家詳細(xì)介紹了如何通過(guò)JavaScript+canvas實(shí)現(xiàn)繪制流星雨效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

前言

最近總是夢(mèng)見(jiàn)一些小時(shí)候的故事,印象最深刻的就是夏天坐在屋頂上,看著滿(mǎn)天的繁星,一顆,兩顆,三顆...不由自主地開(kāi)始了數(shù)星星的過(guò)程。不經(jīng)意間,一顆流星劃過(guò)夜間,雖然只是轉(zhuǎn)瞬即逝,但它似乎比夜空中的其它繁星更吸引著我。聽(tīng)老人說(shuō),看見(jiàn)流星的時(shí)候許愿,愿望是可以實(shí)現(xiàn)的,此時(shí)早已把數(shù)星星拋之腦后,開(kāi)始期待著下一顆流星的出現(xiàn)。但是那天晚上,流星再也沒(méi)有出現(xiàn),這也成了自己小時(shí)候的一個(gè)遺憾。

今天,我決定用canvas為大家?guī)?lái)一場(chǎng)流星雨視覺(jué)盛宴。

需求分析

首先我們需要的元素有:夜空、滿(mǎn)天繁星、流星雨。

滿(mǎn)天繁星: 這個(gè)其實(shí)就是畫(huà)上一個(gè)個(gè)點(diǎn),然后不斷的通過(guò)顏色交替,營(yíng)造出一種星星閃爍的意境。

流星雨: 流星處于他自己的運(yùn)動(dòng)軌跡之中,當(dāng)前的位置最亮,輪廓最清晰,而之前劃過(guò)的地方離當(dāng)前位置軌跡距離越遠(yuǎn)就越暗淡越模糊,其實(shí)它就是一個(gè)漸變的過(guò)程,恰巧canvas有方法可以創(chuàng)建一個(gè)沿參數(shù)坐標(biāo)指定的直線(xiàn)的漸變。然后讓它從右上向左下移動(dòng),這樣就能營(yíng)造一種流星雨的效果,同時(shí)實(shí)現(xiàn)動(dòng)畫(huà)的循環(huán)。

OK,需求分析結(jié)束,準(zhǔn)備動(dòng)手開(kāi)干~

實(shí)現(xiàn)過(guò)程

1.繪制滿(mǎn)天繁星

//創(chuàng)建一個(gè)星星對(duì)象
class Star {
  constructor() {
    this.x = windowWidth * Math.random(); //橫坐標(biāo)
    this.y = 5000 * Math.random(); //縱坐標(biāo)
    this.text = "."; //文本
    this.color = "white"; //顏色
  }
  //初始化
  init() {
    this.getColor();
  }
  //繪制
  draw() {
    context.fillStyle = this.color;
    context.fillText(this.text, this.x, this.y);
  }
}

//畫(huà)星星
for (let i = 0; i < starCount; i++) {
  let star = new Star();
  star.init();
  star.draw();
  arr.push(star);
}

來(lái)看下此時(shí)的效果:

夜空中的滿(mǎn)天繁星現(xiàn)在是有了,但是缺乏一點(diǎn)意境,我們得想辦法讓這些繁星都閃爍起來(lái)。

2.滿(mǎn)天繁星閃起來(lái)

//創(chuàng)建一個(gè)星星對(duì)象
class Star {
  constructor() {
    this.x = windowWidth * Math.random(); //橫坐標(biāo)
    this.y = 5000 * Math.random(); //縱坐標(biāo)
    this.text = "."; //文本
    this.color = "white"; //顏色
  }
	// 獲取隨機(jī)顏色
  getColor() {
    let _r = Math.random();
    if (_r < 0.5) {
      this.color = "#333";
    } else {
      this.color = "white";
    }
  }

  //初始化
  init() {
    this.getColor();
  }
  //繪制
  draw() {
    context.fillStyle = this.color;
    context.fillText(this.text, this.x, this.y);
  }
}

//畫(huà)星星
for (let i = 0; i < starCount; i++) {
  let star = new Star();
  star.init();
  star.draw();
  arr.push(star);
}

//繁星閃起來(lái)
let t1
function playStars() {
  for (let n = 0; n < starCount; n++) {
    arr[n].getColor();
    arr[n].draw();
  }
  t1 = requestAnimationFrame(playStars);
}

繁星閃爍的元素就在于這個(gè)getColor方法,通過(guò)不斷地切換星星的顏色,來(lái)達(dá)到星星閃爍的效果。

再來(lái)看看這時(shí)的效果:

此刻的自己就可以開(kāi)始數(shù)星星了,一顆,兩顆,三顆...

3.繪制流星

簡(jiǎn)單點(diǎn)理解,流星其實(shí)就是一條漸變的線(xiàn)段,當(dāng)前的位置最亮,輪廓最清晰,而之前劃過(guò)的地方離當(dāng)前位置軌跡距離越遠(yuǎn)就越暗淡越模糊。

這里的關(guān)鍵API是createLinearGradient,用于創(chuàng)建一個(gè)沿參數(shù)坐標(biāo)指定的直線(xiàn)的漸變。

語(yǔ)法:

CanvasGradient ctx.createLinearGradient(x0, y0, x1, y1);

  • x0:起點(diǎn)的 x 軸坐標(biāo)。
  • y0:起點(diǎn)的 y 軸坐標(biāo)。
  • x1:終點(diǎn)的 x 軸坐標(biāo)。
  • y1:終點(diǎn)的 y 軸坐標(biāo)。

使用createLinearGradient() 方法初始化一個(gè)線(xiàn)性漸變。在這個(gè)線(xiàn)性漸變中添加三種顏色,達(dá)到一種漸變的效果來(lái)模擬出流星劃過(guò)夜空的狀態(tài)。

/**繪制流星**/
  draw() {
    //繪制一個(gè)流星的函數(shù)
    context.save();
    context.beginPath();
    context.lineWidth = 1; //寬度
    context.globalAlpha = this.alpha; //設(shè)置透明度
    //創(chuàng)建橫向漸變顏色,起點(diǎn)坐標(biāo)至終點(diǎn)坐標(biāo)
    let line = context.createLinearGradient(
      this.x,
      this.y,
      this.x + this.width,
      this.y - this.height
    );
    //分段設(shè)置顏色
    line.addColorStop(0, "white");
    line.addColorStop(0.3, this.color1);
    line.addColorStop(0.6, this.color2);
    context.strokeStyle = line;
    //起點(diǎn)
    context.moveTo(this.x, this.y);
    //終點(diǎn)
    context.lineTo(this.x + this.width, this.y - this.height);
    context.closePath();
    context.stroke();
    context.restore();
  }

現(xiàn)在我們來(lái)看一看當(dāng)年的那個(gè)流星:

4.流星劃過(guò)夜空

流星有了,現(xiàn)在我們得想辦法讓它動(dòng)起來(lái)。這里其實(shí)就是通過(guò)不斷地計(jì)算位置來(lái)達(dá)到流星動(dòng)起來(lái)的效果。

move() {
    //清空流星像素
    let x = this.x + this.width - this.offset_x;
    let y = this.y - this.height;
    context.clearRect(x - 3, y - 3, this.offset_x + 5, this.offset_y + 5);
    //重新計(jì)算位置,往左下移動(dòng)
    this.countPos();
    //透明度增加
    this.alpha -= 0.002;
    //重繪
    this.draw();
  }

現(xiàn)在,我們就可以看到當(dāng)年的那顆流星了,是不是很激動(dòng)。稍安勿躁,為了彌補(bǔ)當(dāng)年的遺憾,這里決定來(lái)一場(chǎng)從未真實(shí)見(jiàn)過(guò)的流星雨。

5.流星雨

寫(xiě)到這里,實(shí)現(xiàn)流星雨其實(shí)就很簡(jiǎn)單了,我們只需要再多生成一些流星,為它們各自分配不同的坐標(biāo)即可。

let t2
// 創(chuàng)建流星雨對(duì)象
class MeteorRain {
  constructor() {
    this.x = -1;
    this.y = -1;
    this.length = -1; //長(zhǎng)度
    this.angle = 30; //傾斜角度
    this.width = -1; //寬度
    this.height = -1; //高度
    this.speed = 1; //速度
    this.offset_x = -1; //橫軸移動(dòng)偏移量
    this.offset_y = -1; //縱軸移動(dòng)偏移量
    this.alpha = 1; //透明度
    this.color1 = ""; //流星的色彩
    this.color2 = ""; //流星的色彩
  }
  init() {
    //初始化
    this.getPos();
    this.alpha = 1; //透明度
    this.getRandomColor();
    //最小長(zhǎng)度,最大長(zhǎng)度
    let x = Math.random() * 80 + 150;
    this.length = Math.ceil(x);
    x = Math.random() + 0.5;
    this.speed = Math.ceil(x); //流星的速度
    let cos = Math.cos((this.angle * 3.14) / 180);
    let sin = Math.sin((this.angle * 3.14) / 180);
    this.width = this.length * cos;
    this.height = this.length * sin;
    this.offset_x = this.speed * cos;
    this.offset_y = this.speed * sin;
  }
  /**獲取隨機(jī)顏色函數(shù)**/
  getRandomColor() {
    let a = Math.ceil(255 - 240 * Math.random());
    //中段顏色
    this.color1 = "rgba(" + a + "," + a + "," + a + ",1)";
    //結(jié)束顏色
    this.color2 = "black";
  }
  /**重新計(jì)算流星坐標(biāo)的函數(shù)**/
  countPos() {
    //
    //往左下移動(dòng),x減少,y增加
    this.x = this.x - this.offset_x;
    this.y = this.y + this.offset_y;
  }
  /**獲取隨機(jī)坐標(biāo)的函數(shù)**/
  getPos() {
    //
    //橫坐標(biāo)
    this.x = Math.random() * window.innerWidth; //窗口高度
    //縱坐標(biāo)
    this.y = Math.random() * window.innerHeight; //窗口寬度
  }
  /**繪制流星**/
  draw() {
    //繪制一個(gè)流星的函數(shù)
    context.save();
    context.beginPath();
    context.lineWidth = 1; //寬度
    context.globalAlpha = this.alpha; //設(shè)置透明度
    //創(chuàng)建橫向漸變顏色,起點(diǎn)坐標(biāo)至終點(diǎn)坐標(biāo)
    let line = context.createLinearGradient(
      this.x,
      this.y,
      this.x + this.width,
      this.y - this.height
    );
    //分段設(shè)置顏色
    line.addColorStop(0, "white");
    line.addColorStop(0.3, this.color1);
    line.addColorStop(0.6, this.color2);
    context.strokeStyle = line;
    //起點(diǎn)
    context.moveTo(this.x, this.y);
    //終點(diǎn)
    context.lineTo(this.x + this.width, this.y - this.height);
    context.closePath();
    context.stroke();
    context.restore();
  }
  move() {
    //清空流星像素
    let x = this.x + this.width - this.offset_x;
    let y = this.y - this.height;
    context.clearRect(x - 3, y - 3, this.offset_x + 5, this.offset_y + 5);
    //重新計(jì)算位置,往左下移動(dòng)
    this.countPos();
    //透明度增加
    this.alpha -= 0.002;
    //重繪
    this.draw();
  }
}

//繪制流星
function playRains() {
  for (let n = 0; n < rainCount; n++) {
    // console.log(rains, "--");
    let rain = rains[n];
    rain.move(); //移動(dòng)
    if (rain.y > window.innerHeight) {
      //超出界限后重來(lái)
      context.clearRect(rain.x, rain.y - rain.height, rain.width, rain.height);
      rains[n] = new MeteorRain();
      rains[n].init();
    }
  }
  t2 = requestAnimationFrame(playRains);
}

6.merge視覺(jué)盛宴

流星極短暫的星星是也,它不像恒星和行星那般耀眼,卻用短暫的生命,劃破夜空,用瞬間瀟灑的弧線(xiàn)留住美麗的光輝。曇花和流星瞬間之美令我無(wú)法忘懷,大自然神奇的造物者給了我們?cè)S多的美,不論瞬間的還是永恒的,我們都要用真心去欣賞去品味。

通過(guò)合并前面五個(gè)步驟,我們就能夠一睹這流星剎那間的交錯(cuò),而后瞬間就穿透為永恒,只是一刻用生命幻化的美。

以上就是JavaScript利用canvas繪制流星雨效果的詳細(xì)內(nèi)容,更多關(guān)于JavaScript canvas繪制流星雨的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • js事件委托和事件代理案例分享

    js事件委托和事件代理案例分享

    這篇文章主要為大家分享了js事件委托和事件代理案例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • JavaScript 實(shí)現(xiàn)下雪特效的示例代碼

    JavaScript 實(shí)現(xiàn)下雪特效的示例代碼

    這篇文章主要介紹了JavaScript 實(shí)現(xiàn)下雪特效的示例代碼,幫助大家利用JavaScript制作特效,感興趣的朋友可以了解下
    2020-09-09
  • bootstrap表單示例代碼分享

    bootstrap表單示例代碼分享

    這篇文章主要為大家詳細(xì)介紹了bootstrap表單示例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • JavaScript給事件委托批量添加事件監(jiān)聽(tīng)詳細(xì)流程

    JavaScript給事件委托批量添加事件監(jiān)聽(tīng)詳細(xì)流程

    事件委托,一般來(lái)講,會(huì)把一個(gè)或者一組元素的事件委托到它的父層或者更外層元素上,真正綁定事件的是外層元素,當(dāng)事件響應(yīng)到需要綁定的元素上時(shí),會(huì)通過(guò)事件冒泡機(jī)制從而觸發(fā)它的外層元素的綁定事件上,然后在外層元素上去執(zhí)行函數(shù)
    2021-10-10
  • 小程序自定義模板實(shí)現(xiàn)吸頂功能

    小程序自定義模板實(shí)現(xiàn)吸頂功能

    這篇文章主要為大家詳細(xì)介紹了小程序自定義模板實(shí)現(xiàn)吸頂功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-01-01
  • layui問(wèn)題之模擬select點(diǎn)擊事件的實(shí)例講解

    layui問(wèn)題之模擬select點(diǎn)擊事件的實(shí)例講解

    今天小編就為大家分享一篇layui問(wèn)題之模擬select點(diǎn)擊事件的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • 非常漂亮的js煙花效果

    非常漂亮的js煙花效果

    這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)非常漂亮的煙花效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • JavaScript+HTML5實(shí)現(xiàn)的日期比較功能示例

    JavaScript+HTML5實(shí)現(xiàn)的日期比較功能示例

    這篇文章主要介紹了JavaScript+HTML5實(shí)現(xiàn)的日期比較功能,涉及javascript結(jié)合HTML5針對(duì)日期的轉(zhuǎn)換與運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下
    2017-07-07
  • LayUI+Shiro實(shí)現(xiàn)動(dòng)態(tài)菜單并記住菜單收展的示例

    LayUI+Shiro實(shí)現(xiàn)動(dòng)態(tài)菜單并記住菜單收展的示例

    這篇文章主要介紹了LayUI+Shiro實(shí)現(xiàn)動(dòng)態(tài)菜單并記住菜單收展的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • javascript學(xué)習(xí)總結(jié)之js使用技巧

    javascript學(xué)習(xí)總結(jié)之js使用技巧

    本篇文章給大家分享javascript學(xué)習(xí)總結(jié)之js使用技巧,都是精華喔~小伙伴快來(lái)學(xué)習(xí)吧。
    2015-09-09

最新評(píng)論