Commits: 5

Make BrowserWindow example (main) bigger

index 2714ed3..b5db0fa 100644
--- a/src/BrowserWindow.elm
+++ b/src/BrowserWindow.elm
@@ -10,6 +10,10 @@ import Html exposing (Html)
=main : Html msg
=main =
=    Element.text "Hello World!"
+        |> Element.el
+            [ Element.width (Element.px 400)
+            , Element.height (Element.px 400)
+            ]
=        |> window
=        |> Element.layout []
=

Remove the ui helper from Simplest and Centered dot

Instead move this code to Main module.

index fef1177..7c7ef14 100644
--- a/src/CenteredDot.elm
+++ b/src/CenteredDot.elm
@@ -6,18 +6,16 @@ import Svg.Attributes
=
=
=main =
-    Element.layout
-        [ Element.width Element.fill
-        , Element.height Element.fill
+    Svg.svg
+        [ Svg.Attributes.style "background: pink"
+        , Svg.Attributes.width "300"
+        , Svg.Attributes.height "150"
+        , Svg.Attributes.viewBox "-100 -100 200 200"
=        ]
-        ui
-
-
-ui =
-    Element.html
-        (Svg.svg
-            [ Svg.Attributes.viewBox "-100 -100 200 200"
-            , Svg.Attributes.height "200"
+        [ Svg.circle
+            [ Svg.Attributes.r "10"
+            , Svg.Attributes.cx "0"
+            , Svg.Attributes.cy "0"
=            ]
-            [ Svg.circle [ Svg.Attributes.r "10" ] [] ]
-        )
+            []
+        ]
index 0591a0c..a32f254 100644
--- a/src/Main.elm
+++ b/src/Main.elm
@@ -225,8 +225,17 @@ options =
=
=        simplestView : Styling -> Model -> Element Msg
=        simplestView style model =
-            Simplest.ui
-                |> Element.el []
+            Simplest.main
+                |> Element.html
+                |> Element.el
+                    [ Element.width (Element.px 300)
+                    , Element.height (Element.px 150)
+                    ]
+                |> Element.el
+                    [ Element.height (Element.minimum 400 Element.shrink)
+                    , Element.width Element.fill
+                    , Element.padding 10
+                    ]
=                |> BrowserWindow.window
=
=        fillTheScreenBlock : Mark.Custom.Block Model Styling Msg
@@ -248,9 +257,11 @@ options =
=
=        centeredDotView : Styling -> Model -> Element Msg
=        centeredDotView style model =
-            CenteredDot.ui
+            CenteredDot.main
+                |> Element.html
=                |> Element.el
-                    [ Element.centerX
+                    [ Element.height (Element.px 400)
+                    , Element.width Element.fill
=                    ]
=                |> BrowserWindow.window
=
index 27930cc..dee7dbd 100644
--- a/src/Simplest.elm
+++ b/src/Simplest.elm
@@ -1,4 +1,4 @@
-module Simplest exposing (main, ui)
+module Simplest exposing (main)
=
=import Element
=import Svg
@@ -7,7 +7,10 @@ import Svg.Attributes
=
=main =
=    Svg.svg
-        [ Svg.Attributes.style "background: pink; height: 100%; width: 100%" ]
+        [ Svg.Attributes.style "background: pink"
+        , Svg.Attributes.width "300"
+        , Svg.Attributes.height "150"
+        ]
=        [ Svg.circle
=            [ Svg.Attributes.r "10"
=            , Svg.Attributes.cx "30"
@@ -15,7 +18,3 @@ main =
=            ]
=            []
=        ]
-
-
-ui =
-    Element.html main

Write a comment explaining how to position an object in the center of the viewBox

index 7c7ef14..59fb692 100644
--- a/src/CenteredDot.elm
+++ b/src/CenteredDot.elm
@@ -1,4 +1,23 @@
-module CenteredDot exposing (main, ui)
+module CenteredDot exposing (main)
+
+{-| This program demonstrates how to center an element within an SVG viewport. The idea is to make sure that (0, 0) point (so called origin) should be in the middle of the ViewBox. We can achive that, by making the top-left corner of the ViewBox same distance from the (0, 0) as the bottom right.
+
+The viewBox property takes a string consisting of four numbers:
+
+    - position of the top edge
+    - position of the left edge
+    - width
+    - and height
+
+If we set the width to 200 and then set the left edge to -100, that will place the right edge at +100. Both edges are 100 away from the 0!
+
+The same way you can control the bottom edge by tweaking the position of the top edge and the height.
+
+In fact it doesnt matter how wide and high the viewBox is. As long as the top will be -1/2 of the width and left will be -1/2 of the width.
+
+That's the trick to position an object (like a dot) exactly in the center of the SVG viewport
+
+-}
=
=import Element
=import Svg

Fix the embeded programs layouts

Make BrowserWindow.window take a list of attributes, so it's possible to size the window as required.

index b5db0fa..91c211c 100644
--- a/src/BrowserWindow.elm
+++ b/src/BrowserWindow.elm
@@ -14,12 +14,12 @@ main =
=            [ Element.width (Element.px 400)
=            , Element.height (Element.px 400)
=            ]
-        |> window
+        |> window []
=        |> Element.layout []
=
=
-window : Element msg -> Element msg
-window content =
+window : List (Element.Attribute msg) -> Element msg -> Element msg
+window attributes content =
=    let
=        circle : Element.Color -> Element msg
=        circle color =
@@ -34,32 +34,33 @@ window content =
=                    , Font.center
=                    ]
=    in
-    Element.column
-        [ Element.width Element.shrink
-        , Element.height Element.shrink
-        , Border.width 2
-        , Border.rounded 6
-        , Border.color <| Element.rgb 0.27 0.27 0.27
-        , Background.color <| Element.rgb 0.27 0.27 0.27
-        , Element.clip
-        ]
-        [ Element.row
-            [ Element.height <| Element.px <| 23
-            , Element.width Element.fill
-            , Border.widthEach { bottom = 2, left = 0, top = 0, right = 0 }
-            , Border.color <| Element.rgb 0.2 0.2 0.2
-            , Element.paddingXY 10 15
-            ]
-            ([ ( 1, 0.4, 0.3 ), ( 1, 0.75, 0.18 ), ( 0.16, 0.79, 0.26 ) ]
-                |> List.map
-                    (\( red, green, blue ) ->
-                        circle (Element.rgb red green blue)
-                    )
-            )
-        , Element.el
+    Element.el attributes <|
+        Element.column
=            [ Element.width Element.fill
-            , Element.width Element.fill
-            , Background.color <| Element.rgb 1 1 1
+            , Element.height Element.fill
+            , Border.width 2
+            , Border.rounded 6
+            , Border.color <| Element.rgb 0.27 0.27 0.27
+            , Background.color <| Element.rgb 0.27 0.27 0.27
+            , Element.clip
+            ]
+            [ Element.row
+                [ Element.height <| Element.px <| 23
+                , Element.width Element.fill
+                , Border.widthEach { bottom = 2, left = 0, top = 0, right = 0 }
+                , Border.color <| Element.rgb 0.2 0.2 0.2
+                , Element.paddingXY 10 15
+                ]
+                ([ ( 1, 0.4, 0.3 ), ( 1, 0.75, 0.18 ), ( 0.16, 0.79, 0.26 ) ]
+                    |> List.map
+                        (\( red, green, blue ) ->
+                            circle (Element.rgb red green blue)
+                        )
+                )
+            , Element.el
+                [ Element.width Element.fill
+                , Element.height Element.fill
+                , Background.color <| Element.rgb 1 1 1
+                ]
+                content
=            ]
-            content
-        ]
index d7cfc83..56f88d6 100644
--- a/src/FillTheScreen.elm
+++ b/src/FillTheScreen.elm
@@ -14,14 +14,15 @@ main =
=
=
=ui =
-    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"
-                ]
-                []
+    Svg.svg
+        [ Svg.Attributes.style "background: pink"
+        , Svg.Attributes.viewBox "-100 -100 200 200"
+        ]
+        [ Svg.circle
+            [ Svg.Attributes.r "10"
+            , Svg.Attributes.cx "0"
+            , Svg.Attributes.cy "0"
=            ]
-        )
+            []
+        ]
+        |> Element.html
index a32f254..acbf627 100644
--- a/src/Main.elm
+++ b/src/Main.elm
@@ -10,6 +10,7 @@ import Element.Background as Background
=import Element.Border as Border
=import Element.Events
=import Element.Input as Input
+import FeatherIcons exposing (icons)
=import FillTheScreen
=import Gradient
=import Html exposing (Html)
@@ -215,8 +216,13 @@ options =
=                |> Counter.ui
=                |> Element.el
=                    [ Element.centerX
+                    , Element.centerY
+                    ]
+                |> Element.el
+                    [ Element.height (Element.px 400)
+                    , Element.width Element.fill
=                    ]
-                |> BrowserWindow.window
+                |> BrowserWindow.window []
=                |> Element.map CounterMsg
=
=        simplestBlock : Mark.Custom.Block Model Styling Msg
@@ -228,15 +234,11 @@ options =
=            Simplest.main
=                |> Element.html
=                |> Element.el
-                    [ Element.width (Element.px 300)
-                    , Element.height (Element.px 150)
-                    ]
-                |> Element.el
-                    [ Element.height (Element.minimum 400 Element.shrink)
+                    [ Element.height (Element.px 400)
=                    , Element.width Element.fill
=                    , Element.padding 10
=                    ]
-                |> BrowserWindow.window
+                |> BrowserWindow.window []
=
=        fillTheScreenBlock : Mark.Custom.Block Model Styling Msg
=        fillTheScreenBlock =
@@ -246,10 +248,10 @@ options =
=        fillTheScreenView style model =
=            FillTheScreen.ui
=                |> Element.el
-                    [ Element.width Element.fill
-                    , Element.height Element.fill
+                    [ Element.height (Element.px 400)
+                    , Element.width Element.fill
=                    ]
-                |> BrowserWindow.window
+                |> BrowserWindow.window []
=
=        centeredDotBlock : Mark.Custom.Block Model Styling Msg
=        centeredDotBlock =
@@ -262,8 +264,9 @@ options =
=                |> Element.el
=                    [ Element.height (Element.px 400)
=                    , Element.width Element.fill
+                    , Element.padding 10
=                    ]
-                |> BrowserWindow.window
+                |> BrowserWindow.window []
=
=        lineBlock : Mark.Custom.Block Model Styling Msg
=        lineBlock =
@@ -275,7 +278,7 @@ options =
=                |> Element.el
=                    [ Element.centerX
=                    ]
-                |> BrowserWindow.window
+                |> BrowserWindow.window []
=
=        gradientBlock : Mark.Custom.Block Model Styling Msg
=        gradientBlock =
@@ -287,7 +290,7 @@ options =
=                |> Element.el
=                    [ Element.centerX
=                    ]
-                |> BrowserWindow.window
+                |> BrowserWindow.window []
=
=        transformationsBlock : Mark.Custom.Block Model Styling Msg
=        transformationsBlock =
@@ -298,7 +301,8 @@ options =
=            model.transformations
=                |> Transformations.ui
=                |> Element.el
-                    [ Element.centerX
+                    [ Element.height Element.fill
+                    , Element.width Element.fill
=                    ]
=                |> Element.el
=                    [ Element.centerX
@@ -377,7 +381,7 @@ options =
=                |> Element.el
=                    [ Element.centerX
=                    ]
-                |> BrowserWindow.window
+                |> BrowserWindow.window []
=
=        spiralBlock : Mark.Custom.Block Model Styling Msg
=        spiralBlock =
@@ -388,8 +392,11 @@ options =
=            Spiral.ui
=                |> Element.el
=                    [ Element.centerX
+                    , Element.width Element.fill
+
+                    -- , Element.height Element.fill
=                    ]
-                |> BrowserWindow.window
+                |> BrowserWindow.window []
=
=        treeBlock : Mark.Custom.Block Model Styling Msg
=        treeBlock =
@@ -438,7 +445,7 @@ options =
=                                    ]
=            in
=            content
-                |> BrowserWindow.window
+                |> BrowserWindow.window []
=
=        viewBoxBlock : Mark.Custom.Block Model Styling Msg
=        viewBoxBlock =
@@ -448,9 +455,6 @@ options =
=        viewBoxView style model =
=            model.viewBox
=                |> ViewBox.ui
-                |> Element.el
-                    [ Element.centerX
-                    ]
=                |> Element.el
=                    [ Element.centerX
=                    , Border.color (Element.rgb 1 0.6 0.6)
index 27129df..1f34423 100644
--- a/src/NestedTransformations.elm
+++ b/src/NestedTransformations.elm
@@ -95,7 +95,7 @@ ui model =
=    let
=        wrapper element =
=            Element.column
-                [ Element.width (Element.maximum 600 Element.fill)
+                [ Element.width Element.fill
=                , Element.centerX
=                , Element.spacing 20
=                ]
index 09c888e..7e1ae87 100644
--- a/src/Spiral.elm
+++ b/src/Spiral.elm
@@ -40,10 +40,9 @@ ui =
=    in
=    Element.html
=        (Svg.svg
-            [ Svg.Attributes.height "400"
-            , Svg.Attributes.viewBox "-100 -100 200 200"
+            [ Svg.Attributes.viewBox "-100 -100 200 200"
=            ]
-            (defs :: spiral 500)
+            (defs :: spiral 50)
=        )
=
=
@@ -52,7 +51,7 @@ spiral age =
=    if age > 0 then
=        let
=            length =
-                500 / toFloat age
+                50 / toFloat age
=        in
=        [ Svg.line
=            [ Svg.Attributes.x2 "1"
index 5de8663..cfc9865 100644
--- a/src/ViewBox.elm
+++ b/src/ViewBox.elm
@@ -73,49 +73,48 @@ update : Msg -> Model -> Model
=update msg model =
=    case msg of
=        Move left top ->
-            { model | left = left, top = top }
+            { model
+                | left = left
+                , top = top
+            }
=
=        Resize width height ->
-            { model | width = width, height = height }
+            { model
+                | width = width
+                , height = height
+            }
=
=
=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.maximum 500 Element.fill
-                , Element.width <| Element.maximum 500 Element.fill
+    let
+        viewbox =
+            svg
+                [ viewBox "-500 -500 1000 1000"
+
+                -- , Svg.Attributes.style "width: 100%; height: 100%"
=                ]
-                (Element.html <|
-                    svg
-                        [ viewBox "0 0 1000 1000"
-                        , Svg.Attributes.style "width: 100%; height: 100%"
-                        ]
-                        [ 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.3"
-                            , stroke "white"
-                            , fill "pink"
-                            ]
-                            []
-                        ]
-                )
-            , svg
+                [ 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.3"
+                    , stroke "white"
+                    , fill "pink"
+                    ]
+                    []
+                ]
+                |> Element.html
+                |> Element.el
+                    [ Element.centerX
+                    , Element.centerY
+                    , Element.width Element.fill
+                    , Element.height Element.fill
+                    ]
+
+        viewport =
+            svg
=                [ [ model.left, model.top, model.width, model.height ]
=                    |> List.map String.fromFloat
=                    |> String.join " "
@@ -136,11 +135,31 @@ ui model =
=                    []
=                ]
=                |> Element.html
-                |> BrowserWindow.window
=                |> Element.el
=                    [ Element.width Element.fill
=                    , Element.height Element.fill
=                    ]
+                |> BrowserWindow.window
+                    [ Element.centerX
+                    , Element.centerY
+                    , Element.width Element.fill
+                    , Element.height Element.fill
+                    ]
+    in
+    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
+            ]
+            [ viewbox
+            , viewport
=            ]
=        , Input.slider
=            [ Element.behindContent
@@ -158,8 +177,8 @@ ui model =
=            , label =
=                Input.labelBelow [ Element.centerX ] <|
=                    Element.text ("left: " ++ String.fromFloat model.left)
-            , min = 0
-            , max = 1000 - model.width
+            , min = -500
+            , max = 500
=            , value = model.left
=            , thumb = Input.defaultThumb
=            , step = Just 1
@@ -180,8 +199,8 @@ ui model =
=            , label =
=                Input.labelBelow [ Element.centerX ] <|
=                    Element.text ("top: " ++ String.fromFloat model.top)
-            , min = 0
-            , max = 1000 - model.width
+            , min = -500
+            , max = 500
=            , value = model.top
=            , thumb = Input.defaultThumb
=            , step = Just 1
@@ -203,7 +222,7 @@ ui model =
=                Input.labelBelow [ Element.centerX ] <|
=                    Element.text ("width: " ++ String.fromFloat model.width)
=            , min = 1
-            , max = 1000 - model.left
+            , max = 500
=            , value = model.width
=            , thumb = Input.defaultThumb
=            , step = Just 1
@@ -225,7 +244,7 @@ ui model =
=                Input.labelBelow [ Element.centerX ] <|
=                    Element.text ("height: " ++ String.fromFloat model.height)
=            , min = 1
-            , max = 1000 - model.top
+            , max = 500
=            , value = model.height
=            , thumb = Input.defaultThumb
=            , step = Just 1
@@ -237,5 +256,5 @@ world : List (Svg Msg)
=world =
=    [ circle [ cx "400", cy "300", r "250", fill "purple" ] []
=    , circle [ cx "200", cy "350", r "50", fill "yellow" ] []
-    , circle [ cx "400", cy "600", r "20", fill "red" ] []
+    , circle [ cx "0", cy "0", r "20", fill "red" ] []
=    ]

Add control of aspect ratio preservation to ViewBox example

index cfc9865..5a4bad5 100644
--- a/src/ViewBox.elm
+++ b/src/ViewBox.elm
@@ -33,12 +33,14 @@ type alias Model =
=    , top : Float
=    , width : Float
=    , height : Float
+    , preserveAspectRatio : Bool
=    }
=
=
=type Msg
=    = Move Float Float
=    | Resize Float Float
+    | PreserveAspectRatio Bool
=
=
=init : Model
@@ -47,6 +49,7 @@ init =
=    , top = 0
=    , width = 400
=    , height = 400
+    , preserveAspectRatio = False
=    }
=
=
@@ -84,14 +87,15 @@ update msg model =
=                , height = height
=            }
=
+        PreserveAspectRatio value ->
+            { model | preserveAspectRatio = value }
+
=
=ui model =
=    let
=        viewbox =
=            svg
=                [ viewBox "-500 -500 1000 1000"
-
-                -- , Svg.Attributes.style "width: 100%; height: 100%"
=                ]
=                [ g [] world
=                , rect
@@ -119,7 +123,13 @@ ui model =
=                    |> List.map String.fromFloat
=                    |> String.join " "
=                    |> viewBox
-                , preserveAspectRatio "none"
+                , preserveAspectRatio <|
+                    case model.preserveAspectRatio of
+                        True ->
+                            "xMidYMid meet"
+
+                        False ->
+                            "none"
=                , Svg.Attributes.style "width: 100%; height: 100%"
=                ]
=                [ g [] world
@@ -249,6 +259,12 @@ ui model =
=            , thumb = Input.defaultThumb
=            , step = Just 1
=            }
+        , Input.checkbox []
+            { checked = model.preserveAspectRatio
+            , icon = Input.defaultCheckbox
+            , label = Input.labelRight [] (Element.text "Preserve aspect ratio")
+            , onChange = PreserveAspectRatio
+            }
=        ]
=
=