mirror of
https://github.com/captbaritone/webamp.git
synced 2026-01-23 18:25:30 +00:00
Make a best effort to prewarm the images needed for the eq graph
This commit is contained in:
parent
d73a742685
commit
2dca07ff0a
4 changed files with 77 additions and 33 deletions
|
|
@ -3,6 +3,7 @@ import { connect } from "react-redux";
|
|||
import { percentToRange, clamp } from "../../utils";
|
||||
import { BANDS } from "../../constants";
|
||||
import spline from "./spline";
|
||||
import * as Selectros from "../../selectors";
|
||||
|
||||
const GRAPH_HEIGHT = 19;
|
||||
const GRAPH_WIDTH = 113;
|
||||
|
|
@ -18,12 +19,8 @@ class EqGraph extends React.Component {
|
|||
this.width = Number(this.canvas.width);
|
||||
this.height = Number(this.canvas.height);
|
||||
|
||||
if (this.props.lineColorsImage) {
|
||||
this.createColorPattern(this.props.lineColorsImage);
|
||||
}
|
||||
if (this.props.preampLineUrl) {
|
||||
this.createPreampLineImage(this.props.preampLineUrl);
|
||||
}
|
||||
this.createColorPattern(this.props.lineColorsImagePromise);
|
||||
this.createPreampLineImage(this.props.preampLineImagePromise);
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
|
|
@ -33,37 +30,35 @@ class EqGraph extends React.Component {
|
|||
}
|
||||
|
||||
shouldComponentUpdate(nextProps) {
|
||||
if (this.props.lineColorsImage !== nextProps.lineColorsImage) {
|
||||
this.createColorPattern(nextProps.lineColorsImage);
|
||||
if (
|
||||
this.props.lineColorsImagePromise !== nextProps.lineColorsImagePromise
|
||||
) {
|
||||
this.createColorPattern(nextProps.lineColorsImagePromise);
|
||||
}
|
||||
if (this.props.preampLineUrl !== nextProps.preampLineUrl) {
|
||||
this.createPreampLineImage(nextProps.preampLineUrl);
|
||||
if (
|
||||
this.props.preampLineImagePromise !== nextProps.preampLineImagePromise
|
||||
) {
|
||||
this.createPreampLineImage(nextProps.preampLineImagePromise);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
createPreampLineImage(preampLineUrl) {
|
||||
const preampLineImg = new Image();
|
||||
preampLineImg.onload = () => {
|
||||
this.setState({ preampLineImg });
|
||||
};
|
||||
preampLineImg.src = preampLineUrl;
|
||||
async createPreampLineImage(preampLineImagePromise) {
|
||||
const preampLineImg = await preampLineImagePromise;
|
||||
this.setState({ preampLineImg });
|
||||
}
|
||||
|
||||
createColorPattern(lineColorsImage) {
|
||||
const bgImage = new Image();
|
||||
bgImage.onload = () => {
|
||||
const { width, height } = bgImage;
|
||||
const colorsCanvas = document.createElement("canvas");
|
||||
const colorsCtx = colorsCanvas.getContext("2d");
|
||||
colorsCanvas.width = width;
|
||||
colorsCanvas.height = height;
|
||||
colorsCtx.drawImage(bgImage, 0, 0, width, height);
|
||||
this.setState({
|
||||
colorPattern: this.canvasCtx.createPattern(colorsCanvas, "repeat-x"),
|
||||
});
|
||||
};
|
||||
bgImage.src = lineColorsImage;
|
||||
async createColorPattern(lineColorsImagePromise) {
|
||||
const bgImage = await lineColorsImagePromise;
|
||||
const { width, height } = bgImage;
|
||||
const colorsCanvas = document.createElement("canvas");
|
||||
const colorsCtx = colorsCanvas.getContext("2d");
|
||||
colorsCanvas.width = width;
|
||||
colorsCanvas.height = height;
|
||||
colorsCtx.drawImage(bgImage, 0, 0, width, height);
|
||||
this.setState({
|
||||
colorPattern: this.canvasCtx.createPattern(colorsCanvas, "repeat-x"),
|
||||
});
|
||||
}
|
||||
|
||||
drawEqLine() {
|
||||
|
|
@ -136,6 +131,11 @@ class EqGraph extends React.Component {
|
|||
|
||||
export default connect(state => ({
|
||||
...state.equalizer.sliders,
|
||||
lineColorsImage: state.display.skinImages.EQ_GRAPH_LINE_COLORS,
|
||||
preampLineUrl: state.display.skinImages.EQ_PREAMP_LINE,
|
||||
// WebampLazy.skinIsLoaded() makes an effort to ensure that these promises are
|
||||
// already resolved before our initial render. This means our setStates
|
||||
// should get called on a microtask and we should rerender with this loaded
|
||||
// before we paint.
|
||||
// This does not work when loading skins after initial render.
|
||||
lineColorsImagePromise: Selectros.getLineColorsImage(state),
|
||||
preampLineImagePromise: Selectros.getPreampLineImage(state),
|
||||
}))(EqGraph);
|
||||
|
|
|
|||
|
|
@ -718,3 +718,25 @@ export function getPresetsAreCycling(state: AppState): boolean {
|
|||
export function getRandomizePresets(state: AppState): boolean {
|
||||
return state.milkdrop.randomize;
|
||||
}
|
||||
|
||||
export function getPreampLineUrl(state: AppState): string {
|
||||
return state.display.skinImages.EQ_PREAMP_LINE;
|
||||
}
|
||||
|
||||
export function getLineColorsUrl(state: AppState): string {
|
||||
return state.display.skinImages.EQ_GRAPH_LINE_COLORS;
|
||||
}
|
||||
|
||||
export const getPreampLineImage = createSelector(
|
||||
getPreampLineUrl,
|
||||
async (url): Promise<HTMLImageElement> => {
|
||||
return Utils.imgFromUrl(url);
|
||||
}
|
||||
);
|
||||
|
||||
export const getLineColorsImage = createSelector(
|
||||
getLineColorsUrl,
|
||||
async (url): Promise<HTMLImageElement> => {
|
||||
return Utils.imgFromUrl(url);
|
||||
}
|
||||
);
|
||||
|
|
|
|||
11
js/utils.ts
11
js/utils.ts
|
|
@ -14,6 +14,17 @@ interface IniData {
|
|||
};
|
||||
}
|
||||
|
||||
export function imgFromUrl(url: string): Promise<HTMLImageElement> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
resolve(img);
|
||||
};
|
||||
img.onerror = reject;
|
||||
img.src = url;
|
||||
});
|
||||
}
|
||||
|
||||
export const getTimeObj = (time: number | null): Time => {
|
||||
if (time == null) {
|
||||
// If we clean up `<MiniTime />` we don't need to do this any more.
|
||||
|
|
|
|||
|
|
@ -390,7 +390,18 @@ class Winamp {
|
|||
async skinIsLoaded(): Promise<void> {
|
||||
// Wait for the skin to load.
|
||||
// TODO #leak
|
||||
return storeHas(this.store, state => !state.display.loading);
|
||||
await storeHas(this.store, state => !state.display.loading);
|
||||
// We attempt to pre-resolve these promises before we declare the skin
|
||||
// loaded. That's because `<EqGraph>` needs these in order to render fully.
|
||||
// As long as these are resolved before we attempt to render, we can ensure
|
||||
// that we will have all the data we need on first paint.
|
||||
//
|
||||
// Note: This won't help for non-initial skin loads.
|
||||
await Promise.all([
|
||||
Selectors.getPreampLineImage(this.store.getState()),
|
||||
Selectors.getLineColorsImage(this.store.getState()),
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
__loadSerializedState(serializedState: SerializedStateV1): void {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue