Day 25 - 用 canvas 做 烟火

庆祝国庆日啦

成功的

失败的

import "./styles.css";
import React, { useEffect, useRef } from "react";

let hue = Math.random() * 360;
let hueVariance = 60;

export default function App() {
  const canvasRef = useRef(null);

  useEffect(() => {
    tick();
  }, [canvasRef]);

  const drawFires = (x = 0, y = 0) => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");

    // 初始半径,以及粒子数量
    let count = 10;
    let radius = 10;
    for (let i = 0; i < count; i++) {
      let angle = (360 / count) * i;
      let radians = (angle * Math.PI) / 180;
      let moveX = x + Math.cos(radians) * radius;
      let moveY = y + Math.sin(radians) * radius;

      ctx.beginPath();
      ctx.arc(moveX, moveY, 2, Math.PI * 2, false);
      // 结束
      ctx.closePath();
      ctx.fillStyle = "#ff0000";
      ctx.fill();

      ctx.beginPath();
      ctx.arc(moveX, moveY, 2, Math.PI * 2, false);
      ctx.x += moveX;
      ctx.y += moveY;

      ctx.radius *= 1 - ctx.speed / 120;
      ctx.alpha -= 0.01;

      const style = setColors();
      ctx.fillStyle = `hsl(${style?.hue}, ${style?.lightness}, ${style?.alpha})`;
      ctx.fill();
      ctx.closePath();
    }
  };
  const handleClick = (e) => {
    let x = e.clientX;
    let y = e.clientY;
    //  addFires(x, y);
    drawFires(x, y);
  };

  /**
   *  隐影
   */
  const tick = () => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");
    ctx.globalCompositeOperation = "destination-out";
    ctx.fillStyle = "rgba(0,0,0," + 10 / 100 + ")";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.globalCompositeOperation = "lighter";
    // 更新画布
    drawFires();
    // requestAnimationFrame(tick);
  };

  function setColors() {
    let firework = { hue: null, brightness: null, alpha: null };
    firework.hue =
      Math.floor(Math.random() * (hue + hueVariance - (hue - hueVariance))) +
      (hue - hueVariance);
    firework.brightness = Math.floor(Math.random() * 21) + 50;
    firework.alpha = (Math.floor(Math.random() * 60) + 40) / 100;
    return firework;
  }

  return (
    <div className="App">
      <canvas
        ref={canvasRef}
        width="500"
        height="500"
        onClick={handleClick}
      ></canvas>
    </div>
  );
}

<<:  Day 26 : Linux - 档案or目录的权限该怎麽看?又该如何做更改?

>>:  Day25 - 保护你的状态转移,在 XState 中使用 Guard Transition

[Day 29] 实作-axios 串接api

先看一下有哪些api 下面列出这次用到的openapi, 可以看到他有一个共通的domain htt...

Day-23 快速面试之考题大公开!(2)

今天来补充一下”快速面试”还要再补充的地方,现在回想还是怕… 有一家厂商满特别的,一开始面试直接问...

Day 21 UICollectionView的练习(1/2)

今天我们使用XIB来练习CollectionView,还不知道XIB怎麽使用的,可以看这边: 连结 ...

理解React的setState到底是同步还是非同步(下)

在上个月初的时候,偶然在IThelp看到这篇讨论 setState後画面没有立即Render,决定趁...

Day 05 - 决策(if, switch)

# if 语句 由一个条件句去判断 bool 值,若是true就执行 statement,false...