Select Git revision
SvgUtils.elm
SvgUtils.elm 5.99 KiB
module SvgUtils exposing (..)
import Html exposing (Html)
import Svg
import Svg.Attributes as SvgAttr
import P2D
import P2D exposing (P2D,Angled,shift,rad)
import String
type alias BoundingRect =
{ min : P2D -- minimal x, minimal y
, max : P2D -- maximal x, maximal y
}
type alias BoundedSvg m = (BoundingRect, Svg.Svg m)
boundingBox : List P2D -> BoundingRect
boundingBox points =
let
(xs,ys) =
points
|> List.map P2D.toTuple
|> List.unzip
min_x : Float
min_x = Maybe.withDefault 0.0 <| List.minimum xs
min_y = Maybe.withDefault 0.0 <| List.minimum ys
max_x = Maybe.withDefault 0.0 <| List.maximum xs
max_y = Maybe.withDefault 0.0 <| List.maximum ys
in
{ min = { x = min_x, y = min_y }
, max = { x = max_x, y = max_y }
}
{-| Compute the viewBox attribute of the svg canvas for a given box
-}
viewBoxBoundings : BoundingRect -> Svg.Attribute msg
viewBoxBoundings bbox =
[ bbox.min.x -- minimum x coordinate
, bbox.min.y -- minimum y coordinate
, bbox.max.x - bbox.min.x -- width
, bbox.max.y - bbox.min.y -- height
]
|> List.map toString
|> List.intersperse " "
|> String.concat
|> SvgAttr.viewBox
translate : P2D -> Svg.Svg m -> Svg.Svg m
translate delta object =
let
transform =
"translate("
++ (toString delta.x)
++ ","
++ (toString delta.y)
++ ")"
in
Svg.g
[ SvgAttr.transform transform ]
[ object ]
type Alignment = Left | Right | Center
{-| moves the first object on top of the second, aligned to the left
-}
aboveOf' : Float -> (BoundedSvg m) -> (BoundedSvg m) -> (BoundedSvg m)
aboveOf' = aboveOf Center