Commonly, a tuple is used to describe 2 coordinates ( x, y )
of
- a point
- a dimension
- a velocity
- ...
examples:
-
Playground.polygon
,Playground.toXY
, ...polygon : Color -> List ( Float, Float ) -> Shape toXY : Keyboard -> ( Float, Float )
-
Collage.shift
,Collage.polygon
, ...shift : ( Float, Float ) -> Collage msg -> Collage msg polygon : List ( Float, Float ) -> Shape
This package contains simple helpers to create, transform & read 2-coordinate-tuples.
... Or at least it did. Now wait here.
In retrospect: Is this really a good idea?
descriptiveness: Do you prefer
( 3, 4 )
orDimensions { width = 3, height = 4 }
?units: Do you prefer
( 3, 4 )
orfromTuple Pixels.int ( 3, 4 )
? Enjoy your time with elm-units and thank me later!safety:
Xy.normalize
,Xy.direction
, ... should return a type that keeps its promise of\xy -> (xy |> Xy.length) = 1
→
Vector2d
,Point2d
,Direction2d
, ...elm-geometry shows how to do it right.
What about the extra verbosity when converting to/from tuples? Cross that out of your head. explicitness >> verbosity. That's why you're here in elm land. Stay a little longer :)
→ this package is @deprecated and won't be maintained further
On tuples,
hayleigh-dot-dev/tuple-extra
will supply you with all you need. If not, throw a PR there.If you ever find yourself writing a package yourself, here's some tips so you don't have to one day write this.
- Focus on one thing: not all of these... dimensions, points, vectorial stuff, handling tuples where left = right, ...
- Look up what people created before you. Helpful tools: tarokuriyama's deep search, korban's catalog
Below an earlier example using this package. See where you would do things differently
import Xy exposing (Xy)
type alias Model =
{ playerPosition : Xy Float
, playerVelocity : Xy Float
}
update msg model =
case msg of
SimulatePhysics ->
{ model
| playerPosition =
model.playerPosition
|> Xy.map2 (+) model.playerVelocity
, playerVelocity =
model.playerVelocity
|> Xy.map ((*) 0.98)
|> Xy.mapY (\y -> y - 1)
}
view { playerPosition } =
Collage.circle 50
|> Collage.filled (Collage.uniform Color.red)
|> Collage.shift playerPosition
|> Collage.Render.svg
another example
type alias Model =
{ windowSize : Xy Float }
init =
( { windowSize = Xy.zero }
, Browser.Dom.getViewport
|> Task.perform
(.viewport >> Xy.fromSize >> Resized)
)
subscriptions =
Browser.Events.onResize
(\w h ->
Resized (( w, h ) |> Xy.map toFloat)
)