react-circular-progressbar icon indicating copy to clipboard operation
react-circular-progressbar copied to clipboard

AnimatedProgressProvider is outdated

Open hoixw opened this issue 1 year ago • 1 comments

The package react-move, used in the docs, is quite outdated. It doesn't support react v18, which is required by next.js 13 and frameworks. You can easily rewrite it in framer-motion.

Example animatedProgressProvider:

import React, { useEffect, useState } from "react";
import { motion, useAnimation } from "framer-motion";

const AnimatedProgressProvider = ({
  valueStart = 0,
  valueEnd,
  duration,
  easingFunction,
  children,
  repeat = false
}) => {
  const controls = useAnimation();
  const [value, setValue] = useState(valueStart);

  useEffect(() => {
    const animate = async () => {
      await controls.start({
        value: valueEnd,
        transition: { duration, ease: easingFunction }
      });

      if (repeat) {
        await controls.start({
          value: valueStart,
          transition: { duration: 0 }
        });
      }
    };

    animate();

    if (repeat) {
      const interval = setInterval(animate, duration * 1000);
      return () => clearInterval(interval);
    }
  }, [controls, valueEnd, valueStart, duration, easingFunction, repeat]);

  return (
    <motion.div
      initial={{ value: valueStart }}
      animate={controls}
      onUpdate={latest => setValue(latest.value)}
    >
      {children(value)}
    </motion.div>
  );
};

export default AnimatedProgressProvider;

Example app.jsx:

import React from "react";
import { CircularProgressbar, buildStyles } from "react-circular-progressbar";
import "react-circular-progressbar/dist/styles.css";
import { easeQuadInOut } from "d3-ease";
import AnimatedProgressProvider from "./AnimatedProgressProvider";

const App = () => (
  <div style={{ width: 200 }}>
    <AnimatedProgressProvider
      valueStart={0}
      valueEnd={66}
      duration={1.4}
      easingFunction={easeQuadInOut}
    >
      {(value) => {
        const roundedValue = Math.round(value);
        return (
          <CircularProgressbar
            value={value}
            text={`${roundedValue}%`}
            styles={buildStyles({ pathTransition: "none" })}
          />
        );
      }}
    </AnimatedProgressProvider>
  </div>
);

export default App;

hoixw avatar Jul 13 '24 16:07 hoixw

Sharing mine if anyone is interested - superminimal, using the latest motion npm package:

import { animate } from "motion";
import { ReactNode, useEffect, useState } from "react";

export default function ProgressAnimator({
  valueEnd,
  children,
}: {
  valueEnd: number;
  children: (value: number) => ReactNode;
}) {
  const [value, setValue] = useState(0);

  useEffect(() => {
    setValue(0);
    const controls = animate(0, valueEnd, {
      duration: 0.8,
      ease: "linear",
      onUpdate: (latest) => setValue(latest),
    });

    return () => controls.stop();
  }, [valueEnd]);

  return <>{children(value)}</>;
}

Usage:



import ProgressAnimator from "@/components/widgets/progress-animator";

import {
  buildStyles,
  CircularProgressbarWithChildren,
} from "react-circular-progressbar";
import "react-circular-progressbar/dist/styles.css";

                            <ProgressAnimator valueEnd={progress}>
                              {(value) => {
                                return (
                                  <CircularProgressbarWithChildren
                                    value={value}
                                      pathTransition: "none",
                                    })}
                                  >
                                    <span className="text-base font-semibold">
                                      {Math.round(value)}%
                                    </span>
                                   
                                  </CircularProgressbarWithChildren>
                                );
                              }}
                            </ProgressAnimator>

@kevinsqi please update docs + example animator/wrapper/provider when possible 😁

spacecat avatar Jul 23 '25 09:07 spacecat