1. <!DOCTYPE html>
    
  2. <html style="width: 100%; height: 100%; overflow: hidden">
    
  3.   <head>
    
  4.     <meta charset="utf-8">
    
  5.     <title>Fiber Example</title>
    
  6.   </head>
    
  7.   <body>
    
  8.     <h1>Fiber Example</h1>
    
  9.     <div id="container">
    
  10.       <p>
    
  11.         To install React, follow the instructions on
    
  12.         <a href="https://github.com/facebook/react/">GitHub</a>.
    
  13.       </p>
    
  14.       <p>
    
  15.         If you can see this, React is <strong>not</strong> working right.
    
  16.         If you checked out the source from GitHub make sure to run <code>npm run build</code>.
    
  17.       </p>
    
  18.     </div>
    
  19.     <script src="../../build/oss-experimental/react/umd/react.development.js"></script>
    
  20.     <script src="../../build/oss-experimental/react-dom/umd/react-dom.development.js"></script>
    
  21.     <script src="https://unpkg.com/babel-standalone@6/babel.js"></script>
    
  22.     <script type="text/babel">
    
  23.       var dotStyle = {
    
  24.         position: 'absolute',
    
  25.         background: '#61dafb',
    
  26.         font: 'normal 15px sans-serif',
    
  27.         textAlign: 'center',
    
  28.         cursor: 'pointer',
    
  29.       };
    
  30. 
    
  31.       var containerStyle = {
    
  32.         position: 'absolute',
    
  33.         transformOrigin: '0 0',
    
  34.         left: '50%',
    
  35.         top: '50%',
    
  36.         width: '10px',
    
  37.         height: '10px',
    
  38.         background: '#eee',
    
  39.       };
    
  40. 
    
  41.       var targetSize = 25;
    
  42. 
    
  43.       class Dot extends React.Component {
    
  44.         constructor() {
    
  45.           super();
    
  46.           this.state = { hover: false };
    
  47.         }
    
  48.         enter() {
    
  49.           this.setState({
    
  50.             hover: true
    
  51.           });
    
  52.         }
    
  53.         leave() {
    
  54.           this.setState({
    
  55.             hover: false
    
  56.           });
    
  57.         }
    
  58.         render() {
    
  59.           var props = this.props;
    
  60.           var s = props.size * 1.3;
    
  61.           var style = {
    
  62.             ...dotStyle,
    
  63.             width: s + 'px',
    
  64.             height: s + 'px',
    
  65.             left: (props.x) + 'px',
    
  66.             top: (props.y) + 'px',
    
  67.             borderRadius: (s / 2) + 'px',
    
  68.             lineHeight: (s) + 'px',
    
  69.             background: this.state.hover ? '#ff0' : dotStyle.background
    
  70.           };
    
  71.           return (
    
  72.             <div style={style} onMouseEnter={() => this.enter()} onMouseLeave={() => this.leave()}>
    
  73.               {this.state.hover ? '*' + props.text + '*' : props.text}
    
  74.             </div>
    
  75.           );
    
  76.         }
    
  77.       }
    
  78. 
    
  79.       class SierpinskiTriangle extends React.Component {
    
  80.         shouldComponentUpdate(nextProps) {
    
  81.           var o = this.props;
    
  82.           var n = nextProps;
    
  83.           return !(
    
  84.             o.x === n.x &&
    
  85.             o.y === n.y &&
    
  86.             o.s === n.s &&
    
  87.             o.children === n.children
    
  88.           );
    
  89.         }
    
  90.         render() {
    
  91.           let {x, y, s, children} = this.props;
    
  92.           if (s <= targetSize) {
    
  93.             return (
    
  94.               <Dot
    
  95.                 x={x - (targetSize / 2)}
    
  96.                 y={y - (targetSize / 2)}
    
  97.                 size={targetSize}
    
  98.                 text={children}
    
  99.               />
    
  100.             );
    
  101.             return r;
    
  102.           }
    
  103.           var newSize = s / 2;
    
  104.           var slowDown = true;
    
  105.           if (slowDown) {
    
  106.             var e = performance.now() + 0.8;
    
  107.             while (performance.now() < e) {
    
  108.               // Artificially long execution time.
    
  109.             }
    
  110.           }
    
  111. 
    
  112.           s /= 2;
    
  113. 
    
  114.           return [
    
  115.             <SierpinskiTriangle x={x} y={y - (s / 2)} s={s}>
    
  116.               {children}
    
  117.             </SierpinskiTriangle>,
    
  118.             <SierpinskiTriangle x={x - s} y={y + (s / 2)} s={s}>
    
  119.               {children}
    
  120.             </SierpinskiTriangle>,
    
  121.             <SierpinskiTriangle x={x + s} y={y + (s / 2)} s={s}>
    
  122.               {children}
    
  123.             </SierpinskiTriangle>,
    
  124.           ];
    
  125.         }
    
  126.       }
    
  127. 
    
  128.       class ExampleApplication extends React.Component {
    
  129.         constructor() {
    
  130.           super();
    
  131.           this.state = {
    
  132.             seconds: 0,
    
  133.             useTimeSlicing: true,
    
  134.           };
    
  135.           this.tick = this.tick.bind(this);
    
  136.           this.onTimeSlicingChange = this.onTimeSlicingChange.bind(this);
    
  137.         }
    
  138.         componentDidMount() {
    
  139.           this.intervalID = setInterval(this.tick, 1000);
    
  140.         }
    
  141.         tick() {
    
  142.           if (this.state.useTimeSlicing) {
    
  143.             // Update is time-sliced.
    
  144.             ReactDOM.unstable_deferredUpdates(() => {
    
  145.               this.setState(state => ({ seconds: (state.seconds % 10) + 1 }));
    
  146.             });
    
  147.           } else {
    
  148.             // Update is not time-sliced. Causes demo to stutter.
    
  149.             this.setState(state => ({ seconds: (state.seconds % 10) + 1 }));
    
  150.           }
    
  151.         }
    
  152.         onTimeSlicingChange(value) {
    
  153.           this.setState(() => ({ useTimeSlicing: value }));
    
  154.         }
    
  155.         componentWillUnmount() {
    
  156.           clearInterval(this.intervalID);
    
  157.         }
    
  158.         render() {
    
  159.           const seconds = this.state.seconds;
    
  160.           const elapsed = this.props.elapsed;
    
  161.           const t = (elapsed / 1000) % 10;
    
  162.           const scale = 1 + (t > 5 ? 10 - t : t) / 10;
    
  163.           const transform = 'scaleX(' + (scale / 2.1) + ') scaleY(0.7) translateZ(0.1px)';
    
  164.           return (
    
  165.             <div>
    
  166.               <div>
    
  167.                 <h3>Time-slicing</h3>
    
  168.                 <p>Toggle this and observe the effect</p>
    
  169.                 <Toggle
    
  170.                   onLabel="On"
    
  171.                   offLabel="Off"
    
  172.                   onChange={this.onTimeSlicingChange}
    
  173.                   value={this.state.useTimeSlicing}
    
  174.                 />
    
  175.               </div>
    
  176.               <div style={{ ...containerStyle, transform }}>
    
  177.                 <div>
    
  178.                   <SierpinskiTriangle x={0} y={0} s={1000}>
    
  179.                     {this.state.seconds}
    
  180.                   </SierpinskiTriangle>
    
  181.                 </div>
    
  182.               </div>
    
  183.             </div>
    
  184.           );
    
  185.         }
    
  186.       }
    
  187. 
    
  188.       class Toggle extends React.Component {
    
  189.         constructor(props) {
    
  190.           super();
    
  191.           this.onChange = this.onChange.bind(this);
    
  192.         }
    
  193.         onChange(event) {
    
  194.           this.props.onChange(event.target.value === 'on');
    
  195.         }
    
  196.         render() {
    
  197.           const value = this.props.value;
    
  198.           return (
    
  199.             <label onChange={this.onChange}>
    
  200.               <label>
    
  201.                 {this.props.onLabel}
    
  202.                 <input type="radio" name="value" value="on" checked={value} />
    
  203.               </label>
    
  204.               <label>
    
  205.                 {this.props.offLabel}
    
  206.                 <input type="radio" name="value" value="off" checked={!value} />
    
  207.               </label>
    
  208.             </label>
    
  209.           );
    
  210.         }
    
  211.       }
    
  212. 
    
  213.       var start = new Date().getTime();
    
  214.       function update() {
    
  215.         ReactDOM.render(
    
  216.           <ExampleApplication elapsed={new Date().getTime() - start} />,
    
  217.           document.getElementById('container')
    
  218.         );
    
  219.         requestAnimationFrame(update);
    
  220.       }
    
  221.       requestAnimationFrame(update);
    
  222.     </script>
    
  223.   </body>
    
  224. </html>