iT邦幫忙

2021 iThome 鐵人賽

DAY 25
1
Modern Web

Canvas 小錦囊系列 第 25

Day 25 - 用 canvas 做 煙火

  • 分享至 

  • xImage
  •  

慶祝國慶日啦

成功的

失敗的

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 24 - 用 canvas 畫個時鐘
下一篇
Day 26 - 用canvas 做顏色遊戲
系列文
Canvas 小錦囊30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言