Improve the styling of the piano

Create a more convincing representation of the piano.

I would like to compute the left-offset based on the naturalWidth. That change
is probably forthcoming.
This commit is contained in:
William Carroll 2020-04-11 11:36:37 +01:00
parent 3562343c19
commit 2f446d0441
2 changed files with 58 additions and 29 deletions

View file

@ -87,7 +87,7 @@ view : State -> Html Msg
view (State {selectedChord}) =
div [] [ p [] [ text (viewChord selectedChord) ]
, button [ onClick NextChord ] [ text "Next Chord" ]
, Piano.render { highlight = [] }
, Piano.render { highlight = Theory.notesForChord selectedChord }
]
{-| For now, I'm just dumping things onto the page to sketch ideas. -}

View file

@ -7,22 +7,53 @@ import Html.Events exposing (..)
import Theory
{-| Convert an integer into its pixel representation for CSS. -}
pixelate : Int -> String
pixelate x = String.fromInt x ++ "px"
{-| Pixel width of the white keys. -}
naturalWidth : Int
naturalWidth = 40
{-| Pixel height of the white keys. -}
naturalHeight : Int
naturalHeight = 200
{-| Pixel width of the black keys. -}
accidentalWidth : Int
accidentalWidth = round (toFloat naturalWidth * 0.7)
{-| Pixel height of the black keys. -}
accidentalHeight : Int
accidentalHeight = round (toFloat naturalHeight * 0.6)
{-| These are the white keys on most modern pianos. -}
natural : Bool -> Html a
natural isHighlit =
li [ style "background-color" (if isHighlit then "red" else "white")
, style "height" "20px"
, style "border-top" "1px solid black"
, style "border-bottom" "1px solid black"
] []
natural : Int -> Bool -> Html a
natural offset isHighlit =
div [ style "background-color" (if isHighlit then "red" else "white")
, style "border-right" "1px solid black"
, style "border-top" "1px solid black"
, style "border-bottom" "1px solid black"
, style "width" (pixelate naturalWidth)
, style "height" (pixelate naturalHeight)
, style "position" "absolute"
, style "left" ((String.fromInt offset) ++ "px")
] []
{-| These are the black keys on most modern pianos. -}
accidental : Bool -> Html a
accidental isHighlit =
li [ style "background-color" (if isHighlit then "red" else "black")
, style "height" "10px"
, style "width" "66%"
] []
accidental : Int -> Bool -> Html a
accidental offset isHighlit =
div [ style "background-color" (if isHighlit then "red" else "black")
, style "border-top" "1px solid black"
, style "border-left" "1px solid black"
, style "border-right" "1px solid black"
, style "border-bottom" "1px solid black"
, style "width" (pixelate accidentalWidth)
, style "height" (pixelate accidentalHeight)
, style "position" "absolute"
, style "left" ((String.fromInt offset) ++ "px")
, style "z-index" "1"
] []
{-| A section of the piano consisting of all twelve notes. The name octave
implies eight notes, which most scales (not the blues scale) honor. -}
@ -31,18 +62,18 @@ octave highlight =
let
isHighlit note = List.member note highlight
in
[ natural (isHighlit Theory.C)
, accidental (isHighlit Theory.C_sharp)
, natural (isHighlit Theory.D)
, accidental (isHighlit Theory.D_sharp)
, natural (isHighlit Theory.E)
, natural (isHighlit Theory.F)
, accidental (isHighlit Theory.F_sharp)
, natural (isHighlit Theory.G)
, accidental (isHighlit Theory.G_sharp)
, natural (isHighlit Theory.A)
, accidental (isHighlit Theory.A_sharp)
, natural (isHighlit Theory.B)
[ natural 0 (isHighlit Theory.C)
, accidental 25 (isHighlit Theory.C_sharp)
, natural 40 (isHighlit Theory.D)
, accidental 65 (isHighlit Theory.D_sharp)
, natural 80 (isHighlit Theory.E)
, natural 120 (isHighlit Theory.F)
, accidental 145 (isHighlit Theory.F_sharp)
, natural 160 (isHighlit Theory.G)
, accidental 185 (isHighlit Theory.G_sharp)
, natural 200 (isHighlit Theory.A)
, accidental 225 (isHighlit Theory.A_sharp)
, natural 240 (isHighlit Theory.B)
]
indexForNote : Theory.Note -> Int
@ -64,6 +95,4 @@ indexForNote note =
{-| Return the HTML that renders a piano representation. -}
render : { highlight : List Theory.Note } -> Html a
render {highlight} =
ul [ style "width" "100px"
, style "list-style" "none"
] (octave highlight |> List.reverse |> List.repeat 1 |> List.concat)
div [ style "display" "flex" ] (octave highlight |> List.reverse |> List.repeat 1 |> List.concat)