Get band input UI working for EQ

This commit is contained in:
Jordan Eldredge 2016-08-23 11:52:37 -07:00
parent d932bb38f6
commit 5a5b88756e
6 changed files with 271 additions and 1 deletions

View file

@ -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);
}

42
js/__tests__/Band-test.js Normal file
View file

@ -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);
});
});

54
js/components/Band.jsx Normal file
View file

@ -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 <div className='band' style={style}>
<input
type='range'
min='1'
max='100'
step='1'
value={value}
onChange={this.setValue}
/>
</div>;
}
}
export default connect((state) => state.equalizer)(Band);

View file

@ -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 <DraggableWindow handleClass='title-bar'>
<div id='equalizer-window' className={className}>
<div className='equalizer-top title-bar' />
<div id='preamp'>
<Band band='preamp' />
</div>
<div id='band-60'>
<Band band='band60' />
</div>
<div id='band-170'>
<Band band='band170' />
</div>
<div id='band-310'>
<Band band='band310' />
</div>
<div id='band-600'>
<Band band='band600' />
</div>
<div id='band-1k'>
<Band band='band1k' />
</div>
<div id='band-3k'>
<Band band='band3k' />
</div>
<div id='band-6k'>
<Band band='band6k' />
</div>
<div id='band-12k'>
<Band band='band12k' />
</div>
<div id='band-14k'>
<Band band='band14k' />
</div>
<div id='band-16k'>
<Band band='band16k' />
</div>
</div>
</DraggableWindow>;
};

View file

@ -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
});

View file

@ -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}
]
},
{