fixtures/fiber-triangle/index.html (215 lines of code) (raw):

<!DOCTYPE html> <html style="width: 100%; height: 100%; overflow: hidden"> <head> <meta charset="utf-8"> <title>Fiber Example</title> </head> <body> <h1>Fiber Example</h1> <div id="container"> <p> To install React, follow the instructions on <a href="https://github.com/facebook/react/">GitHub</a>. </p> <p> If you can see this, React is <strong>not</strong> working right. If you checked out the source from GitHub make sure to run <code>npm run build</code>. </p> </div> <script src="../../build/node_modules/react/umd/react.development.js"></script> <script src="../../build/node_modules/react-dom/umd/react-dom.development.js"></script> <script src="https://unpkg.com/babel-standalone@6/babel.js"></script> <script type="text/babel"> var dotStyle = { position: 'absolute', background: '#61dafb', font: 'normal 15px sans-serif', textAlign: 'center', cursor: 'pointer', }; var containerStyle = { position: 'absolute', transformOrigin: '0 0', left: '50%', top: '50%', width: '10px', height: '10px', background: '#eee', }; var targetSize = 25; class Dot extends React.Component { constructor() { super(); this.state = { hover: false }; } enter() { this.setState({ hover: true }); } leave() { this.setState({ hover: false }); } render() { var props = this.props; var s = props.size * 1.3; var style = { ...dotStyle, width: s + 'px', height: s + 'px', left: (props.x) + 'px', top: (props.y) + 'px', borderRadius: (s / 2) + 'px', lineHeight: (s) + 'px', background: this.state.hover ? '#ff0' : dotStyle.background }; return ( <div style={style} onMouseEnter={() => this.enter()} onMouseLeave={() => this.leave()}> {this.state.hover ? '*' + props.text + '*' : props.text} </div> ); } } class SierpinskiTriangle extends React.Component { shouldComponentUpdate(nextProps) { var o = this.props; var n = nextProps; return !( o.x === n.x && o.y === n.y && o.s === n.s && o.children === n.children ); } render() { let {x, y, s, children} = this.props; if (s <= targetSize) { return ( <Dot x={x - (targetSize / 2)} y={y - (targetSize / 2)} size={targetSize} text={children} /> ); return r; } var newSize = s / 2; var slowDown = true; if (slowDown) { var e = performance.now() + 0.8; while (performance.now() < e) { // Artificially long execution time. } } s /= 2; return [ <SierpinskiTriangle x={x} y={y - (s / 2)} s={s}> {children} </SierpinskiTriangle>, <SierpinskiTriangle x={x - s} y={y + (s / 2)} s={s}> {children} </SierpinskiTriangle>, <SierpinskiTriangle x={x + s} y={y + (s / 2)} s={s}> {children} </SierpinskiTriangle>, ]; } } class ExampleApplication extends React.Component { constructor() { super(); this.state = { seconds: 0, useTimeSlicing: true, }; this.tick = this.tick.bind(this); this.onTimeSlicingChange = this.onTimeSlicingChange.bind(this); } componentDidMount() { this.intervalID = setInterval(this.tick, 1000); } tick() { if (this.state.useTimeSlicing) { // Update is time-sliced. ReactDOM.unstable_deferredUpdates(() => { this.setState(state => ({ seconds: (state.seconds % 10) + 1 })); }); } else { // Update is not time-sliced. Causes demo to stutter. this.setState(state => ({ seconds: (state.seconds % 10) + 1 })); } } onTimeSlicingChange(value) { this.setState(() => ({ useTimeSlicing: value })); } componentWillUnmount() { clearInterval(this.intervalID); } render() { const seconds = this.state.seconds; const elapsed = this.props.elapsed; const t = (elapsed / 1000) % 10; const scale = 1 + (t > 5 ? 10 - t : t) / 10; const transform = 'scaleX(' + (scale / 2.1) + ') scaleY(0.7) translateZ(0.1px)'; return ( <div> <div> <h3>Time-slicing</h3> <p>Toggle this and observe the effect</p> <Toggle onLabel="On" offLabel="Off" onChange={this.onTimeSlicingChange} value={this.state.useTimeSlicing} /> </div> <div style={{ ...containerStyle, transform }}> <div> <SierpinskiTriangle x={0} y={0} s={1000}> {this.state.seconds} </SierpinskiTriangle> </div> </div> </div> ); } } class Toggle extends React.Component { constructor(props) { super(); this.onChange = this.onChange.bind(this); } onChange(event) { this.props.onChange(event.target.value === 'on'); } render() { const value = this.props.value; return ( <label onChange={this.onChange}> <label> {this.props.onLabel} <input type="radio" name="value" value="on" checked={value} /> </label> <label> {this.props.offLabel} <input type="radio" name="value" value="off" checked={!value} /> </label> </label> ); } } var start = new Date().getTime(); function update() { ReactDOM.render( <ExampleApplication elapsed={new Date().getTime() - start} />, document.getElementById('container') ); requestAnimationFrame(update); } requestAnimationFrame(update); </script> </body> </html>