Fix some subtle eq graph alignment issues

This commit is contained in:
Jordan Eldredge 2017-10-12 15:17:33 -07:00
parent 68f3d7b91c
commit 08a347bb5e
4 changed files with 24 additions and 50 deletions

View file

@ -105,7 +105,6 @@ function setEqFromFile(file) {
const eqf = parser(arrayBuffer);
const preset = eqf.presets[0];
// TODO: Fix normalize. Currently these numbers are kinda wrong.
dispatch(setPreamp(normalize(preset.preamp)));
BANDS.forEach(band => {
dispatch(setEqBand(band, normalize(preset[`hz${band}`])));

View file

@ -1,17 +1,10 @@
import React from "react";
import { connect } from "react-redux";
import { getCurvePoints } from "cardinal-spline-js";
import { rebound } from "../../utils";
import { percentToRange, clamp } from "../../utils";
import { BANDS } from "../../constants";
export const roundToEven = value => 2 * Math.round(value / 2);
// The line is two pixels wide, and sits "above" the offset specified. So we use 30 not 32 as our max.
const reboundTo32 = rebound(1, 100, 0, 30);
export const getY = value => roundToEven(reboundTo32(value));
class EqGraph extends React.Component {
constructor(props) {
super(props);
@ -88,19 +81,25 @@ class EqGraph extends React.Component {
this.canvasCtx.strokeStyle = this.state.colorPattern;
this.canvasCtx.lineWidth = 2;
this.canvasCtx.beginPath();
const paddingLeft = 4;
const paddingLeft = 4; // TODO: This should be 3
const points = amplitudes.reduce(
(prev, value, i) => prev.concat(paddingLeft + i * 16, getY(100 - value)),
[]
);
const min = 1;
const max = 31;
const points = amplitudes.reduce((prev, value, i) => {
const percent = (100 - value) / 100;
const y = percentToRange(percent, min, max);
return prev.concat(paddingLeft + i * 16, y);
}, []);
// Spline between points in order to create nice curves
const tension = 0.5;
const resolution = 4; // Points in each segment
const smoothPoints = getCurvePoints(points, tension, resolution);
for (let i = 0; i < smoothPoints.length; i += 2) {
this.canvasCtx.lineTo(smoothPoints[i], smoothPoints[i + 1]);
// Splining can push peaks out of bounds. So we fudge them back in.
const y = clamp(smoothPoints[i + 1], min, max);
this.canvasCtx.lineTo(smoothPoints[i], y);
}
this.canvasCtx.stroke();
@ -112,7 +111,7 @@ class EqGraph extends React.Component {
// The skin has not finished loading yet
return;
}
const preampValue = getY(this.props.preamp);
const preampValue = percentToRange(this.props.preamp / 100, 0, 30);
this.canvasCtx.drawImage(
this.state.preampLineImg,
0,

View file

@ -1,23 +0,0 @@
import { roundToEven } from "./EqGraph";
describe("roundToEven", () => {
it("leaves even numbers as is", () => {
const actual = roundToEven(4);
const expected = 4;
expect(actual).toEqual(expected);
});
it("handles zero", () => {
const actual = roundToEven(0);
const expected = 0;
expect(actual).toEqual(expected);
});
it("handles odd numbers", () => {
const actual = roundToEven(3);
const expected = 4;
expect(actual).toEqual(expected);
});
});
describe("getY", () => {
it("gives the first sprite", () => {});
});

View file

@ -68,10 +68,16 @@ export function downloadURI(uri, name) {
window.document.body.removeChild(link);
}
export const rebound = (oldMin, oldMax, newMin, newMax) => oldValue =>
Math.round(
(oldValue - oldMin) * (newMax - newMin) / (oldMax - oldMin) + newMin
);
export const toPercent = (min, max, value) => (value - min) / (max - min);
export const percentToRange = (percent, min, max) =>
min + Math.round(percent * (max - min));
export const percentToIndex = (percent, length) =>
percentToRange(percent, 0, length - 1);
const rebound = (oldMin, oldMax, newMin, newMax) => oldValue =>
percentToRange(toPercent(oldMin, oldMax, oldValue), newMin, newMax);
// Convert a .eqf value to a 1-100
export const normalize = rebound(1, 64, 1, 100);
@ -92,13 +98,6 @@ export const merge = (target, source) => {
return target;
};
export const toPercent = (min, max, value) => (value - min) / (max - min);
export const percentToIndex = (percent, length) =>
Math.min(
Math.floor(percent * length),
length - 1 // Special case for 100%
);
// Maps a value in a range (defined my min/max) to a value in an array (options).
export const segment = (min, max, value, newValues) => {
const ratio = toPercent(min, max, value);