Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="author" content="https://github.com/josdejong/">
  
  <title>Render dynamic SVG's with React</title>
  <style>
    body {
      font-family: verdana, sans-serif;
    }
    #container {
      width: 100%;
      text-align: center;
    }
    #smiley {
      display: inline-block;
      background: #fffdae;
    }
  </style>
  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.6.15/browser.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.6.15/browser-polyfill.min.js"></script>
  <script type="text/babel">
    "use strict";
    class Smiley extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          x: 0,
          y: 0
        }
      }
      render() {
        let radius = Math.min(this.props.width, this.props.height) / 2;
        let strokeWidth = radius / 20;
        let cx = this.props.width / 2;
        let cy = this.props.height / 2;
        return <svg ref="svg" {...this.props} onMouseMove={this.handleMouseMove.bind(this)}>
          {this.renderHead(cx, cy, radius, strokeWidth)}
          {this.renderEye(cx - radius/3, cy - radius/5, radius/4, strokeWidth)}
          {this.renderEye(cx + radius/3, cy - radius/5, radius/4, strokeWidth)}
          {this.renderMouth(cx - 0.6 * radius, 1.3 * radius, 1.2 * radius, strokeWidth)}
        </svg>;
      }
      renderHead (cx, cy, radius, strokeWidth) {
        return <circle cx={cx} cy={cy} r={radius - 10} fill="gold" stroke="black" strokeWidth={strokeWidth} />;
      }
      renderEye (cx, cy, radius, strokeWidth) {
        let angle = Math.atan2(this.state.y - cy, this.state.x - cx); // angle
        let bcx = cx + radius / 2 * Math.cos(angle);
        let bcy = cy + radius / 2 * Math.sin(angle);
        return [
          <circle key="eye"     cx={cx}  cy={cy}  r={radius}   fill="white" stroke="black" strokeWidth={strokeWidth} />,
          <circle key="eyeball" cx={bcx} cy={bcy} r={radius/2} fill="black"/>
        ];
      }
      renderMouth (left, top, width, strokeWidth) {
        let bottom = top + width * 2/5;
        let path = `M${left} ${top} C ${left + 0.25*width} ${bottom}, ${left + 0.75*width} ${bottom}, ${left+width} ${top}`;
        return <path d={path} stroke="black" strokeWidth={strokeWidth} fill="transparent"/>;
      }
      handleMouseMove (event) {
        let svg = React.findDOMNode(this.refs.svg);
        let rect = svg.getBoundingClientRect();
        this.setState({
          x: event.clientX - rect.left,
          y: event.clientY - rect.top
        });
      }
    }
    React.render( <Smiley width="600" height="400" />, document.getElementById('smiley'));
  </script>
</head>
<body>
  <div id="container">
    <h1>Render dynamic SVG's with React</h1>
    <p>move your mouse over the smiley below...</p>
    <div id="smiley"></div>
    <p>Have fun!</p>
  </div>
</body>
</html>
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
josdejongpro
0viewers