Skip to content

Instantly share code, notes, and snippets.

@dela3499
Last active August 31, 2015 21:05
Show Gist options
  • Select an option

  • Save dela3499/1b3187cb284e034b843f to your computer and use it in GitHub Desktop.

Select an option

Save dela3499/1b3187cb284e034b843f to your computer and use it in GitHub Desktop.
Turn raw swipe information into a swipe direction. http://share-elm.com/gists/1b3187cb284e034b843f
import Graphics.Element exposing (show, Element)
import Touch exposing (Touch)
import Signal
import Set
import Maybe exposing (andThen, withDefault)
import Graphics.Collage exposing (..)
import Color exposing (..)
import Window
--import Html exposing (fromElement, Html, div, Attribute, node)
--import Html.Attributes exposing (name, content)
type alias Swipe = Touch
type Direction
= Left
| Right
| Up
| Down
touches': Signal (List Touch, List Touch)
touches' =
Signal.foldp
(\touches (a, _) -> (touches, a))
([], [])
Touch.touches
getSwipes: (List Touch, List Touch) -> List Swipe
getSwipes (newTouches, oldTouches) =
let getIds touches =
List.map
(\touch -> touch.id)
touches
|> Set.fromList
swipeIds =
Set.diff
(getIds oldTouches)
(getIds newTouches)
|> Set.toList
in
List.filter
(\touch -> List.member touch.id swipeIds)
oldTouches
swipes: Signal (List Swipe)
swipes = Signal.map getSwipes touches'
getSwipeDirection: Swipe -> Maybe Direction
getSwipeDirection swipe =
let dx =
swipe.x - swipe.x0
|> toFloat
dy =
-(swipe.y - swipe.y0)
|> toFloat
(r, theta) =
toPolar (dx, dy)
(nearestDir, angleDiff) =
getNearestDirection theta
in
if r > 100 && angleDiff < 20
then Just nearestDir
else Nothing
-- Given angle in radians, return closest direction, and difference in degrees.
getNearestDirection: Float -> (Direction, Float)
getNearestDirection theta =
let dirAngles =
[ (Left, 180)
, (Right, 0)
, (Right, 360)
, (Up, 90)
, (Down, 270)
]
dirDiffs =
List.map
(\(direction, angle) ->
(direction, abs (angle - (toDegrees theta))))
dirAngles
in
List.sortBy snd dirDiffs
|> List.head
|> withDefault (Left, 0)
toDegrees: Float -> Float
toDegrees rads =
let raw = rads * (180 / pi)
in
if raw > 0
then raw
else raw + 360
getSwipeDirection': List Swipe -> Maybe Direction
getSwipeDirection' swipes =
List.head swipes `andThen` getSwipeDirection
swipeDirection: Signal (Maybe Direction)
swipeDirection = Signal.map getSwipeDirection' swipes
hasValue: Maybe a -> Bool
hasValue a =
case a of
Just _ -> True
Nothing -> False
swipeDirection': Signal Direction
swipeDirection' =
Signal.filter hasValue (Just Left) swipeDirection
|> Signal.map
(\dir ->
case dir of
Just val -> val
Nothing -> Left)
swipeDirection'': Signal Direction
swipeDirection'' =
Signal.sampleOn Touch.touches swipeDirection'
--main: Signal Element
main = Signal.map2 display' Window.dimensions swipeDirection''
display': (Int, Int) -> Direction -> Element
display' (w, h) direction =
collage w h
[ ngon 3 (toFloat w / 7)
|> filled black
|> rotate (direction |> directionToAngle |> degrees)
]
{--
display: (Int, Int) -> Direction -> Html
display (w, h) direction =
let triangle = display' (w, h) direction |> fromElement
in
div []
[ triangle
, meta
[ name "viewport"
, content "width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, minimal-ui"
]
[]
]
meta : List Attribute -> List Html -> Html
meta attributes children =
node "meta" attributes children
--}
directionToAngle direction =
case direction of
Left -> 180
Right -> 0
Up -> 90
Down -> 270
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment