mirror of
https://github.com/captbaritone/webamp.git
synced 2026-07-25 02:57:30 +00:00
Type preRenderBar
This commit is contained in:
parent
dd36504ad6
commit
fe90c1bacd
2 changed files with 51 additions and 47 deletions
|
|
@ -6,6 +6,8 @@ import { useTypedSelector, useActionCreator } from "../hooks";
|
|||
import VisualizerInner from "./VisualizerInner";
|
||||
|
||||
const PIXEL_DENSITY = 2;
|
||||
const BAR_WIDTH = 3 * PIXEL_DENSITY;
|
||||
const GRADIENT_COLOR_COUNT = 16;
|
||||
|
||||
type Props = {
|
||||
analyser: AnalyserNode;
|
||||
|
|
@ -18,7 +20,7 @@ function preRenderBg(
|
|||
bgColor: string,
|
||||
fgColor: string,
|
||||
windowShade: boolean
|
||||
) {
|
||||
): HTMLCanvasElement {
|
||||
// Off-screen canvas for pre-rendering the background
|
||||
const bgCanvas = document.createElement("canvas");
|
||||
bgCanvas.width = width;
|
||||
|
|
@ -42,6 +44,48 @@ function preRenderBg(
|
|||
return bgCanvas;
|
||||
}
|
||||
|
||||
function preRenderBar(
|
||||
height: number,
|
||||
colors: string[],
|
||||
renderHeight: number
|
||||
): HTMLCanvasElement {
|
||||
/**
|
||||
* The order of the colours is commented in the file: the fist two colours
|
||||
* define the background and dots (check it to see what are the dots), the
|
||||
* next 16 colours are the analyzer's colours from top to bottom, the next
|
||||
* 5 colours are the oscilloscope's ones, from center to top/bottom, the
|
||||
* last colour is for the analyzer's peak markers.
|
||||
*/
|
||||
|
||||
// Off-screen canvas for pre-rendering a single bar gradient
|
||||
const barCanvas = document.createElement("canvas");
|
||||
barCanvas.width = BAR_WIDTH;
|
||||
barCanvas.height = height;
|
||||
|
||||
const offset = 2; // The first two colors are for the background;
|
||||
const gradientColors = colors.slice(offset, offset + GRADIENT_COLOR_COUNT);
|
||||
|
||||
const barCanvasCtx = barCanvas.getContext("2d");
|
||||
if (barCanvasCtx == null) {
|
||||
throw new Error("Could not construct canvas context");
|
||||
}
|
||||
const multiplier = GRADIENT_COLOR_COUNT / renderHeight;
|
||||
// In shade mode, the five colors are, from top to bottom:
|
||||
// 214, 102, 0 -- 3
|
||||
// 222, 165, 24 -- 6
|
||||
// 148, 222, 33 -- 9
|
||||
// 57, 181, 16 -- 12
|
||||
// 24, 132, 8 -- 15
|
||||
// TODO: This could probably be improved by iterating backwards
|
||||
for (let i = 0; i < renderHeight; i++) {
|
||||
const colorIndex = GRADIENT_COLOR_COUNT - 1 - Math.floor(i * multiplier);
|
||||
barCanvasCtx.fillStyle = gradientColors[colorIndex];
|
||||
const y = height - i * PIXEL_DENSITY;
|
||||
barCanvasCtx.fillRect(0, y, BAR_WIDTH, PIXEL_DENSITY);
|
||||
}
|
||||
return barCanvas;
|
||||
}
|
||||
|
||||
function Visualizer(props: Props) {
|
||||
const colors = useTypedSelector(Selectors.getSkinColors);
|
||||
const style = useTypedSelector(Selectors.getVisualizerStyle);
|
||||
|
|
@ -67,6 +111,10 @@ function Visualizer(props: Props) {
|
|||
);
|
||||
}, [colors, height, width, windowShade]);
|
||||
|
||||
const barCanvas = useMemo(() => {
|
||||
return preRenderBar(height, colors, renderHeight);
|
||||
}, [colors, height, renderHeight]);
|
||||
|
||||
const innerProps = {
|
||||
width: renderWidth,
|
||||
height: renderHeight,
|
||||
|
|
@ -77,6 +125,7 @@ function Visualizer(props: Props) {
|
|||
dummyVizData,
|
||||
toggleVisualizerStyle,
|
||||
bgCanvas,
|
||||
barCanvas,
|
||||
};
|
||||
return <VisualizerInner {...innerProps} {...props} />;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 GRADIENT_COLOR_COUNT = 16;
|
||||
const PEAK_COLOR_INDEX = 23;
|
||||
|
||||
// Return the average value in a slice of dataArray
|
||||
|
|
@ -40,40 +39,6 @@ function octaveBucketsForBufferLength(bufferLength) {
|
|||
|
||||
return octaveBuckets;
|
||||
}
|
||||
function preRenderBar(height, colors, renderHeight) {
|
||||
/**
|
||||
* The order of the colours is commented in the file: the fist two colours
|
||||
* define the background and dots (check it to see what are the dots), the
|
||||
* next 16 colours are the analyzer's colours from top to bottom, the next
|
||||
* 5 colours are the oscilloscope's ones, from center to top/bottom, the
|
||||
* last colour is for the analyzer's peak markers.
|
||||
*/
|
||||
|
||||
// Off-screen canvas for pre-rendering a single bar gradient
|
||||
const barCanvas = document.createElement("canvas");
|
||||
barCanvas.width = BAR_WIDTH;
|
||||
barCanvas.height = height;
|
||||
|
||||
const offset = 2; // The first two colors are for the background;
|
||||
const gradientColors = colors.slice(offset, offset + GRADIENT_COLOR_COUNT);
|
||||
|
||||
const barCanvasCtx = barCanvas.getContext("2d");
|
||||
const multiplier = GRADIENT_COLOR_COUNT / renderHeight;
|
||||
// In shade mode, the five colors are, from top to bottom:
|
||||
// 214, 102, 0 -- 3
|
||||
// 222, 165, 24 -- 6
|
||||
// 148, 222, 33 -- 9
|
||||
// 57, 181, 16 -- 12
|
||||
// 24, 132, 8 -- 15
|
||||
// TODO: This could probably be improved by iterating backwards
|
||||
for (let i = 0; i < renderHeight; i++) {
|
||||
const colorIndex = GRADIENT_COLOR_COUNT - 1 - Math.floor(i * multiplier);
|
||||
barCanvasCtx.fillStyle = gradientColors[colorIndex];
|
||||
const y = height - i * PIXEL_DENSITY;
|
||||
barCanvasCtx.fillRect(0, y, BAR_WIDTH, PIXEL_DENSITY);
|
||||
}
|
||||
return barCanvas;
|
||||
}
|
||||
|
||||
class VisualizerInner extends React.Component {
|
||||
componentDidMount() {
|
||||
|
|
@ -134,7 +99,6 @@ class VisualizerInner extends React.Component {
|
|||
}
|
||||
// TODO: Split this into to methods. One for skin update, one for style
|
||||
// update.
|
||||
this.preRenderBar();
|
||||
this.props.analyser.fftSize = 2048;
|
||||
if (this.props.style === VISUALIZERS.OSCILLOSCOPE) {
|
||||
this.bufferLength = this.props.analyser.fftSize;
|
||||
|
|
@ -149,15 +113,6 @@ class VisualizerInner extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
// Pre-render the bar gradient
|
||||
preRenderBar() {
|
||||
this.barCanvas = preRenderBar(
|
||||
this._height(),
|
||||
this.props.colors,
|
||||
this._renderHeight()
|
||||
);
|
||||
}
|
||||
|
||||
paintFrame() {
|
||||
switch (this.props.style) {
|
||||
case VISUALIZERS.OSCILLOSCOPE:
|
||||
|
|
@ -222,7 +177,7 @@ class VisualizerInner extends React.Component {
|
|||
// Draw the gradient
|
||||
const b = BAR_WIDTH;
|
||||
if (height > 0) {
|
||||
ctx.drawImage(this.barCanvas, 0, y, b, height, x, y, b, height);
|
||||
ctx.drawImage(this.props.barCanvas, 0, y, b, height, x, y, b, height);
|
||||
}
|
||||
|
||||
// Draw the gray peak line
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue