mhlavacka
mhlavacka

Reputation: 701

How to rewrite JS Progressbar.js object to React component

I play with React for few days, everything seemed fairly easily, until I got stuck with rewriting this JS object as a React component.

This is JsFiddle Example with JS object example. How to go about rewriting this as React component?

This is what I was trying:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import ProgressBar from 'progressbar.js';

class Circle extends Component{
  componentDidMount() {
    this._create(this.props);
  }

  _create(props) {
    var container = ReactDOM.findDOMNode(this.refs.progressBar);
    container.animate(props.progress);
  }

  render() {
   return <div ref="progressBar"></div>;
  }
}

Circle.defaultProps = {
  options: {},
  progress: 1.0,
}

export default Circle;

Upvotes: 0

Views: 506

Answers (1)

ju5td0m7m1nd
ju5td0m7m1nd

Reputation: 36

Here is a example of loading circle,

but it is NOT modified from the code above.

Instead, I use SVG, strokeDashArray and strokeDashOffset

CODE

import React from 'react';
const styles = {
  svg :{
      position:'fixed', 
      width:'100%',
      height:'100%',
      position:'fixed',
      top:'0', left:'0',
      background:'rgba(240,240,240,1)',
  },
  circle : {
      strokeDasharray : '300',
      transition : 'all .4s ease-in',
  },
}
export default class Loading extends React.Component {    
  constructor(props){
      super(props);
      let screenSize = this._calculateDevice();
      this.state = {  offset:600,
                      cx:screenSize.width/2,
                      cy:screenSize.height/2,
                      r:50,
                  }
      this._unmount = this._unmount.bind(this);
  }  
  _calculateDevice() {
      let width = window.innerWidth
      || document.documentElement.clientWidth
      || document.body.clientWidth;

      let height = window.innerHeight
      || document.documentElement.clientHeight
      || document.body.clientHeight;
      return {width, height}
  } 
  componentDidMount (){
      this.interval = setInterval(() => {
                          const offset = this.state.offset - 50; 
                          this.setState({offset: offset });
                      },200);
  }
  componentWillUnmount() {
      clearInterval(this.interval); 
  }
  _unmount () {
      this.setState({loaded:true});
  }
  _circlePath (){
      let d = `M${this.state.cx},${this.state.cy}a${this.state.r},${this.state.r} 0 1,0 100,0a${this.state.r},${this.state.r} 0 1,0 -100,0`;
      return d
  }
  render (){
      let d = this._circlePath();
      let style = Object.assign({}, styles.circle, {'strokeDashoffset':this.state.offset});
      let svgStyle = styles.svg;
      return(  
          <svg style={svgStyle}>
              <path
                  stroke = "#AAA"
                  strokeWidth = "5px"
                  fill = "none" 
                  d = {d} 
              />
              <path
                  style = {style}
                  stroke = "#D22"
                  strokeWidth = "5px"
                  fill = "none" 
                  d = {d} 
              />
          </svg> 
      )
  } 
}   

Briefly explain

componentDidMount (){
  this.interval = setInterval(() => {
                      const offset = this.state.offset - 50; 
                      this.setState({offset: offset });
                  },200);
}

the function in the setInterval will update the offset and will also create new path.

_circlePath (){
  let d =   `M${this.state.cx},${this.state.cy}a${this.state.r},${this.state.r} 0 1,0 100,0a${this.state.r},${this.state.r} 0 1,0 -100,0`;
  return d
}

and this function will create the path which decide how the circle looks like in svg.

So we can use the changing of path to implement the effect of spinning circle

NOTICE

Due to the setInterval function

we need to remember to clear the interval before the component unmount

to avoid crash of setInterval on a component that doesn't exist.

Upvotes: 1

Related Questions