Selaa lähdekoodia

Add props, fix fret widths

Add various props for fretboard display, also made fret widths realistic.
master
TheoryOfNekomata 3 vuotta sitten
vanhempi
commit
4b10aeafc4
2 muutettua tiedostoa jossa 205 lisäystä ja 51 poistoa
  1. +18
    -0
      src/components/Fretboard/Fretboard.stories.tsx
  2. +187
    -51
      src/components/Fretboard/Fretboard.tsx

+ 18
- 0
src/components/Fretboard/Fretboard.stories.tsx Näytä tiedosto

@@ -8,3 +8,21 @@ export default {
// By passing optional props to this story, you can control the props of the component when
// you consume the story in a test.
export const Default = (props?: Partial<Props>) => <Fretboard {...props} />

export const ReducedFrets = (props?: Partial<Props>) => <Fretboard {...props} frets={18} />

export const FixedTunings = (props?: Partial<Props>) => <Fretboard {...props} fixedTunings displayTunings />

export const Fretted = (props?: Partial<Props>) => <Fretboard {...props} fretted={[0, 0, 1, 2, 2, 0]} />

export const Tunable = (props?: Partial<Props>) => <Fretboard {...props} displayTunings />

export const LeftHanded = (props?: Partial<Props>) => <Fretboard {...props} leftHanded />

export const Bass = (props?: Partial<Props>) => <Fretboard {...props} tunings={[43, 38, 33, 28]} />

export const ExtendedGuitar = (props?: Partial<Props>) => <Fretboard {...props} tunings={[64, 59, 55, 50, 45, 40, 35, 30]} />

// export const ExtendedBass = (props?: Partial<Props>) => <Fretboard {...props} tunings={[48, 43, 38, 33, 28, 23]} />

export const WithCapo = (props?: Partial<Props>) => <Fretboard {...props} capoFret={8} />

+ 187
- 51
src/components/Fretboard/Fretboard.tsx Näytä tiedosto

@@ -1,17 +1,55 @@
import React, { FC } from 'react'
import React, {ChangeEventHandler, FC} from 'react'
import * as PropTypes from 'prop-types'

const propTypes = {
tunings: PropTypes.arrayOf(PropTypes.number),
frets: PropTypes.number,
leftHanded: PropTypes.bool,
fixedTunings: PropTypes.bool,
displayTunings: PropTypes.bool,
capoFret: PropTypes.number,
fretted: PropTypes.arrayOf(PropTypes.number),
}

export type Props = PropTypes.InferProps<typeof propTypes>

const PITCHES = 'C C# D D# E F F# G G# A A# B'.split(' ')

const Fretboard: FC<Props> = ({ tunings = [64, 59, 55, 50, 45, 40], frets = 24, leftHanded = false }) => {
const getPitchName = (n: number) => PITCHES[n % 12] + Math.floor(n / 12)

const Fretboard: FC<Props> = ({
tunings = [64, 59, 55, 50, 45, 40],
frets = 24,
leftHanded = false,
fixedTunings = false,
displayTunings = false,
capoFret = 0,
fretted = [],
}) => {
const [clientSide, setClientSide, ] = React.useState(false)
const [pitches, setPitches, ] = React.useState<string[]>(tunings!.map(t => getPitchName(t!)))

const updateStringPitch = (currentStringNumber: number): ChangeEventHandler<HTMLInputElement> => e => {
const { value } = e.target
setPitches(oldPitches => [
...oldPitches.slice(0, currentStringNumber),
getPitchName(Number(value)),
...oldPitches.slice(currentStringNumber + 1),
])
}

React.useEffect(() => {
setClientSide(true)
}, [])

// React.useEffect(() => {
// if (!Array.isArray(tunings!)) {
// return
// }
//
// setPitches(() => tunings.map(t => getPitchName(t!)))
// }, [tunings])

if (!Array.isArray(tunings!)) {
return null
}
@@ -23,59 +61,80 @@ const Fretboard: FC<Props> = ({ tunings = [64, 59, 55, 50, 45, 40], frets = 24,
style={{
border: '0.0625rem solid',
boxSizing: 'border-box',
transform: leftHanded
? 'perspective(6rem) rotateY(2deg) scaleX(1.375)'
: 'perspective(6rem) rotateY(-2deg) scaleX(1.375)',
transformOrigin: leftHanded ? 'left' : 'right',
}}
>
{strings!.map((pitches, stringNumber) => (
{strings!.map((stringPitches, stringNumber) => (
<div
style={{
display: 'flex',
flexDirection: leftHanded ? 'row-reverse' : 'row',
}}
>
<div
style={{
display: 'flex',
flexDirection: leftHanded ? 'row-reverse' : 'row',
width: '5rem',
height: '1rem',
padding: 0,
boxSizing: 'border-box',
}}
>
<input
type="number"
style={{
display: 'block',
width: '3rem',
height: '1rem',
padding: 0,
boxSizing: 'border-box',
}}
defaultValue={tunings[stringNumber]!}
min={0}
max={127}
/>
<span
style={{
display: 'block',
width: '2rem',
height: '1rem',
textAlign: leftHanded ? 'left' : 'right',
}}
>
{PITCHES[tunings[stringNumber]! % 12]}
{Math.floor(tunings[stringNumber]! / 12)}
</span>
</div>
{
displayTunings
&& (
<div
style={{
display: 'block',
width: '5rem',
height: '1rem',
padding: '0 0 0 1rem',
boxSizing: 'border-box',
position: 'relative',
flexShrink: 0,
}}
>
<div
style={{
display: 'block',
width: '100%',
height: '100%',
padding: 0,
boxSizing: 'border-box',
position: 'relative',
}}
>
<span
style={{
display: 'block',
width: '2rem',
height: '100%',
position: 'absolute',
top: 0,
left: 0,
pointerEvents: 'none',
}}
>
{pitches[stringNumber]}
</span>
<input
type="number"
style={{
display: 'block',
width: '100%',
height: '100%',
padding: 0,
boxSizing: 'border-box',
border: 0,
backgroundColor: 'transparent',
font: 'inherit',
textAlign: 'right',
}}
readOnly={!clientSide || Boolean(fixedTunings)}
onChange={updateStringPitch(stringNumber)}
defaultValue={tunings[stringNumber]!}
min={0}
max={127}
/>
</div>
</div>
)
}
<div
style={{
display: 'block',
position: 'relative',
width: '1rem',
width: '0.5rem',
height: '1rem',
flexShrink: 0,
padding: 0,
@@ -88,8 +147,8 @@ const Fretboard: FC<Props> = ({ tunings = [64, 59, 55, 50, 45, 40], frets = 24,
style={{
position: 'relative',
display: 'block',
width: '1rem',
height: '1rem',
width: '100%',
height: '100%',
flexShrink: 0,
padding: 0,
border: 0,
@@ -104,12 +163,40 @@ const Fretboard: FC<Props> = ({ tunings = [64, 59, 55, 50, 45, 40], frets = 24,
backgroundColor: 'currentColor',
}}
/>
{
fretted![stringNumber] === 0
&& (
<span
style={{
position: 'absolute',
top: 0,
left: 0,
height: '100%',
width: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'space-around',
flexDirection: 'column',
color: 'red',
}}
>
<span
style={{
width: '0.75rem',
height: '0.75rem',
backgroundColor: 'currentColor',
borderRadius: '50%',
}}
/>
</span>
)
}
</button>
</div>
{pitches.map((_, i) => (
{stringPitches.map((_, i) => (
<div
style={{
width: `${(frets! - i + frets! / 2) * 100}%`,
width: `${(frets! - i - 1) / 12 * 100 + 100}%`,
height: '1rem',
position: 'relative',
}}
@@ -129,8 +216,8 @@ const Fretboard: FC<Props> = ({ tunings = [64, 59, 55, 50, 45, 40], frets = 24,
>
<div
style={{
width: `${0.75 - i * (1 / 80)}rem`,
height: `${0.75 - i * (1 / 256)}rem`,
width: '0.75rem',
height: '0.75rem',
backgroundColor: 'currentColor',
opacity: 0.5,
borderRadius: '50%',
@@ -139,8 +226,8 @@ const Fretboard: FC<Props> = ({ tunings = [64, 59, 55, 50, 45, 40], frets = 24,
{i % 12 === 11 && (
<div
style={{
width: `${0.75 - i * (1 / 80)}rem`,
height: `${0.75 - i * (1 / 256)}rem`,
width: '0.75rem',
height: '0.75rem',
backgroundColor: 'currentColor',
opacity: 0.5,
borderRadius: '50%',
@@ -171,7 +258,56 @@ const Fretboard: FC<Props> = ({ tunings = [64, 59, 55, 50, 45, 40], frets = 24,
backgroundColor: 'currentColor',
}}
/>
{
fretted![stringNumber] === i + 1
&& (
<span
style={{
position: 'absolute',
top: 0,
left: 0,
height: '100%',
width: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'space-around',
flexDirection: 'column',
color: 'red',
}}
>
<span
style={{
width: '0.75rem',
height: '0.75rem',
backgroundColor: 'currentColor',
borderRadius: '50%',
}}
/>
</span>
)
}
</button>
{
capoFret === (i + 1) && stringNumber === 0 && (
<div
style={{
position: 'absolute',
top: 0,
height: `${tunings.length * 100}%`,
width: '100%',
}}
>
<div
style={{
width: '0.75rem',
height: '100%',
backgroundColor: 'currentColor',
borderRadius: '0.375rem',
}}
/>
</div>
)
}
</div>
))}
</div>


Ladataan…
Peruuta
Tallenna