From dd36504ad6b92a6dd753b01b8e14fa07a4ee3479 Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Tue, 7 Apr 2020 21:58:00 -0700 Subject: [PATCH] Type preRenderBg --- js/components/Visualizer.tsx | 57 +++++++++++++++++++++++++++++--- js/components/VisualizerInner.js | 42 ++--------------------- 2 files changed, 55 insertions(+), 44 deletions(-) diff --git a/js/components/Visualizer.tsx b/js/components/Visualizer.tsx index 15432572..55b8ce6c 100644 --- a/js/components/Visualizer.tsx +++ b/js/components/Visualizer.tsx @@ -1,14 +1,47 @@ -import React from "react"; +import React, { useMemo } from "react"; import * as Actions from "../actionCreators"; import * as Selectors from "../selectors"; import { useTypedSelector, useActionCreator } from "../hooks"; import VisualizerInner from "./VisualizerInner"; +const PIXEL_DENSITY = 2; + type Props = { analyser: AnalyserNode; }; +// Pre-render the background grid +function preRenderBg( + width: number, + height: number, + bgColor: string, + fgColor: string, + windowShade: boolean +) { + // Off-screen canvas for pre-rendering the background + const bgCanvas = document.createElement("canvas"); + bgCanvas.width = width; + bgCanvas.height = height; + const distance = 2 * PIXEL_DENSITY; + + const bgCanvasCtx = bgCanvas.getContext("2d"); + if (bgCanvasCtx == null) { + throw new Error("Could not construct canvas context"); + } + bgCanvasCtx.fillStyle = bgColor; + bgCanvasCtx.fillRect(0, 0, width, height); + if (!windowShade) { + bgCanvasCtx.fillStyle = fgColor; + for (let x = 0; x < width; x += distance) { + for (let y = PIXEL_DENSITY; y < height; y += distance) { + bgCanvasCtx.fillRect(x, y, PIXEL_DENSITY, PIXEL_DENSITY); + } + } + } + return bgCanvas; +} + function Visualizer(props: Props) { const colors = useTypedSelector(Selectors.getSkinColors); const style = useTypedSelector(Selectors.getVisualizerStyle); @@ -17,17 +50,33 @@ function Visualizer(props: Props) { const dummyVizData = useTypedSelector(Selectors.getDummyVizData); const toggleVisualizerStyle = useActionCreator(Actions.toggleVisualizerStyle); - const windowShade = getWindowShade("main"); + const renderWidth = windowShade ? 38 : 76; + const renderHeight = windowShade ? 5 : 16; + + const width = renderWidth * PIXEL_DENSITY; + const height = renderHeight * PIXEL_DENSITY; + + const bgCanvas = useMemo(() => { + return preRenderBg( + width, + height, + colors[0], + colors[1], + Boolean(windowShade) + ); + }, [colors, height, width, windowShade]); + const innerProps = { + width: renderWidth, + height: renderHeight, colors, style, - width: windowShade ? 38 : 76, - height: windowShade ? 5 : 16, status, windowShade, dummyVizData, toggleVisualizerStyle, + bgCanvas, }; return ; } diff --git a/js/components/VisualizerInner.js b/js/components/VisualizerInner.js index ba4fa48d..e5cbcaee 100644 --- a/js/components/VisualizerInner.js +++ b/js/components/VisualizerInner.js @@ -1,9 +1,6 @@ import React from "react"; -import * as Actions from "../actionCreators"; -import * as Selectors from "../selectors"; import { VISUALIZERS, MEDIA_STATUS } from "../constants"; -import { useTypedSelector, useActionCreator } from "../hooks"; const PIXEL_DENSITY = 2; const NUM_BARS = 20; @@ -43,29 +40,6 @@ function octaveBucketsForBufferLength(bufferLength) { return octaveBuckets; } - -// Pre-render the background grid -function preRenderBg(width, height, bgColor, fgColor, windowShade) { - // Off-screen canvas for pre-rendering the background - const bgCanvas = document.createElement("canvas"); - bgCanvas.width = width; - bgCanvas.height = height; - const distance = 2 * PIXEL_DENSITY; - - const bgCanvasCtx = bgCanvas.getContext("2d"); - bgCanvasCtx.fillStyle = bgColor; - bgCanvasCtx.fillRect(0, 0, width, height); - if (!windowShade) { - bgCanvasCtx.fillStyle = fgColor; - for (let x = 0; x < width; x += distance) { - for (let y = PIXEL_DENSITY; y < height; y += distance) { - bgCanvasCtx.fillRect(x, y, PIXEL_DENSITY, PIXEL_DENSITY); - } - } - } - return bgCanvas; -} - function preRenderBar(height, colors, renderHeight) { /** * The order of the colours is commented in the file: the fist two colours @@ -160,7 +134,6 @@ class VisualizerInner extends React.Component { } // TODO: Split this into to methods. One for skin update, one for style // update. - this.preRenderBg(); this.preRenderBar(); this.props.analyser.fftSize = 2048; if (this.props.style === VISUALIZERS.OSCILLOSCOPE) { @@ -176,17 +149,6 @@ class VisualizerInner extends React.Component { } } - // Pre-render the background grid - preRenderBg() { - this.bgCanvas = preRenderBg( - this._width(), - this._height(), - this.props.colors[0], - this.props.colors[1], - this.props.windowShade - ); - } - // Pre-render the bar gradient preRenderBar() { this.barCanvas = preRenderBar( @@ -199,11 +161,11 @@ class VisualizerInner extends React.Component { paintFrame() { switch (this.props.style) { case VISUALIZERS.OSCILLOSCOPE: - this.canvasCtx.drawImage(this.bgCanvas, 0, 0); + this.canvasCtx.drawImage(this.props.bgCanvas, 0, 0); this._paintOscilloscopeFrame(); break; case VISUALIZERS.BAR: - this.canvasCtx.drawImage(this.bgCanvas, 0, 0); + this.canvasCtx.drawImage(this.props.bgCanvas, 0, 0); this._paintBarFrame(); break; default: