iT邦幫忙

2021 iThome 鐵人賽

DAY 23
1
Modern Web

Canvas 小錦囊系列 第 23

Day 23 - 用 canvas 與 requestAnimationFrame 做 進度條

  • 分享至 

  • xImage
  •  

前述

雖然用一般的 css 就可以完成進度條,但為了符合主題,用了 canvas 來完成!

codesendBox

import React, { useState, useRef, useEffect } from "react";

const CanvasCircle = () => {
  const canvasRef = useRef(null);
  const [context, setContext] = useState(null);
  const [centerX, setCenterX] = useState(0);
  const [centerY, setCenterY] = useState(0);
  const [rad, setRad] = useState(0);
  const [speed, setSpeed] = useState(0.1);

  useEffect(() => {
    const canvas = canvasRef.current; // Get canvas elements
    const ctx = canvas.getContext("2d");

    setContext(ctx);
    const CentX = canvas.width / 2; // Canvas central point X-axis coordinates
    const CentY = canvas.height / 2; // Canvas center point y axis coordinates
    const Rad = (Math.PI * 2) / 100;
    setCenterX(CentX);
    setCenterY(CentY);
    setRad(Rad);
  }, [canvasRef]);

  useEffect(() => {
    const drawFrame = () => {
      if (context) {
        context.clearRect(0, 0, 500, 500);

        whiteCircle();
        text(speed);
        blueCircle(speed);

        setSpeed((prev) => {
          if (prev > 100) prev = 0;
          return (prev += 0.1);
        });
      }
    };
    const draw = window.requestAnimationFrame(drawFrame);
    return () => cancelAnimationFrame(draw);
  }, [context, blueCircle]);

  // Draw a blue outer ring
  function blueCircle(n) {
    context.save();
    context.beginPath();
    context.strokeStyle = "#49f";
    context.lineWidth = 12;
    context.arc(
      centerX,
      centerY,
      100,
      -Math.PI / 2,
      -Math.PI / 2 + n * rad,
      false
    );
    context.stroke();
    context.restore();
  }

  // Draw a white outer ring
  function whiteCircle() {
    context.save();
    context.beginPath();
    context.strokeStyle = "#A5DEF1";
    context.lineWidth = 12;
    context.arc(centerX, centerY, 100, 0, Math.PI * 2, false);
    context.stroke();
    context.closePath();
    context.restore();
  }

  // Percentage Text Drawing
  function text(n) {
    context.save();
    context.fillStyle = "#F47C7C";
    context.font = "40px Arial";
    context.textAlign = "center";
    context.textBaseline = "middle";
    context.fillText(n.toFixed(0) + "%", centerX, centerY);
    context.restore();
  }

  return <canvas id="canvas" ref={canvasRef} width={500} height={500}></canvas>;
};

export default CanvasCircle;


上一篇
Day22 - 用 canvas 做 圈圈叉叉遊戲
下一篇
Day 24 - 用 canvas 畫個時鐘
系列文
Canvas 小錦囊30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言