国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

canvas 鼠標(biāo)點(diǎn)擊出現(xiàn)煙花效果

denson / 3612人閱讀

摘要:主要想法鼠標(biāo)點(diǎn)擊事件觸發(fā)圓點(diǎn)出現(xiàn)在鼠標(biāo)處圓點(diǎn)大小,顏色,數(shù)量隨機(jī)有一個(gè)小白圈做為軌跡不斷改變半徑變大變淡消失圓點(diǎn)向外移動(dòng),自身變小,消失。

主要想法:

鼠標(biāo)點(diǎn)擊事件觸發(fā)圓點(diǎn)出現(xiàn)在鼠標(biāo)處

圓點(diǎn)大小,顏色,數(shù)量隨機(jī)

有一個(gè)小白圈做為軌跡,不斷改變半徑變大變淡消失

圓點(diǎn)向外移動(dòng),自身變小,消失。隨著移動(dòng)的距離遠(yuǎn),移動(dòng)速度跟著變

需要處理的是,從鼠標(biāo)點(diǎn)擊處可以確定圓點(diǎn)的x,y軸,但是動(dòng)去哪,怎么動(dòng)是一個(gè)問(wèn)題,
所以先確定圓點(diǎn)的目標(biāo)坐標(biāo),再?gòu)膱A點(diǎn)的原始坐標(biāo)(即鼠標(biāo)點(diǎn)擊處)向目標(biāo)坐標(biāo)移動(dòng),并且x,y 成比例 去移動(dòng)才不會(huì)在x,y移動(dòng)距離不相等的情況下 不平衡

隨機(jī)生成圓點(diǎn)目標(biāo)坐標(biāo)的函數(shù)代碼:

let endpos = (x, y) => {
  let angle = random(0, 360) * Math.PI / 180,
    value = random(20, 150),
    radius = [-1, 1][random(0, 1)] * value;

  return {
    x: x + radius * Math.cos(angle),
    y: y + radius * Math.sin(angle)
  }
}

因?yàn)樾枰罅康碾S機(jī)數(shù),所以封裝一個(gè)生成隨機(jī)數(shù)函數(shù)

let random = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;

圓點(diǎn)的移動(dòng)函數(shù),我們需要的移動(dòng)是從原始坐標(biāo)向目標(biāo)坐標(biāo)由快而慢。
生成比例分成3段。那就是原始坐標(biāo)到第一段坐標(biāo)為第一段,第一段坐標(biāo)到第二段坐標(biāo)為第二段,第二段坐標(biāo)到目標(biāo)坐標(biāo)為第三段。如果當(dāng)前坐標(biāo)是處于第一段內(nèi),則速度越快,以此類推

現(xiàn)在兩種情況,一種是目標(biāo)坐標(biāo)大于原始坐標(biāo),那么,第一段就為最接近原始坐標(biāo)的那一段(Math.max(current, ff) == current ? (Math.max(current, mm) == current ? s : m) : f),第二種情況是目標(biāo)坐標(biāo)小于原始坐標(biāo),那么就反過(guò)來(lái),第一段為離原始坐標(biāo)最遠(yuǎn)的那一段。

//根據(jù)不同距離段設(shè)置前行的步伐,分為3個(gè)階段,離出發(fā)點(diǎn)近的那一段為速度最快,中間為速度一般,最遠(yuǎn)為速度最慢
//區(qū)分目標(biāo)點(diǎn)小于出發(fā)點(diǎn)的情況
//ratio為兩點(diǎn)之間的距離的行走比例,比例數(shù)值越大,行走越慢
  moveFun(start, end, current) {
    let s = random(26, 35),
      m = random(20, 25),
      f = random(15, 20),
      ff = start.x + ~~((end.x - start.x) / 3),
      mm = ff + ~~((end.x - start.x) / 3),
      ratio = end.x >= start.x ? (Math.max(current, ff) == current ? (Math.max(current, mm) == current ? s : m) : f) : (Math.max(current, ff) == current ? f : (Math.max(current, mm) == current ? m : s)),
      mp = {
        x: end.x - start.x,
        y: end.y - start.y
      };

    return {
      x: Math.abs(mp.x / ratio),
      y: Math.abs(mp.y / ratio)
    }
  }

每一個(gè)小圓點(diǎn)做為一個(gè)個(gè)體,自帶移動(dòng)函數(shù),和移動(dòng)的目標(biāo)坐標(biāo)。每次Animation時(shí),圓點(diǎn)進(jìn)行重繪更新最新的坐標(biāo)

小圓點(diǎn)的代碼:

class Circle {
  constructor(x, y) {
    this.r = random(9, 13)
    this.opos = {}
    this.x = this.opos.x = x
    this.y = this.opos.y = y

    this.colors = ["#FF1461", "#18FF92", "#5A87FF", "#FBF38C"]
    this.color = this.colors[random(0, this.colors.length)];
    this.tpos = endpos(x, y)
  }

  creatCircle(ctx) {
    ctx.beginPath()
    ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI)
    ctx.closePath()
    ctx.fillStyle = this.color
    ctx.fill()
  }

  //根據(jù)不同距離段設(shè)置前行的步伐,分為3個(gè)階段,離出發(fā)點(diǎn)近的那一段為速度最快,中間為速度一般,最遠(yuǎn)為速度最慢
  //區(qū)分目標(biāo)點(diǎn)小于出發(fā)點(diǎn)的情況
  //ratio為兩點(diǎn)之間的距離的行走比例,比例數(shù)值越大,行走越慢
  moveFun(start, end, current) {
    let s = random(26, 35),
      m = random(20, 25),
      f = random(15, 20),
      ff = start.x + ~~((end.x - start.x) / 3),
      mm = ff + ~~((end.x - start.x) / 3),
      ratio = end.x >= start.x ? (Math.max(current, ff) == current ? (Math.max(current, mm) == current ? s : m) : f) : (Math.max(current, ff) == current ? f : (Math.max(current, mm) == current ? m : s)),
      mp = {
        x: end.x - start.x,
        y: end.y - start.y
      };

    return {
      x: Math.abs(mp.x / ratio),
      y: Math.abs(mp.y / ratio)
    }
  }

  //根據(jù)計(jì)算出來(lái)的移動(dòng)值去移動(dòng)
  //如果目標(biāo)坐標(biāo)大于原始坐標(biāo)則向右移動(dòng),最大不能超過(guò)目標(biāo)坐標(biāo),反之向左移動(dòng)最小不能小于目標(biāo)坐標(biāo)
  move() {
    var movepos = this.moveFun(this.opos, this.tpos, this.x);

    this.x = (this.opos.x > this.tpos.x) ? Math.max(this.x - movepos.x, this.tpos.x) : Math.min(this.x + movepos.x, this.tpos.x)
    this.y = this.opos.y > this.tpos.y ? Math.max(this.y - movepos.y, this.tpos.y) : Math.min(this.y + movepos.y, this.tpos.y)
    this.r = Math.max(Math.abs((this.r - Math.random() / 1.2).toFixed(2)), 0)

  }
}

大圓則是從鼠標(biāo)點(diǎn)擊處創(chuàng)建的一個(gè)圓,并不斷改變其半徑向外擴(kuò)展,并且越來(lái)越透明,當(dāng)它已經(jīng)很大并且很透明時(shí)意味著我們的動(dòng)畫(huà)要結(jié)束了,所以以這個(gè)為標(biāo)準(zhǔn),停止動(dòng)畫(huà),并且清空屏幕

大圓代碼:

class BigCircle {
  constructor(x, y) {
    this.bR = random(16, 32)
    this.overR = random(60, 100)
    this.x = x
    this.y = y
    this.op = 1
  }

