Code Monkey home page Code Monkey logo

startstopfrp's Introduction

StartStopFRP

A behavior based frp system

Semantically

Behavior t a :: Time -> a EvStream t a :: [(Time, a)]

in english

"Behavior t a" are values that change over time. Examples of this could be a (Behavior t String) for what words are currently displayed on the screen right now, or a (Behavior t (Int, Int)) for the location of your mouse.

"EvStream t a" are values that happen at one point in time. Such as when you click your mouse, or when you press a key on your keyboard.

Behaviors are a Functor

(fmap f b) creates a behavior whos value is the value of b applied with f.

EvStreams are a Functor

(fmap f ev) creates a Event Stream that fires whenever ev fires with a value of ev applied to f.

Behaviors are an Applicative

The pure function returns a constant behavior, so (pure 3) would produce a behavior whos value is always 3.

(bf <*> ba) creates a behavior whos current value is the current value of ba applied to the current value of bf.

Behaviors are a Monad

Return is the same as pure. So (return x) a constant behavior whos value is always x.

Examples:

clickExample :: EvStream t [Event] -> Hold t (Behavior t Picture)
clickExample ev = do
  -- filter ev down to only the first mouse click event.
  let mouseClickEvs = filterMap (\xs -> case filterMap isMouseClickEvent xs of
                                          [] -> Nothing
                                          (x:_) -> Just x) ev

  -- creates a behavior with a value of the last clicks position
  bLastMouseClick <- holdEs mouseClickEvs (0,0)

  -- Takes a position and makes a Picture of text with the value of the position
  let positionToText = translate (negate 240) (negate 240) . scale 0.4 0.4 . text . show

  -- return a behavior whos current value is the current screen to draw.
  return $ fmap positionToText bLastMouseClick

-- Takes a list of (x,y) corrdenates and produces a Picture which is a plot.
drawPlot :: [(Float, Float)] -> Picture
drawPlot points = color (Gloss.black) . (Gloss.line) $ shiftedPoints
  where
    max_x = maximum $ fmap fst points
    min_x = minimum $ fmap fst points
    shiftedPoints = fmap (\(x,y) -> (x - max_x, y)) points
    
-- This takes the clock and a behavior, it then produces a behaivor whos value is a list of samples of b.
holdLastNSecs :: Float -> EvStream t Float -> Behavior t a -> Hold t (Behavior t [(Float, a)])
holdLastNSecs holdTime clock b = foldEs (\vs (t, v) -> (t, v) : filter ((> t - holdTime) . fst) vs) (flip (,) <$> b <@> clock) []

mouseTrackerExample :: EvStream t Float -> EvStream t [Event] -> Hold t (Behavior t Picture)
mouseTrackerExample clock ev = do
  -- behavior whos value is the position of the mouse
  bMousePos <- holdEs (filterMap (\xs -> case filterMap isMouseChange xs of
                                      [] -> Nothing
                                      (x:_) -> Just x) ev) (0,0)
  
  -- a behavior whos value is a list of samples of the mouses position for the last 5 seconds
  bMousePosData <- holdLastNSecs 5 clock (fmap snd bMousePos)
  
  return $ fmap (translate 0 0 . scale 50 1 . drawPlot) bMousePosData

holdLastNSecs :: Float -> EvStream t Float -> Behavior t a -> Hold t (Behavior t [(Float, a)])
holdLastNSecs holdTime clock b = foldEs (\vs (t, v) -> (t, v) : filter ((> t - holdTime) . fst) vs) (flip (,) <$> b <@> clock) []

decayColorLine :: [(Float, (Float, Float))] -> Picture
decayColorLine vs = foldl' (flip (<>)) mempty $ fmap (\(t, (x, y)) -> color (timeColor t) $ translate x y $ circleSolid 10) $ vs
  where
    minTime = minimum $ fmap fst vs
    maxTime = maximum $ fmap fst vs

    timeDif = maxTime - minTime
    timeRed t = (t - minTime - 0.1) / (timeDif + 0.1)
    timeBlue t = (maxTime - t) / (timeDif + 0.05)
    timeColor t = makeColor (timeRed t) (timeBlue t) 0 1

    pair = zipWith (\(t, pos1) (_, pos2) -> (t, [pos1, pos2])) vs (drop 1 vs)
    
mouseTrailExample :: EvStream t Float -> EvStream t [Event] -> Hold t (Behavior t Picture)
mouseTrailExample clock ev = do
  bMousePos <- holdEs (filterMapEs (\xs -> case filterMap isMouseChange xs of
                                      [] -> Nothing
                                      (x:_) -> Just x) ev) (0,0)
  bTrail <- holdLastNSecs 1.2 clock bMousePos

  return $ fmap decayColorLine bTrail

startstopfrp's People

Contributors

tylerwx51 avatar

Watchers

James Cloos avatar Denis Stoyanov avatar

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.