diff --git a/js/components/Visualizer.tsx b/js/components/Visualizer.tsx index b1e6f7c7..9fb2f753 100644 --- a/js/components/Visualizer.tsx +++ b/js/components/Visualizer.tsx @@ -1,4 +1,4 @@ -import React, { useMemo } from "react"; +import React, { useMemo, useCallback } from "react"; import * as Actions from "../actionCreators"; import * as Selectors from "../selectors"; @@ -8,6 +8,7 @@ import VisualizerInner from "./VisualizerInner"; const PIXEL_DENSITY = 2; const BAR_WIDTH = 3 * PIXEL_DENSITY; const GRADIENT_COLOR_COUNT = 16; +const PEAK_COLOR_INDEX = 23; type Props = { analyser: AnalyserNode; @@ -85,7 +86,6 @@ function preRenderBar( } return barCanvas; } - function Visualizer(props: Props) { const colors = useTypedSelector(Selectors.getSkinColors); const style = useTypedSelector(Selectors.getVisualizerStyle); @@ -115,6 +115,34 @@ function Visualizer(props: Props) { return preRenderBar(height, colors, renderHeight); }, [colors, height, renderHeight]); + const printBar = useCallback( + ( + ctx: CanvasRenderingContext2D, + x: number, + barHeight: number, + peakHeight: number + ) => { + barHeight = Math.ceil(barHeight) * PIXEL_DENSITY; + peakHeight = Math.ceil(peakHeight) * PIXEL_DENSITY; + if (barHeight > 0 || peakHeight > 0) { + const y = height - barHeight; + // Draw the gradient + const b = BAR_WIDTH; + if (height > 0) { + ctx.drawImage(barCanvas, 0, y, b, height, x, y, b, height); + } + + // Draw the gray peak line + if (!windowShade) { + const peakY = height - peakHeight; + ctx.fillStyle = colors[PEAK_COLOR_INDEX]; + ctx.fillRect(x, peakY, b, PIXEL_DENSITY); + } + } + }, + [barCanvas, colors, height, windowShade] + ); + const innerProps = { width: renderWidth, height: renderHeight, @@ -126,6 +154,7 @@ function Visualizer(props: Props) { toggleVisualizerStyle, bgCanvas, barCanvas, + printBar, }; return ; } diff --git a/js/components/VisualizerInner.js b/js/components/VisualizerInner.js index a231ad59..9b354a24 100644 --- a/js/components/VisualizerInner.js +++ b/js/components/VisualizerInner.js @@ -6,7 +6,6 @@ const PIXEL_DENSITY = 2; const NUM_BARS = 20; const BAR_WIDTH = 3 * PIXEL_DENSITY; const BAR_PEAK_DROP_RATE = 0.01; -const PEAK_COLOR_INDEX = 23; // Return the average value in a slice of dataArray function sliceAverage(dataArray, sliceWidth, sliceNumber) { @@ -54,7 +53,7 @@ class VisualizerInner extends React.Component { if (this.props.status === MEDIA_STATUS.PLAYING) { if (this.props.dummyVizData) { Object.keys(this.props.dummyVizData).forEach((i) => { - this._printBar(i, this.props.dummyVizData[i]); + this.props.printBar(this.canvasCtx, i, this.props.dummyVizData[i]); }); } else { this.paintFrame(); @@ -168,27 +167,6 @@ class VisualizerInner extends React.Component { this.canvasCtx.stroke(); } - _printBar(x, height, peakHeight) { - height = Math.ceil(height) * PIXEL_DENSITY; - peakHeight = Math.ceil(peakHeight) * PIXEL_DENSITY; - if (height > 0 || peakHeight > 0) { - const y = this._height() - height; - const ctx = this.canvasCtx; - // Draw the gradient - const b = BAR_WIDTH; - if (height > 0) { - ctx.drawImage(this.props.barCanvas, 0, y, b, height, x, y, b, height); - } - - // Draw the gray peak line - if (!this.props.windowShade) { - const peakY = this._height() - peakHeight; - ctx.fillStyle = this.props.colors[PEAK_COLOR_INDEX]; - ctx.fillRect(x, peakY, b, PIXEL_DENSITY); - } - } - } - _paintBarFrame() { this.props.analyser.getByteFrequencyData(this.dataArray); const heightMultiplier = this._renderHeight() / 256; @@ -214,7 +192,8 @@ class VisualizerInner extends React.Component { } this.barPeaks[j] = barPeak; - this._printBar( + this.props.printBar( + this.canvasCtx, j * xOffset, amplitude * heightMultiplier, barPeak * heightMultiplier