  creatBigCircle(ctx) {
    ctx.beginPath()
    ctx.arc(this.x, this.y, this.bR, 0, 2 * Math.PI)
    ctx.closePath()
    ctx.strokeStyle = "rgba(128, 128, 128, " + this.op + ")"
    ctx.stroke()
  }

  changeR() {
    this.bR = Math.min(this.bR += random(1, 4), this.overR);
    this.op = Math.max((this.op - Math.random() / 12).toFixed(2), 0)
  }

  //檢查是否運(yùn)行完畢,以大圓為標(biāo)準(zhǔn)清空屏幕
  complete() {
    return this.bR >= this.overR && this.op <= 0;
  }
}

全部代碼:

//canvas鼠標(biāo)點(diǎn)擊煙花特效

let endpos = (x, y) => {
  let angle = random(0, 360) * Math.PI / 180,
    value = random(20, 150),
    radius = [-1, 1][random(0, 1)] * value;

  return {
    x: x + radius * Math.cos(angle),
    y: y + radius * Math.sin(angle)
  }
}

let random = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;

class Circle {
  constructor(x, y) {
    this.r = random(9, 13)
    this.opos = {}
    this.x = this.opos.x = x
    this.y = this.opos.y = y

    this.colors = ["#FF1461", "#18FF92", "#5A87FF", "#FBF38C"]
    this.color = this.colors[random(0, this.colors.length)];
    this.tpos = endpos(x, y)
  }

  creatCircle(ctx) {
    ctx.beginPath()
    ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI)
    ctx.closePath()
    ctx.fillStyle = this.color
    ctx.fill()
  }

  //根據(jù)不同距離段設(shè)置前行的步伐,分為3個(gè)階段,離出發(fā)點(diǎn)近的那一段為速度最快,中間為速度一般,最遠(yuǎn)為速度最慢
  //區(qū)分目標(biāo)點(diǎn)小于出發(fā)點(diǎn)的情況
  //ratio為兩點(diǎn)之間的距離的行走比例,比例數(shù)值越大,行走越慢
  moveFun(start, end, current) {
      let s = random(26, 35),
        m = random(20, 25),
        f = random(15, 20),
        ff = start.x + ~~((end.x - start.x) / 3),
        mm = ff + ~~((end.x - start.x) / 3),
        ratio = end.x >= start.x ? (Math.max(current, ff) == current ? (Math.max(current, mm) == current ? s : m) : f) : (Math.max(current, ff) == current ? f : (Math.max(current, mm) == current ? m : s)),
        mp = {
          x: end.x - start.x,
          y: end.y - start.y
        };

      return {
        x: Math.abs(mp.x / ratio),
        y: Math.abs(mp.y / ratio)
      }
    }
    
    //根據(jù)計(jì)算出來(lái)的移動(dòng)值去移動(dòng)
    //如果目標(biāo)坐標(biāo)大于原始坐標(biāo)則向右移動(dòng),最大不能超過(guò)目標(biāo)坐標(biāo),反之向左移動(dòng)最小不能小于目標(biāo)坐標(biāo)
  move() {
    var movepos = this.moveFun(this.opos, this.tpos, this.x);

    this.x = (this.opos.x > this.tpos.x) ? Math.max(this.x - movepos.x, this.tpos.x) : Math.min(this.x + movepos.x, this.tpos.x)
    this.y = this.opos.y > this.tpos.y ? Math.max(this.y - movepos.y, this.tpos.y) : Math.min(this.y + movepos.y, this.tpos.y)
    this.r = Math.max(Math.abs((this.r - Math.random() / 1.2).toFixed(2)), 0)

  }
}

class BigCircle {
  constructor(x, y) {
    this.bR = random(16, 32)
    this.overR = random(60, 100)
    this.x = x
    this.y = y
    this.op = 1
  }

  creatBigCircle(ctx) {
    ctx.beginPath()
    ctx.arc(this.x, this.y, this.bR, 0, 2 * Math.PI)
    ctx.closePath()
    ctx.strokeStyle = "rgba(128, 128, 128, " + this.op + ")"
    ctx.stroke()
  }

