showcases/ascii/app.js (122 lines of code) (raw):

/* global window,document */ import React, {Component} from 'react'; import {render} from 'react-dom'; import DeckGL, {OrthographicView} from 'deck.gl'; import {isWebGL2} from 'luma.gl'; import ControlPanel from './components/control-panel'; import AsciiLayer from './ascii-layer/ascii-layer'; class Root extends Component { constructor(props) { super(props); this.state = { width: 500, height: 500, settings: { fontFamily: 'Monaco', isPlaying: true, sizeScale: 1, videoSource: 0 }, timestamp: Date.now(), webgl2Supported: true, videoLoading: true }; this._onResize = this._onResize.bind(this); this._onUpdate = this._onUpdate.bind(this); this._onLoad = this._onLoad.bind(this); this._onInitialize = this._onInitialize.bind(this); this._updateSettings = this._updateSettings.bind(this); } componentDidMount() { this._onResize(); window.addEventListener('resize', this._onResize); this._timer = window.requestAnimationFrame(this._onUpdate); } componentWillUnmount() { window.removeEventListener('resize', this._onResize); window.cancelAnimationFrame(this._timer); } _onResize() { this.setState({ width: window.innerWidth, height: window.innerHeight }); } _onUpdate() { if (this.state.settings.isPlaying) { this.setState({ timestamp: Date.now() }); } this._timer = window.requestAnimationFrame(this._onUpdate); } _onLoad(video) { if (video) { video.crossOrigin = 'anonymouse'; } this._video = video; } _onInitialize(gl) { this.setState({ webgl2Supported: isWebGL2(gl) }); } _updateSettings(settings) { this.setState({ settings: {...this.state.settings, ...settings} }); } _renderDeckGLOverlay({width, height, video}) { const {timestamp, settings} = this.state; return ( <DeckGL width={width || 1} height={height || 1} views={new OrthographicView()} onWebGLInitialized={this._onInitialize} > <AsciiLayer id="video" video={video} timestamp={timestamp} fontFamily={settings.fontFamily} sizeScale={settings.sizeScale} /> </DeckGL> ); } render() { const {width, height, settings, webgl2Supported} = this.state; if (!webgl2Supported) { return <div className="warning">WebGL2 is not supported in your browser.</div>; } let canvasWidth = 0; let canvasHeight = 0; let canvasStyle = null; if (this._video && this._video.videoWidth) { const {videoWidth, videoHeight} = this._video; const scale = Math.min(width / videoWidth, height / videoHeight); canvasWidth = videoWidth * scale; canvasHeight = videoHeight * scale; canvasStyle = { width: canvasWidth, height: canvasHeight, top: (height - canvasHeight) / 2, left: (width - canvasWidth) / 2 }; } return ( <div id="app-container"> <video autoPlay loop id="source-video" ref={this._onLoad} /> <div id="canvas-wrapper" style={canvasStyle}> {this._renderDeckGLOverlay({ width: canvasWidth, height: canvasHeight, video: this._video })} </div> <ControlPanel {...settings} video={this._video} updateSettings={this._updateSettings} /> </div> ); } } render(<Root />, document.body.appendChild(document.createElement('div')));