Commits: 2

Implement the viewbox example

new file mode 100644
index 0000000..5b77dc1
--- /dev/null
+++ b/src/ViewBox.elm
@@ -0,0 +1,262 @@
+module ViewBox exposing
+    ( Flags
+    , Model
+    , Msg
+    , init
+    , main
+    , subscriptions
+    , ui
+    , update
+    , view
+    )
+
+import Browser
+import CartesianPlane exposing (graph)
+import Element
+import Element.Background as Background
+import Element.Border as Border
+import Element.Input as Input
+import Html exposing (Html)
+import Svg exposing (..)
+import Svg.Attributes exposing (..)
+
+
+main =
+    Browser.element
+        { init = init
+        , view = view
+        , update = update
+        , subscriptions = subscriptions
+        }
+
+
+type alias Flags =
+    ()
+
+
+type alias Model =
+    { left : Float
+    , top : Float
+    , width : Float
+    , height : Float
+    }
+
+
+type Msg
+    = Move Float Float
+    | Resize Float Float
+
+
+init : Flags -> ( Model, Cmd Msg )
+init () =
+    ( { left = 0
+      , top = 0
+      , width = 400
+      , height = 400
+      }
+    , Cmd.none
+    )
+
+
+view : Model -> Html.Html Msg
+view model =
+    let
+        wrapper element =
+            Element.el
+                [ Element.width (Element.maximum 1200 Element.fill)
+                , Element.height Element.fill
+                , Element.centerX
+                ]
+                element
+    in
+    ui model
+        |> wrapper
+        |> Element.layout
+            [ Element.height Element.fill
+            , Element.width Element.fill
+            ]
+
+
+update : Msg -> Model -> ( Model, Cmd Msg )
+update msg model =
+    case msg of
+        Move left top ->
+            ( { model | left = left, top = top }, Cmd.none )
+
+        Resize width height ->
+            ( { model | width = width, height = height }, Cmd.none )
+
+
+subscriptions : Model -> Sub Msg
+subscriptions model =
+    Sub.none
+
+
+ui model =
+    Element.column
+        [ Element.width Element.fill
+        , Element.height Element.fill
+        , Element.spacing 30
+        , Element.padding 30
+        ]
+        [ Element.row
+            [ Element.width Element.fill
+            , Element.height Element.fill
+            , Element.centerX
+            , Element.spacing 30
+            , Element.padding 30
+            ]
+            [ Element.el
+                [ Element.height Element.fill
+                , Element.width Element.fill
+                ]
+                (Element.html <|
+                    svg [ viewBox "0 0 1000 1000" ]
+                        [ g [] world
+                        , rect
+                            [ x (String.fromFloat model.left)
+                            , y (String.fromFloat model.top)
+                            , width (String.fromFloat model.width)
+                            , height (String.fromFloat model.height)
+                            , opacity "0.8"
+                            , stroke "white"
+                            , Svg.Attributes.style "fill: hsl(120, 100%, 85.1%)"
+                            ]
+                            []
+                        ]
+                )
+            , Element.el
+                [ Element.height Element.fill
+                , Element.width Element.fill
+                , Background.color <| Element.rgb 0.7 1 0.7
+                ]
+                (Element.html <|
+                    svg
+                        [ [ model.left, model.top, model.width, model.height ]
+                            |> List.map String.fromFloat
+                            |> String.join " "
+                            |> viewBox
+                        , preserveAspectRatio "none"
+                        , Svg.Attributes.style "width: 100; height: 100%"
+                        ]
+                        [ g [] world
+                        ]
+                )
+            ]
+        , Input.slider
+            [ Element.behindContent
+                (Element.el
+                    [ Element.width Element.fill
+                    , Element.height (Element.px 2)
+                    , Element.centerY
+                    , Background.color <| Element.rgb 0.7 0.7 0.7
+                    , Border.rounded 2
+                    ]
+                    Element.none
+                )
+            ]
+            { onChange = \left -> Move left model.top
+            , label =
+                Input.labelBelow [ Element.centerX ] <|
+                    Element.text ("left: " ++ String.fromFloat model.left)
+            , min = 0
+            , max = 1000 - model.width
+            , value = model.left
+            , thumb = Input.defaultThumb
+            , step = Just 1
+            }
+        , Input.slider
+            [ Element.behindContent
+                (Element.el
+                    [ Element.width Element.fill
+                    , Element.height (Element.px 2)
+                    , Element.centerY
+                    , Background.color <| Element.rgb 0.7 0.7 0.7
+                    , Border.rounded 2
+                    ]
+                    Element.none
+                )
+            ]
+            { onChange = \top -> Move model.left top
+            , label =
+                Input.labelBelow [ Element.centerX ] <|
+                    Element.text ("top: " ++ String.fromFloat model.top)
+            , min = 0
+            , max = 1000 - model.width
+            , value = model.top
+            , thumb = Input.defaultThumb
+            , step = Just 1
+            }
+        , Input.slider
+            [ Element.behindContent
+                (Element.el
+                    [ Element.width Element.fill
+                    , Element.height (Element.px 2)
+                    , Element.centerY
+                    , Background.color <| Element.rgb 0.7 0.7 0.7
+                    , Border.rounded 2
+                    ]
+                    Element.none
+                )
+            ]
+            { onChange = \width -> Resize width model.height
+            , label =
+                Input.labelBelow [ Element.centerX ] <|
+                    Element.text ("width: " ++ String.fromFloat model.width)
+            , min = 0
+            , max = 1000 - model.left
+            , value = model.width
+            , thumb = Input.defaultThumb
+            , step = Just 1
+            }
+        , Input.slider
+            [ Element.behindContent
+                (Element.el
+                    [ Element.width Element.fill
+                    , Element.height (Element.px 2)
+                    , Element.centerY
+                    , Background.color <| Element.rgb 0.7 0.7 0.7
+                    , Border.rounded 2
+                    ]
+                    Element.none
+                )
+            ]
+            { onChange = \height -> Resize model.width height
+            , label =
+                Input.labelBelow [ Element.centerX ] <|
+                    Element.text ("height: " ++ String.fromFloat model.height)
+            , min = 0
+            , max = 1000 - model.top
+            , value = model.height
+            , thumb = Input.defaultThumb
+            , step = Just 1
+            }
+        ]
+
+
+world : List (Svg Msg)
+world =
+    [ circle [ cx "400", cy "300", r "250", fill "purple" ] []
+    ]
+
+
+
+--   <|
+--     Element.html <|
+--         graph
+--             [ circle
+--                 [ cx <| String.fromFloat model.x
+--                 , cy <| String.fromFloat model.y
+--                 , r "0.01"
+--                 , fill "magenta"
+--                 ]
+--                 []
+--             , text_
+--                 [ x <| String.fromFloat (model.x + 0.03)
+--                 , y <| String.fromFloat model.y
+--                 , fontSize "0.05"
+--                 , dominantBaseline "central"
+--                 ]
+--                 [ text <| Debug.toString ( model.x, model.y ) ]
+--             ]
+-- ,         ]

Implement three simple examples: Simplest (just SVG), FillTheScreen and CenterdDot

Let the cartesian plane take the edge lenght argument.

index 0d82b4a..83986b5 100644
--- a/src/CartesianPlane.elm
+++ b/src/CartesianPlane.elm
@@ -5,33 +5,54 @@ import Svg exposing (..)
=import Svg.Attributes exposing (..)
=
=
-graph : List (Svg msg) -> Html msg
-graph shapes =
+graph : Float -> List (Svg msg) -> Html msg
+graph size shapes =
=    let
+        top =
+            0 - size / 2
+
+        left =
+            0 - size / 2
+
+        bottom =
+            size / 2
+
+        right =
+            size / 2
+
+        hairline =
+            size / 1000
+
+        fontsize =
+            size / 200
+
=        background =
=            g []
=                [ line
-                    [ x1 "-1"
+                    [ x1 (String.fromFloat left)
=                    , y1 "0"
-                    , x2 "1"
+                    , x2 (String.fromFloat right)
=                    , y2 "0"
=                    , stroke "black"
-                    , strokeWidth "0.001"
+                    , strokeWidth (String.fromFloat hairline)
=                    ]
=                    []
=                , line
=                    [ x1 "0"
=                    , x2 "0"
-                    , y1 "-1"
-                    , y2 "1"
+                    , x2 (String.fromFloat top)
+                    , y2 (String.fromFloat bottom)
=                    , stroke "black"
-                    , strokeWidth "0.001"
+                    , strokeWidth (String.fromFloat hairline)
=                    ]
=                    []
=                ]
=    in
=    svg
-        [ viewBox "-1 -1 2 2"
+        [ [ left, top, size, size ]
+            |> List.map String.fromFloat
+            |> String.join " "
+            |> viewBox
=        , preserveAspectRatio "xMidYMid meet"
=        , Svg.Attributes.width "100%"
=        , Svg.Attributes.height "100%"
new file mode 100644
index 0000000..0382141
--- /dev/null
+++ b/src/CenteredDot.elm
@@ -0,0 +1,18 @@
+module Simplest exposing (main)
+
+import Element
+import Svg
+import Svg.Attributes
+
+
+main =
+    Element.layout
+        [ Element.width Element.fill
+        , Element.height Element.fill
+        ]
+        (Element.html
+            (Svg.svg
+                [ Svg.Attributes.viewBox "-1000 -1000 2000 2000" ]
+                [ Svg.circle [ Svg.Attributes.r "10" ] [] ]
+            )
+        )
new file mode 100644
index 0000000..753928b
--- /dev/null
+++ b/src/FillTheScreen.elm
@@ -0,0 +1,24 @@
+module FillTheScreen exposing (main)
+
+import Element
+import Svg
+import Svg.Attributes
+
+
+main =
+    Element.layout
+        [ Element.width Element.fill
+        , Element.height Element.fill
+        ]
+        (Element.html
+            (Svg.svg
+                [ Svg.Attributes.style "background: pink; height: 100%; width: 100%" ]
+                [ Svg.circle
+                    [ Svg.Attributes.r "10"
+                    , Svg.Attributes.cx "30"
+                    , Svg.Attributes.cy "30"
+                    ]
+                    []
+                ]
+            )
+        )
new file mode 100644
index 0000000..8710e3c
--- /dev/null
+++ b/src/Simplest.elm
@@ -0,0 +1,15 @@
+module Simplest exposing (main)
+
+import Svg
+import Svg.Attributes
+
+
+main =
+    Svg.svg [ Svg.Attributes.style "background: pink" ]
+        [ Svg.circle
+            [ Svg.Attributes.r "10"
+            , Svg.Attributes.cx "30"
+            , Svg.Attributes.cy "30"
+            ]
+            []
+        ]