diff --git a/css/equalizer-window.css b/css/equalizer-window.css index 2eb1a0e7..820e0f6f 100644 --- a/css/equalizer-window.css +++ b/css/equalizer-window.css @@ -8,3 +8,113 @@ height: 14px; width: 275px; } + +#winamp2-js #preamp { + position: absolute; + left: 20px; + top: 37px; +} + +#winamp2-js #band-60 { + position: absolute; + left: 80px; + top: 37px; +} + +#winamp2-js #band-170 { + position: absolute; + left: 98px; + top: 37px; +} + +#winamp2-js #band-310 { + position: absolute; + left: 116px; + top: 37px; +} + +#winamp2-js #band-600 { + position: absolute; + left: 134px; + top: 37px; +} + +#winamp2-js #band-1k { + position: absolute; + left: 152px; + top: 37px; +} + +#winamp2-js #band-3k { + position: absolute; + left: 170px; + top: 37px; +} + +#winamp2-js #band-6k { + position: absolute; + left: 188px; + top: 37px; +} + +#winamp2-js #band-12k { + position: absolute; + left: 206px; + top: 37px; +} + +#winamp2-js #band-14k { + position: absolute; + left: 224px; + top: 37px; +} + +#winamp2-js #band-16k { + position: absolute; + left: 242px; + top: 37px; +} + +#winamp2-js .band { + width: 14px; + height: 64px; +} + +#winamp2-js .band input[type=range] { + /* These two numbers are pure magic. No idea why they work */ + margin-left: -25px; + margin-top: 25px; + width: 64px; + height: 14px; + background-position: 0 0; + transform: rotate(270deg); + cursor:url('../cursors/POSBAR.PNG'), auto; +} + +#winamp2-js .band input[type=range]::-webkit-slider-thumb { + height: 11px; + width: 11px; + /* Confusingly, due to rotation, this is actually left margin */ + margin-top: -1px; + cursor:url('../cursors/POSBAR.PNG'), auto; + /* Counteract the input's rotation */ + -webkit-transform: rotate(-270deg); + -moz-transform: rotate(-270deg); + -ms-transform: rotate(-270deg); + -o-transform: rotate(-270deg); + transform: rotate(-270deg); +} + +#winamp2-js .band input[type=range]::-moz-range-thumb { + height: 11px; + width: 11px; + /* Confusingly, due to rotation, this is actually left margin */ + margin-top: -1px; + cursor:url('../cursors/POSBAR.PNG'), auto; + /* Counteract the input's rotation */ + -webkit-transform: rotate(-270deg); + -moz-transform: rotate(-270deg); + -ms-transform: rotate(-270deg); + -o-transform: rotate(-270deg); + transform: rotate(-270deg); +} diff --git a/js/__tests__/Band-test.js b/js/__tests__/Band-test.js new file mode 100644 index 00000000..fca51829 --- /dev/null +++ b/js/__tests__/Band-test.js @@ -0,0 +1,42 @@ +jest.unmock('../components/Band.jsx'); + +import { + spriteNumber, + spriteOffsets +} from '../components/Band.jsx'; + +describe('spriteNumber', () => { + it('gives the first sprite', () => { + const actual = spriteNumber(0); + const expected = 0; + expect(actual).toEqual(expected); + }); + it('gives the middle sprite', () => { + const actual = spriteNumber(50); + const expected = 14; + expect(actual).toEqual(expected); + }); + it('gives the last sprite', () => { + const actual = spriteNumber(100); + const expected = 27; + expect(actual).toEqual(expected); + }); +}); + +describe('spriteOffsets', () => { + it('gives the first sprite', () => { + const actual = spriteOffsets(0); + const expected = {x: 0, y: 0}; + expect(actual).toEqual(expected); + }); + it('gives the middle sprite', () => { + const actual = spriteOffsets(14); + const expected = {x: 0, y: 1}; + expect(actual).toEqual(expected); + }); + it('gives the last sprite', () => { + const actual = spriteOffsets(27); + const expected = {x: 13, y: 1}; + expect(actual).toEqual(expected); + }); +}); diff --git a/js/components/Band.jsx b/js/components/Band.jsx new file mode 100644 index 00000000..e9b8a403 --- /dev/null +++ b/js/components/Band.jsx @@ -0,0 +1,54 @@ +import React from 'react'; +import {connect} from 'react-redux'; + +// Given a value between 1-100, return the sprite number (0-27) +export const spriteNumber = (value) => { + const percent = value / 100; + return Math.round(percent * 27); +}; + +// Given a sprite number, return the x,y +export const spriteOffsets = (number) => { + const x = number % 14; + const y = Math.floor(number / 14); + return {x, y}; +}; + +class Band extends React.Component { + constructor(props) { + super(props); + this.setValue = this.setValue.bind(this); + } + + setValue(e) { + this.props.dispatch({ + type: 'SET_BAND_VALUE', + band: this.props.band, + value: e.target.value + }); + } + + render() { + const value = this.props[this.props.band]; + const offset = spriteOffsets(spriteNumber(value)); + const xOffset = offset.x * 15; // Each sprite is 15px wide + const yOffset = offset.y * 65; // Each sprite is 15px tall + + const style = { + backgroundPosition: `-${xOffset}px -${yOffset}px` + }; + + return
+ +
; + } +} + +export default connect((state) => state.equalizer)(Band); diff --git a/js/components/EqualizerWindow.jsx b/js/components/EqualizerWindow.jsx index 066d0086..647e2ce9 100644 --- a/js/components/EqualizerWindow.jsx +++ b/js/components/EqualizerWindow.jsx @@ -3,6 +3,7 @@ import {connect} from 'react-redux'; import classnames from 'classnames'; import DraggableWindow from './DraggableWindow.jsx'; +import Band from './Band.jsx'; import '../../css/equalizer-window.css'; @@ -16,6 +17,39 @@ const EqualizerWindow = (props) => { return
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
; }; diff --git a/js/reducers.js b/js/reducers.js index 3b4fafa6..5e05836d 100644 --- a/js/reducers.js +++ b/js/reducers.js @@ -84,6 +84,32 @@ const contextMenu = (state, action) => { } }; +const equalizer = (state, action) => { + if (!state) { + return { + preamp: 50, + band60: 50, + band170: 50, + band310: 50, + band600: 50, + band1k: 50, + band3k: 50, + band6k: 50, + band12k: 50, + band14k: 50, + band16k: 50 + }; + } + switch (action.type) { + case 'SET_BAND_VALUE': + const newState = {...state}; + newState[action.band] = action.value; + return newState; + default: + return state; + } +}; + const media = (state, action) => { if (!state) { return { @@ -136,6 +162,7 @@ const reducer = combineReducers({ userInput, display, contextMenu, + equalizer, media }); diff --git a/js/skinSprites.js b/js/skinSprites.js index 2d458619..c7528803 100644 --- a/js/skinSprites.js +++ b/js/skinSprites.js @@ -143,7 +143,10 @@ module.exports = [ sprites: [ {selectors: ['#equalizer-window'], x: 0, y: 0, width: 275, height: 116}, {selectors: ['.equalizer-top'], x: 0, y: 149, width: 275, height: 14}, - {selectors: ['.selected .equalizer-top'], x: 0, y: 134, width: 275, height: 14} + {selectors: ['.selected .equalizer-top'], x: 0, y: 134, width: 275, height: 14}, + {selectors: ['.band'], x: 13, y: 164, width: 209, height: 129}, + {selectors: ['.band input::-webkit-slider-thumb', 'band input::-moz-range-thumb'], x: 0, y: 164, width: 11, height: 11}, + {selectors: ['band input::-webkit-slider-thumb:active', '.band input::-moz-range-thumb:active'], x: 0, y: 176, width: 11, height: 11} ] }, {