140行代码实现一个逼真的大雪纷飞的效果

  • 2019 年 12 月 7 日
  • 筆記

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://jerry.blog.csdn.net/article/details/103366270

本地新建一个html文件,把下列代码复制粘贴进去,保存,用浏览器打开:

<html>  <style>  html, body {    margin: 0;    padding: 0;    background: #000;  }  </style>  <script>  // https://codepen.io/pimskie/pen/jEVPNx    function myload(){      var canvas = document.querySelector('.snow'),      ctx = canvas.getContext('2d'),      windowW = window.innerWidth,      windowH = window.innerHeight,      numFlakes = 200,      flakes = [];    function Flake(x, y) {    var maxWeight = 5,        maxSpeed = 3;      this.x = x;    this.y = y;    this.r = randomBetween(0, 1);    this.a = randomBetween(0, Math.PI);    this.aStep = 0.01;        this.weight = randomBetween(2, maxWeight);    this.alpha = (this.weight / maxWeight);    this.speed = (this.weight / maxWeight) * maxSpeed;      this.update = function() {      this.x += Math.cos(this.a) * this.r;      this.a += this.aStep;        this.y += this.speed;    }    }    function init() {    var i = numFlakes,        flake,        x,        y;      while (i--) {      x = randomBetween(0, windowW, true);      y = randomBetween(0, windowH, true);          flake = new Flake(x, y);      flakes.push(flake);    }      scaleCanvas();    loop();  }    function scaleCanvas() {    canvas.width = windowW;    canvas.height = windowH;  }    function loop() {    var i = flakes.length,        z,        dist,        flakeA,        flakeB;      // clear canvas    ctx.save();    ctx.setTransform(1, 0, 0, 1, 0, 0);    ctx.clearRect(0, 0, windowW, windowH);    ctx.restore();      // loop of hell    while (i--) {        flakeA = flakes[i];      flakeA.update();          /*for (z = 0; z < flakes.length; z++) {        flakeB = flakes[z];        if (flakeA !== flakeB && distanceBetween(flakeA, flakeB) < 150) {          ctx.beginPath();          ctx.moveTo(flakeA.x, flakeA.y);          ctx.lineTo(flakeB.x, flakeB.y);          ctx.strokeStyle = '#444444';          ctx.stroke();          ctx.closePath();        }      }*/          ctx.beginPath();      ctx.arc(flakeA.x, flakeA.y, flakeA.weight, 0, 2 * Math.PI, false);      ctx.fillStyle = 'rgba(255, 255, 255, ' + flakeA.alpha + ')';      ctx.fill();        if (flakeA.y >= windowH) {        flakeA.y = -flakeA.weight;      }    }      requestAnimationFrame(loop);  }    function randomBetween(min, max, round) {    var num = Math.random() * (max - min + 1) + min;      if (round) {      return Math.floor(num);    } else {      return num;    }  }    function distanceBetween(vector1, vector2) {    var dx = vector2.x - vector1.x,        dy = vector2.y - vector1.y;      return Math.sqrt(dx*dx + dy*dy);  }    init();    }  </script>  <body onload = "myload()">  <canvas class="snow"></canvas>  </body>  </html>

最后效果如图,相当酷炫: