The shine package

[Tags:library, mit, test]

Shine wraps javascript's drawing functions in a declarative API. Heavily inspired by Gloss.

Read the README for an overview of the library.


[Skip to Readme]

Properties

Versions 0.1.0.0
Dependencies base (>=4.2 && <5), ghcjs-dom (==0.2.*), ghcjs-prim, keycode, mtl, time, transformers [details]
License MIT
Copyright (c) 2016 Francesco Gazzetta
Author Francesco Gazzetta
Maintainer Francesco Gazzetta <francygazz@gmail.com>
Category Web, Graphics, Javascript
Home page https://github.com/fgaz/shine
Bug tracker https://github.com/fgaz/shine/issues
Source repository head: git clone https://github.com/fgaz/shine
Uploaded Wed Apr 20 17:20:28 UTC 2016 by fgaz
Updated Fri Apr 22 11:51:21 UTC 2016 by fgaz to revision 1
Distributions
Downloads 48 total (5 in the last 30 days)
Votes
2 []
Status Docs uploaded by user
Build status unknown [no reports yet]

Modules

[Index]

Downloads

Maintainer's Corner

For package maintainers and hackage trustees

Readme for shine

Readme for shine-0.1.0.0

Shine - Declarative Graphics for the Web

Shine wraps javascript's drawing functions in a declarative API.

Heavily inspired by gloss.

Compiling

You need ghcjs

Usage

Pictures

To represent your drawing you have to build a tree using the Picture datatype.

pic :: Picture
pic = Rect 10 20 -- represents a 10x20 square

To compose multiple Pictures you can use Over, which accepts two Pictures and overlaps them.

Picture is a monoid: <> is an alias for Over and mempty is the empty picture.

-- draw some shapes on top of each other
pic :: Picture
pic = Rect 10 20
   <> Translate 30 30 (Circle 15)
   <> Colored (Color 255 0 0 0.2) (RectF 4 4)
   <> Text "Sans 12px" LeftAlign 200 "The quick brown fox jumps over the lazy dog."

Using Foldable you can do things like

concentricCircles :: Picture
concentricCircles = foldMap Circle [1,10..100]

Drawing Pictures

Before drawing anything you need to obtain a CanvasRenderingContext2D. For this purpose, shine provides two utility functions: fullScreenCanvas and fixedSizeCanvas

main :: IO ()
main = runWebGUI $ \ webView -> do
    ctx <- fixedSizeCanvas webView 800 600
    -- do something with ctx

To render a Picture on a context you have three options:

render

You can draw it manually using render from Graphics.Shine.Render

main :: IO ()
main = runWebGUI $ \ webView -> do
    ctx <- fixedSizeCanvas webView 400 400
    draw ctx concentricCircles

animate

You can draw a Picture that depends on time. That is, a Float -> Picture.

-- An expanding-and-contracting circle.
animation :: Float -> Picture
animation = Translate 200 200
          . Circle
          . (*100) . (+1) -- bigger positive oscillation
          . sin -- the circle's radius oscillates

main :: IO ()
main = runWebGUI $ \ webView -> do
    ctx <- fixedSizeCanvas webView 400 400
    animate ctx 30 animation

play

Finally, you can draw a Picture that depends on time, inputs (keyboard and mouse) and an internal state. This is especially useful for games, hence the name.

-- this code draws a black rectangle in the center of the canvas only when the
-- left mouse button is pressed
main :: IO ()
main = runWebGUI $ \ webView -> do
    ctx <- fixedSizeCanvas webView 400 400
    Just doc <- webViewGetDomDocument webView
    play ctx doc 30 initialState draw handleInput step
  where
    -- our state represents the state of the left mouse button
    initialState = Up
    -- we draw a square only if the button is pressed
    draw Up = Empty
    draw Down = Translate 200 200 $ RectF 200 200
    -- when an event is fired we store the button state
    handleInput (MouseBtn BtnLeft buttonState _) = const buttonState
    handleInput _ = id -- catch-all for all other events
    step _ = id -- our state does not depend on time