GithubHelp home page GithubHelp logo

4lejandrito / react-guitar Goto Github PK

View Code? Open in Web Editor NEW
619.0 10.0 45.0 23.41 MB

A beautiful and accessible guitar component for React. โš›๏ธ ๐ŸŽธ

Home Page: https://react-guitar.com

License: MIT License

JavaScript 0.87% TypeScript 98.49% CSS 0.52% Shell 0.12%
react guitar

react-guitar's Introduction

React-Guitar ยท npm version

A beautiful and accessible guitar component for React.

See https://react-guitar.com for a live demo.

Screenshot of the rendered component with an E major chord

Edit quizzical-dawn-0hzuq

Projects using React-Guitar

Usage

npm i react-guitar
import React from 'react'
import { render } from 'react-dom'
import Guitar from 'react-guitar'

render(
  <Guitar strings={[0, 1, 2, 2, 0, -1]} />,
  document.getElementById('root')
)

Check out the storybook for more advanced examples.

Props

Name Description
id An optional id in case several guitars are on the screen at the same time. This is used to generate the radio button names used internally which must be unique. If not specified an autoincremented id will be generated.
className A CSS class string to apply to the container element.
strings An array where each number represents the fret the string is pressed on (0 means open string and -1 muted). [0, 1, 2, 2, 0, -1] is an A minor in a standard guitar and [3, 0, 0, 0] is a C major in a ukelele.
frets An object with the shape { from: number amount: number } to configure the frets of the guitar ({ from: 0, amount: 22 } by default). It can start on any fret which is useful for displaying just a chord instead of the whole guitar.
lefty A boolean to configure the guitar for left handed people like me.
center A boolean to indicate if the current fretting should be centered. If set to true the guitar horizontal scroll will be set so that the middle fret is centered.
renderFinger A function (string: number, fret: number) => JSX.Element that will be used to render the content of the white bubble used for the fingers. This can be used to render the note name.
theme A theme object to customise the guitar look and feel. See Theming.
playOnHover A boolean to indicate if hovering with the mouse should trigger play events.
onChange A function (strings: number[]) => void that will be called when a string is press/unpressed. If not present the guitar will be read only.
onPlay A function (string: number) => void that will be called each time the user plays a string (hovering with the mouse). This can be used to play the sound of the string.

Hooks

useSound

In order to enable sound playing react-guitar offers the useSound hook:

npm i react-guitar react-guitar-sound react-guitar-tunings
import React, { useMemo } from 'react'
import { render } from 'react-dom'
import Guitar from 'react-guitar'
import { standard } from 'react-guitar-tunings'
import useSound from 'react-guitar-sound'

function SampleGuitarWithSound() {
  const strings = useMemo(() => [0, 1, 2, 2, 0, -1], [])
  const { play, strum } = useSound({ fretting: strings, tuning: standard })

  return <Guitar strings={strings} onPlay={play} />
}

render(<SampleGuitarWithSound />, document.getElementById('root'))

Edit quizzical-dawn-0hzuq

It receives an object with the following properties:

Name Description
fretting The same value passed as the strings prop to the <Guitar /> component with the current fretting.
tuning An array of midi values for each string. See react-guitar-tunings for a list of the most common ones.
instrument Optionally the instrument to use, an acousting nylon guitar by default.

And will return an object containing:

Name Description
play A function that receives a string number and plays its current sound.
strum A function that will strum all the strings of the guitar.

There are 2 ways to create a custom instrument:

  1. Using withSoundFont:

    import React, { useMemo } from 'react'
    import { render } from 'react-dom'
    import Guitar from 'react-guitar'
    import { standard } from 'react-guitar-tunings'
    import useSound, { withSoundFont } from 'react-guitar-sound'
    
    const electricGuitar = withSoundFont('electric_guitar_clean')
    
    function SampleGuitarWithSound() {
      const strings = useMemo(() => [0, 1, 2, 2, 0, -1], [])
      const { play, strum } = useSound({
        instrument: electricGuitar,
        fretting: strings,
        tuning: standard,
      })
    
      return <Guitar strings={strings} onPlay={play} />
    }
    
    render(<SampleGuitarWithSound />, document.getElementById('root'))

    It uses danigb/soundfont-player under the hood so all these instrument names are available.

  2. Using withSamples:

    import React, { useMemo } from 'react'
    import { render } from 'react-dom'
    import Guitar from 'react-guitar'
    import { standard } from 'react-guitar-tunings'
    import useSound, { withSamples } from 'react-guitar-sound'
    
    const flamencoGuitar = withSamples({
      E2: 'https://react-guitar.com/samples/E2.mp3',
      D3: 'https://react-guitar.com/samples/D3.mp3',
      G3: 'https://react-guitar.com/samples/G3.mp3',
      E4: 'https://react-guitar.com/samples/E4.mp3',
    })
    
    function SampleGuitarWithSound() {
      const strings = useMemo(() => [0, 1, 2, 2, 0, -1], [])
      const { play, strum } = useSound({
        instrument: flamencoGuitar,
        fretting: strings,
        tuning: standard,
      })
    
      return <Guitar strings={strings} onPlay={play} />
    }
    
    render(<SampleGuitarWithSound />, document.getElementById('root'))

Theming

react-guitar look and feel can be customised by passing the theme prop. A theme is an object describing the customisable properties of the guitar:

