效果预览

rose.gif

源码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      body {
        overflow: hidden;
        margin: 0;
        background-color: #010002;
      }
      canvas {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        background-color: #204;
      }
    </style>
  </head>
  <body>
    <canvas id="cnv"></canvas>
    <script>
      console.clear();
      let ctx = cnv.getContext("2d");
      let img = new Image();
      let imgStatus = 2;
      img.src = "./images/rose2.jpg"; // 换成自己的图片地址
      
      img.onload = () => {
        console.log(img);
        // prepare image data
        let imgSize = { x: img.width, y: img.height };
        ctx.canvas.width = imgSize.x;
        ctx.canvas.height = imgSize.y;
        ctx.drawImage(img, 0, 0);
        let imgData = ctx.getImageData(0, 0, img.width, img.height);
        let imgBytes = imgData.data; //
        let canvasRatio = imgSize.x / imgSize.y;
        let uY = (val) => ctx.canvas.height * 0.01 * val;
        let uX = (val) => ctx.canvas.width * 0.01 * val;
        function resize() {
          ctx.canvas.height = innerHeight * 0.95;
          ctx.canvas.width = ctx.canvas.height * canvasRatio;
          ctx.canvas.style.border = `${uY(1)}px solid gray`;
          ctx.canvas.style.borderRadius = `${uY(10)}px`;
          ctx.fillStyle = "black"; //
          ctx.fillRect(0, 0, uX(100), uY(100));
        }
        resize();
        window.addEventListener("resize", (event) => {
          resize();
        });
        class Point {
          constructor(x, y) {
            this.x = x;
            this.y = y;
            this.speed;
            this.speedRatio;
            this.color;
            this.radius = 0.3;
            this.init();
          }
          init() {
            this.x = Math.random() * 100;
            this.y = Math.random() * 100; //Math.random() * 100;
            this.speed = Math.random() * 0.3 + 0.2;
          }
          getData() {
            let x = Math.floor(this.x * 0.01 * imgSize.x);
            let y = Math.floor(this.y * 0.01 * imgSize.y);
            let idx = y * (imgSize.x * 4) + x * 4;
            let r = imgBytes[idx + 0];
            let g = imgBytes[idx + 1];
            let b = imgBytes[idx + 2];
            this.color = `rgb(${r}, ${g}, ${b})`;
            let gray = (r + g + b) / 3 / 255;
            this.speedRatio = 1 - gray * 0.9;
          }
          update() {
            this.y += this.speed * this.speedRatio;
            if (this.y >= 100) {
              this.init();
              this.getData();
            }
          }
          draw() {
            ctx.fillStyle = this.color;
            ctx.beginPath();
            ctx.arc(uX(this.x), uY(this.y), uY(this.radius), 0, Math.PI * 2);
            ctx.fill();
          }
        }
        class Points {
          constructor(amount) {
            this.amount = amount;
            this.points;
            this.init();
          }
          init() {
            this.points = Array.from({ length: this.amount }, () => {
              return new Point();
            });
          }
          update() {
            this.points.forEach((p) => {
              p.getData();
              p.update();
              p.draw();
            });
          }
        }
        let points = new Points(20000);
        draw();
        function draw() {
          requestAnimationFrame(draw);
          ctx.fillStyle = `rgba(32, 32, 32, 0.1)`;
          ctx.fillRect(0, 0, uX(100), uY(100));
          points.update();
        }
      };
    </script>
  </body>
</html>

程序猿Top
1 声望0 粉丝