简体   繁体   中英

React & Progressbar.js: Custom shaped progress circle

I found this cool loading progress project available in JavaScript and React . In their example at the bottom they have a progress loading circle in shape of a .svg picture (Heart). I want to do the same with a custom .svg and in React, but I struggle to get a working example. I installed it with npm, but how to import it and how to use it?

// import

import progressBar from 'react-progressbar.js';
// or like in their outdated example? 
// var ProgressBar = require('react-progressbar.js')
...
// Why progressBar.Circle, can't I import Circle directly from the package?
var Circle = progressBar.Circle;

let options = {
    strokeWidth: 2,
  };
  let containerStyle = {
    width: '200px',
    height: '200px',
  };

...

 return (
    <Circle
      progress={1}
      text={'test'}
      options={options}
      initialAnimate={true}
      containerStyle={containerStyle}
      containerClassName={'.progressbar'}
    />
  );

At the moment I get the Error:

Error: Element ref was specified as a string (progressBar) but no owner was set.

If someone could make a minimal working example how to use react-progressbar.js that would be nice.

I am also open to alternatives, if they are easy to use without too much code. Thanks in advance.

The package is a bit outdated, so it is based on an older version of react that allowed refs to be simple strings. Newer versions of react (as the one your are probably using) does not allow that anymore, hence the error.

See: Element ref was specified as a string (map) but no owner was set

You should either:

  1. Downgrade your react version (I would not suggest to use an older version just to use an outdated dependency)
  2. Use a different library (A quick google search revelead a lot of react progressbar packages)
  3. Use the Javascript version of this library, and wrap the functionalty inside a custom react component

Something along the lines of

import { Circle } from 'progressbar.js'

export default class CircleProgress extends React.Component<Props, State> {
    

   componentDidMount() {
     var bar = new Circle('#container', {easing: 'easeInOut'});
     bar.animate(1);
   }

   render() {
     return (
       <div id="container"></div>
     )
   }
}

@gbalduzzi 's answer is the right and accepted one. I still wanted to post a full working example with a custom .svg image:

import React from 'react';
import ProgressBar from 'progressbar.js';

export default class CustomProgressShape extends React.Component {
  componentDidMount() {
    var svgPath = document.getElementById('heart-path');
    var path = new ProgressBar.Path(svgPath, {
      easing: 'easeInOut',
      duration: 5000,
      step: function(state, circle) {
        if (circle.value() === 1) {
          circle.set(0);
          circle.animate(1.0);
        }
      },
    });
    path.set(0);
    path.animate(1.0);
  }

  render() {
    return (
      <>
        <svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" viewBox="0 0 100 100">
          <path
            fill-opacity="0"
            stroke-width="0.5"
            stroke="#f4f4f4"
            d="M81.495,13.923c-11.368-5.261-26.234-0.311-31.489,11.032C44.74,13.612,29.879,8.657,18.511,13.923  C6.402,19.539,0.613,33.883,10.175,50.804c6.792,12.04,18.826,21.111,39.831,37.379c20.993-16.268,33.033-25.344,39.819-37.379  C99.387,33.883,93.598,19.539,81.495,13.923z"
          />
          <path
            id="heart-path"
            fill-opacity="0"
            stroke-width="0.6"
            stroke="#555"
            d="M81.495,13.923c-11.368-5.261-26.234-0.311-31.489,11.032C44.74,13.612,29.879,8.657,18.511,13.923  C6.402,19.539,0.613,33.883,10.175,50.804c6.792,12.04,18.826,21.111,39.831,37.379c20.993-16.268,33.033-25.344,39.819-37.379  C99.387,33.883,93.598,19.539,81.495,13.923z"
          />
        </svg>
        <div id="container"></div> <div id="heart-path2"></div>
      </>
    );
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM