From 08a347bb5e26f7d6782d2bb1c86d69173f93259c Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Thu, 12 Oct 2017 15:17:33 -0700 Subject: [PATCH] Fix some subtle eq graph alignment issues --- js/actionCreators.js | 1 - js/components/EqualizerWindow/EqGraph.js | 29 +++++++++---------- js/components/EqualizerWindow/EqGraph.test.js | 23 --------------- js/utils.js | 21 +++++++------- 4 files changed, 24 insertions(+), 50 deletions(-) delete mode 100644 js/components/EqualizerWindow/EqGraph.test.js diff --git a/js/actionCreators.js b/js/actionCreators.js index 3c423825..71709c54 100644 --- a/js/actionCreators.js +++ b/js/actionCreators.js @@ -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}`]))); diff --git a/js/components/EqualizerWindow/EqGraph.js b/js/components/EqualizerWindow/EqGraph.js index 51cded36..cc32551d 100644 --- a/js/components/EqualizerWindow/EqGraph.js +++ b/js/components/EqualizerWindow/EqGraph.js @@ -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, diff --git a/js/components/EqualizerWindow/EqGraph.test.js b/js/components/EqualizerWindow/EqGraph.test.js deleted file mode 100644 index 31d61e13..00000000 --- a/js/components/EqualizerWindow/EqGraph.test.js +++ /dev/null @@ -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", () => {}); -}); diff --git a/js/utils.js b/js/utils.js index 4a05ae39..3bd437f3 100644 --- a/js/utils.js +++ b/js/utils.js @@ -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);