{
  description: string // for screen readers
  color: string
  nut: { color: string }
  fret: {
    color: string
    separator: {
      color: string
      radius?: boolean
      shadow?: boolean
      width?: 'sm' | 'md'
    }
    marker?: (fret: number) => JSX.Element | null
    counter: { color: string }
  }
  string: { color: (string: number) => string }
  finger: { text: { color: string }; color: string }
}

See https://react-guitar.com/storybook/?path=/story/guitar--theming for an interactive example.

By default the guitar is styled as a Spanish guitar but some other themes are available:

Upgrading from 0.x

If you were using useSound like this:

useSound(
  {
    E2: '...E2.mp3',
    D3: '...D3.mp3',
    G3: '...G3.mp3',
    E4: '...E4.mp3',
  },
  strings,
  tuning
)

You need to change it to:

import useSound, { withSamples } from 'react-guitar-sound'

// outside the render function
const instrument = withSamples({
  E2: 'https://react-guitar.com/samples/E2.mp3',
  D3: 'https://react-guitar.com/samples/D3.mp3',
  G3: 'https://react-guitar.com/samples/G3.mp3',
  E4: 'https://react-guitar.com/samples/E4.mp3',
})

// inside the render function
useSound({
  instrument,
  fretting: strings,
  tuning,
})

Developing

  • yarn build will build the component and the site, this is mandatory the first time you clone the repo.
  • yarn start will spin up the storybook and the site and all the packages in watch mode.

react-guitar's People

Contributors

4lejandrito avatar ryanbutton avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-guitar's Issues

Running app fails at createSnapshot

Running npm run start or yarn start fails with the following error:

[...]/node_modules/html-webpack-plugin/lib/webpack5/file-watcher-api.js:13
    mainCompilation.fileSystemInfo.createSnapshot(

TypeError: Cannot read properties of undefined (reading 'createSnapshot')

OS: macOS Monterey 12.5.1 running on M1 processor
node: v17.0.1
npm: 8.19.3

Add support for themes

At the moment the guitar is skinned as a Spanish guitar with scss. It would be awesome to have some kind of theming API through which people could skin the guitar as they like.

Maybe something based on https://emotion.sh?

Add keyboard shortcuts

  • s for strumming down.
  • w for strumming up.
  • p for playing a single string (when focused using tab).
  • Document the shortcuts in a help panel or something similar.
  • Shortcuts for common chords? See #1.

add different tunings

Might want to add more tunings. The most common historical lute tuning for example (low to high), easily playable on a current day guitar:

  • e, a, d, f sharp, b, e

P.S. I teach the classical guitar in public schools. Thank you! Thank you! Thank you for your effort!

Want to hide finger component

Thanks for react-guitar!! ๐Ÿ˜

It would be great if we could hide finger components in my project like below screenshot.

I did this by giving visibility:hidden to the finger class in the developer tools.
image

It seems that it can be implemented by allowing visibility to be passed to the theme.

Thank you for your consideration.

Add story to show smaller guitars

react-guitar can be scaled by changing the font-size of its container. It would be nice to have a story in the storybook to showcase this feature.

Consider adding react v18 to peerDependencies

react v18 isn't included in the list of peerDependencies.

Haven't fully tested, but it's working after using it in a newly installed create-react-app which uses [email protected].

Not a blocking issue, but I need to use a workaround like --legacy-peer-deps in order to use the packages.

npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve
npm ERR!
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/react

...

npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.8 || ^17.0" from [email protected]
npm ERR! node_modules/react-guitar
npm ERR!   react-guitar@"^1.1.1" from the root project
npm ERR!
npm ERR! Conflicting peer dependency: [email protected]
npm ERR! node_modules/react
npm ERR!   peer react@"^16.8 || ^17.0" from [email protected]
npm ERR!   node_modules/react-guitar
npm ERR!     react-guitar@"^1.1.1" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.

If I can help, let me know.

Thank you for considering this.

Add a chord picker

Things that definitely need to be improved:

  • Add chord picker modal based on tonaljs/chord.
  • Clearly show muted strings.
  • Make it easier to select common chords (major, minor...). The list of types is too long now.
  • Exclude impossible chord positions for 5 fingered humans.
  • Include chords that don't start with the root.
  • Include flat roots.
  • When a flat chord is detected the UI shows wrong notes.

Things that would be nice to add:

  • Shortcuts for common chords? See #1.
  • Shortcuts for 7th 9th, sharp and flat chords.
  • More settings to filter the type of chords to show (bar chords, open strings...).

I've marked the new guitar-fretter package as private. I will:

  • Make it public when the logic is more polished.

Play on hover

Please make the play-on-hover so it plays as if you had clicked the place you are hovering (so you can use it fo "find" cords by the sound of it.

More frets in viewport

Had a couple ideas for you I could help implement if you're interested.

  1. Make the frets a bit less wide to fit more in the viewport.
  2. Have the frets narrow a bit going left to right like a real guitar.
  3. Allow entry by shorthand (like x-4-2-0-0-0) or add that support in the URL.

Also I added a simple sequencer to my piano/chord tool, and I wonder if you'd mind if I borrowed your guitar sounds to add some flavors? Maybe I could have a mode allow entry by guitar voicings (x-4-2-0-0-0) and have each one link to react-guitar.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.