  changeR() {
    this.bR = Math.min(this.bR += random(1, 4), this.overR);
    this.op = Math.max((this.op - Math.random() / 12).toFixed(2), 0)
  }

  //檢查是否運(yùn)行完畢,以大圓為標(biāo)準(zhǔn)清空屏幕
  complete() {
    return this.bR >= this.overR && this.op <= 0;
  }
}

window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;

window.clearRequestTimeout = window.cancelAnimationFrame || window.mozCancelRequestAnimationFrame || window.webkitCancelRequestAnimationFrame || window.msCancelRequestAnimationFrame;


let c = document.getElementById("fireworks"),
  w = c.width = c.offsetWidth,
  h = c.height = c.offsetHeight,

  ctx = c.getContext("2d"),
  nums = 40,
  circles = [],
  bCircle = null,
  animationId = false;

let int = function(x, y) {
  circles = []

  if (animationId) clearRequestTimeout(animationId)

  for (let i = nums; i-- > 0;) {
    circles.push(new Circle(x, y))
  }

  bCircle = new BigCircle(x, y)
  creat()
}

let creat = function() {
  ctx.clearRect(0, 0, w, h);

  circles.forEach(function(v) {
    v.move();
    v.creatCircle(ctx)
  })

  bCircle.changeR()
  bCircle.creatBigCircle(ctx)

  animationId = requestAnimationFrame(creat)

  if (bCircle.complete()) {
    //以大圓為標(biāo)準(zhǔn),清空屏幕停止動(dòng)畫(huà)
    ctx.clearRect(0, 0, w, h);
    clearRequestTimeout(animationId)
  }
}

c.onclick = function(e) {
  e = e || window.event;
  int(e.clientX, e.clientY)
}

html為

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/83391.html

相關(guān)文章

  • canvas 簡(jiǎn)易時(shí)鐘

    摘要:簡(jiǎn)易版時(shí)鐘時(shí)鐘清除畫(huà)布,每次執(zhí)行重新繪圖,解決時(shí)鐘模糊,邊框有鋸齒。 canvas 簡(jiǎn)易版時(shí)鐘 showImg(https://segmentfault.com/img/bVDNx7?w=405&h=370); 時(shí)鐘 *{ margin:0; padding:0; } bod...

    高勝山 評(píng)論0 收藏0
  • canvas 簡(jiǎn)易時(shí)鐘

    摘要:簡(jiǎn)易版時(shí)鐘時(shí)鐘清除畫(huà)布,每次執(zhí)行重新繪圖,解決時(shí)鐘模糊,邊框有鋸齒。 canvas 簡(jiǎn)易版時(shí)鐘 showImg(https://segmentfault.com/img/bVDNx7?w=405&h=370); 時(shí)鐘 *{ margin:0; padding:0; } bod...

    sugarmo 評(píng)論0 收藏0
  • 每周一點(diǎn)canvas動(dòng)畫(huà)——《支付寶價(jià)格拖動(dòng)選擇》

    摘要:主要功能就是拖動(dòng)標(biāo)尺變動(dòng)價(jià)格。整個(gè)標(biāo)尺的長(zhǎng)度為,步長(zhǎng)為元。金額顯示首先,增加一個(gè)輸入框,然后獲取它。輸入金額移動(dòng)標(biāo)尺標(biāo)尺的移動(dòng)除了拖動(dòng)以外,我們也希望通過(guò)金額輸入框來(lái)達(dá)到。 效果源碼 終于到年底了,再過(guò)兩天我也要回家過(guò)年了,想想就激動(dòng)呢!今天給大家?guī)?lái)一個(gè)基于移動(dòng)端的canvas價(jià)格選擇效果。 showImg(https://segmentfault.com/img/bV3QGd?w...

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

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

0條評(píng)論

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