Changes
7 changed files (+823/-82)
-
-
@@ -56,6 +56,20 @@type alias FreeLoop = { width : Length , play : Length , overlap : Length } type LoopStyle = Simple | Folded type alias Loops = { fixed : Maybe FixedLoop , free : Maybe FreeLoop , style : LoopStyle , thickness : Length }
-
@@ -64,8 +78,7 @@ This does not have to be shorter than `LongPiece`.-} type alias ShortPiece = { length : Length , fixedLoop : Maybe FixedLoop , freeLoop : Maybe FreeLoop , loops : Loops , caseSideFlap : Length , claspSideFlap : Length }
-
@@ -87,6 +100,16 @@ = BlackOnWhite| WhiteOnBlack colorSchemaToString : ColorSchema -> String colorSchemaToString schema = case schema of BlackOnWhite -> "black-on-white" WhiteOnBlack -> "white-on-black" type alias Rendering = { size : CanvasSize , margin : Length
-
@@ -107,6 +130,22 @@ , rendering : Rendering} defaultFixedLoop : FixedLoop defaultFixedLoop = { offset = mm 8 , width = mm 6 , play = mm 1 } defaultFreeLoop : FreeLoop defaultFreeLoop = { width = mm 5 , play = mm 2 , overlap = mm 5 } default : Parameters default = { lugWidth = mm 20
-
@@ -123,17 +162,12 @@ , flap = mm 15} , shortPiece = { length = mm 80 , fixedLoop = Just { offset = mm 8 , width = mm 6 , play = mm 1 } , freeLoop = Just { width = mm 5 , play = mm 2 } , loops = { fixed = Just defaultFixedLoop , free = Just defaultFreeLoop , style = Folded , thickness = mm 1.0 } , caseSideFlap = mm 15 , claspSideFlap = mm 20 }
-
-
-
@@ -15,10 +15,10 @@ import Html.Attributes exposing (..)import Html.Events exposing (onInput) import Html.LivingStandard exposing (..) import Length exposing (Length, toMM) import Parameters exposing (ColorSchema(..), Parameters) import Parameters exposing (ColorSchema(..), Parameters, colorSchemaToString, defaultFixedLoop, defaultFreeLoop) import Parameters.Constraints exposing (NumberConstraints, constraints) import Parameters.Key as Key exposing (Key(..)) import Parameters.Parser exposing (Error(..), parseInt, parseLength) import Parameters.Parser exposing (..)
-
@@ -50,8 +50,39 @@ , ( Key.toString SurfaceThickness, String.fromFloat (toMM params.thickness) ), ( Key.toString LiningThickness, String.fromFloat (toMM params.lining) ) , ( Key.toString BuckleHoleCount, String.fromInt params.longPiece.buckleHole.count ) , ( Key.toString BuckleHoleDiameter, String.fromFloat (toMM params.longPiece.buckleHole.diameter) ) , ( Key.toString LoopThickness, String.fromFloat (toMM params.shortPiece.loops.thickness) ) , ( Key.toString HasFixedLoop , if params.shortPiece.loops.fixed == Nothing then "false" else "true" ) , ( Key.toString FixedLoopWidth , params.shortPiece.loops.fixed |> Maybe.withDefault defaultFixedLoop |> .width |> toMM |> String.fromFloat ) , ( Key.toString FixedLoopPlay , params.shortPiece.loops.fixed |> Maybe.withDefault defaultFixedLoop |> .play |> toMM |> String.fromFloat ) , ( Key.toString HasFreeLoop , if params.shortPiece.loops.free == Nothing then "false" else "true" ) , ( Key.toString FreeLoopWidth , params.shortPiece.loops.free |> Maybe.withDefault defaultFreeLoop |> .width |> toMM |> String.fromFloat ) , ( Key.toString FreeLoopPlay , params.shortPiece.loops.free |> Maybe.withDefault defaultFreeLoop |> .play |> toMM |> String.fromFloat ) , ( Key.toString FreeLoopOverlap , params.shortPiece.loops.free |> Maybe.withDefault defaultFreeLoop |> .overlap |> toMM |> String.fromFloat ) , ( Key.toString CanvasMargin, String.fromFloat (toMM params.rendering.margin) ) , ( Key.toString LineWidth, String.fromFloat (toMM params.rendering.lineWidth) ) , ( Key.toString ColorSchema, colorSchemaToString params.rendering.colorSchema ) ] in { fields = fields
-
@@ -99,6 +130,92 @@ _ ->Nothing parseFixedLoop : Fields -> Result Errors (Maybe Parameters.FixedLoop) parseFixedLoop fields = case parseField HasFixedLoop parseBool fields of Ok True -> case ( parseField FixedLoopWidth (parseLength constraints.shortPiece.loops.fixed.width) fields , parseField FixedLoopPlay (parseLength constraints.shortPiece.loops.fixed.play) fields ) of ( Ok width, Ok play ) -> let base = Parameters.defaultFixedLoop in Ok (Just { base | width = width, play = play }) ( width, play ) -> Err (mkErrors [ ( FixedLoopWidth, getError width ) , ( FixedLoopPlay, getError play ) ] ) _ -> Ok Nothing parseFreeLoop : Fields -> Result Errors (Maybe Parameters.FreeLoop) parseFreeLoop fields = case parseField HasFreeLoop parseBool fields of Ok True -> case ( parseField FreeLoopWidth (parseLength constraints.shortPiece.loops.free.width) fields , parseField FreeLoopPlay (parseLength constraints.shortPiece.loops.free.play) fields , parseField FreeLoopOverlap (parseLength constraints.shortPiece.loops.free.overlap) fields ) of ( Ok width, Ok play, Ok overlap ) -> Ok (Just { width = width, play = play, overlap = overlap }) ( width, play, overlap ) -> Err (mkErrors [ ( FreeLoopWidth, getError width ) , ( FreeLoopPlay, getError play ) , ( FreeLoopOverlap, getError overlap ) ] ) _ -> Ok Nothing parseLoops : Fields -> Result Errors Parameters.Loops parseLoops fields = case ( parseFixedLoop fields, parseFreeLoop fields ) of ( Ok fixed, Ok free ) -> let base = Parameters.default.shortPiece.loops in Ok { base | fixed = fixed, free = free } ( fixed, free ) -> Err (Dict.union (getError fixed |> Maybe.withDefault Dict.empty) (getError free |> Maybe.withDefault Dict.empty) ) parseShortPiece : Fields -> Result Errors Parameters.ShortPiece parseShortPiece fields = case parseLoops fields of Ok loops -> let base = Parameters.default.shortPiece in Ok { base | loops = loops } Err errs -> Err errs parseBuckleHole : Fields -> Result Errors Parameters.BuckleHole parseBuckleHole fields = case
-
@@ -141,20 +258,22 @@ parseCanvas fields =case ( parseField CanvasMargin (parseLength constraints.rendering.margin) fields , parseField LineWidth (parseLength constraints.rendering.lineWidth) fields , parseField ColorSchema parseColorSchema fields ) of ( Ok margin, Ok lineWidth ) -> ( Ok margin, Ok lineWidth, Ok colorSchema ) -> let base = Parameters.default.rendering in Ok { base | margin = margin, lineWidth = lineWidth } Ok { base | margin = margin, lineWidth = lineWidth, colorSchema = colorSchema } ( margin, lineWidth ) -> ( margin, lineWidth, colorSchema ) -> Err (mkErrors [ ( CanvasMargin, getError margin ) , ( LineWidth, getError lineWidth ) , ( ColorSchema, getError colorSchema ) ] )
-
@@ -166,11 +285,13 @@ ( ( parseField LugWidth (parseLength constraints.lugWidth) fields, parseField LiningThickness (parseLength constraints.lining) fields , parseField SurfaceThickness (parseLength constraints.thickness) fields ) , parseLongPiece fields , ( parseLongPiece fields , parseShortPiece fields ) , parseCanvas fields ) of ( ( Ok lugWidth, Ok lining, Ok thickness ), Ok longPiece, Ok rendering ) -> ( ( Ok lugWidth, Ok lining, Ok thickness ), ( Ok longPiece, Ok shortPiece ), Ok rendering ) -> let base = Parameters.default
-
@@ -181,14 +302,16 @@ | lugWidth = lugWidth, lining = lining , thickness = thickness , longPiece = longPiece , shortPiece = shortPiece , rendering = rendering } ( ( lugWidth, lining, thickness ), longPiece, rendering ) -> ( ( lugWidth, lining, thickness ), ( longPiece, shortPiece ), rendering ) -> [ mkErrors [ ( LugWidth, getError lugWidth ) ] , mkErrors [ ( LiningThickness, getError lining ) ] , mkErrors [ ( SurfaceThickness, getError thickness ) ] , getError longPiece |> Maybe.withDefault Dict.empty , getError shortPiece |> Maybe.withDefault Dict.empty , getError rendering |> Maybe.withDefault Dict.empty ] |> List.map Dict.toList
-
@@ -323,6 +446,12 @@NotAnInt -> [ text "Invalid integer value. This field only accepts integer value." ] NotABool -> [ text "Invalid bool value. Value must be either \"true\" or \"false\"." ] NonexistentVariant str -> [ text ("\"" ++ str ++ "\" is not a valid choice. Did you modify program's source code?") ] descriptionId : Key -> String descriptionId key =
-
@@ -380,46 +509,64 @@ )] type alias RadioBoxProps msg = { label : List (Html.Html msg) type alias ChoiceFieldProps msg = { key : Key , title : List (Html.Html msg) , description : List (Html.Html msg) , key : Key , value : String , checked : Bool , onCheck : msg , attrs : List (Html.Attribute msg) , choices : List { value : String , label : List (Html.Html msg) , description : List (Html.Html msg) } } radioBox : RadioBoxProps msg -> List (Html.Attribute msg) -> Html.Html msg radioBox { label, description, key, value, checked, onCheck } attrs = let id = Key.toString key ++ "_" ++ value choiceField : Model -> ChoiceFieldProps Msg -> Html.Html Msg choiceField model { key, title, description, attrs, choices } = node "x-field" [] (span [ slot "title" ] title :: p [ slot "description" ] description :: List.map (\choice -> let id = Key.toString key ++ "_" ++ choice.value choiceDescriptionId = id ++ "__description" choiceDescriptionId = id ++ "__description" in node "x-radio-box" [ if checked then attribute "checked" "" checked = Dict.get (Key.toString key) model.fields |> Maybe.withDefault "" |> (==) choice.value in node "x-radio-box" [ if checked then attribute "checked" "" else class "" ] [ Html.label [ for id, slot "label" ] label , Html.p [ Html.Attributes.id choiceDescriptionId, slot "description" ] description , input (type_ "radio" :: Html.Attributes.id id :: Html.Attributes.name (Key.toString key) :: Html.Attributes.value value :: Html.Attributes.checked checked :: Html.Events.onCheck (\_ -> onCheck) :: ariaDescribedBy [ choiceDescriptionId ] :: attrs ) [] ] else class "" ] [ Html.label [ for id, slot "label" ] choice.label , Html.p [ Html.Attributes.id choiceDescriptionId, slot "description" ] description , input (type_ "radio" :: Html.Attributes.id id :: Html.Attributes.name (Key.toString key) :: Html.Attributes.value choice.value :: Html.Attributes.checked checked :: Html.Events.onCheck (\_ -> FieldChanged key choice.value) :: ariaDescribedBy [ choiceDescriptionId ] :: attrs ) [] ] ) choices ) type alias GroupProps msg =
-
@@ -496,6 +643,87 @@ }] , hr [] [] , group { title = [ text "Loops" ], description = Nothing } [ choiceField model { key = HasFixedLoop , title = [ text "Fixed Loop" ] , description = [ text "Whether to draw fixed loop. Certain kind of deployant buckles don't require a fixed loop." ] , attrs = [] , choices = [ { label = [ text "Enabled" ] , description = [ text "Output fixed loop." ] , value = "true" } , { label = [ text "Disabled" ] , description = [ text "Do not output fixed loop." ] , value = "false" } ] } , numberField model { key = FixedLoopWidth , title = [ text "Fixed Loop Width" ] , description = [ text "Width of the fixed loop." ] , unit = Just "mm" , disabled = not (Dict.get (Key.toString HasFixedLoop) model.fields == Just "true") , attrs = step "0.1" :: lengthFieldAttrs constraints.shortPiece.loops.fixed.width } , numberField model { key = FixedLoopPlay , title = [ text "Fixed Loop Play" ] , description = [ text "Extra length to add to the fixed loop, for adjusting tightness." ] , unit = Just "mm" , disabled = not (Dict.get (Key.toString HasFixedLoop) model.fields == Just "true") , attrs = step "0.1" :: lengthFieldAttrs constraints.shortPiece.loops.fixed.play } , choiceField model { key = HasFreeLoop , title = [ text "Free Loop" ] , description = [ text "Whether to draw free loop. Certain kind of deployant buckles don't require a free loop." ] , attrs = [] , choices = [ { label = [ text "Enabled" ] , description = [ text "Output free loop." ] , value = "true" } , { label = [ text "Disabled" ] , description = [ text "Do not output free loop." ] , value = "false" } ] } , numberField model { key = FreeLoopWidth , title = [ text "Free Loop Width" ] , description = [ text "Width of the free loop." ] , unit = Just "mm" , disabled = not (Dict.get (Key.toString HasFreeLoop) model.fields == Just "true") , attrs = step "0.1" :: lengthFieldAttrs constraints.shortPiece.loops.free.width } , numberField model { key = FreeLoopPlay , title = [ text "Free Loop Play" ] , description = [ text "Extra length to add to the free loop, for adjusting tightness." ] , unit = Just "mm" , disabled = not (Dict.get (Key.toString HasFreeLoop) model.fields == Just "true") , attrs = step "0.1" :: lengthFieldAttrs constraints.shortPiece.loops.free.play } , numberField model { key = FreeLoopOverlap , title = [ text "Free Loop Overlap" ] , description = [ text "Length of overlapping section of the free loop for gluing and/or stitching." ] , unit = Just "mm" , disabled = not (Dict.get (Key.toString HasFreeLoop) model.fields == Just "true") , attrs = step "0.1" :: lengthFieldAttrs constraints.shortPiece.loops.free.overlap } ] , hr [] [] , group { title = [ text "Rendering" ], description = Nothing } [ numberField model { key = CanvasMargin
-
@@ -515,30 +743,21 @@ , unit = Just "mm", disabled = False , attrs = step "0.1" :: lengthFieldAttrs constraints.rendering.lineWidth } , node "x-field" [] [ label [ for (Key.toString ColorSchema), slot "title" ] [ text "Color Schema" ] , p [ id (descriptionId ColorSchema), slot "description" ] [ text "Color schema of the template." ] , radioBox { key = ColorSchema , label = [ text "Black on White" ] , description = [ text "Select this if you print the template with a regular printer." ] , value = "bow" , checked = model.parameters.rendering.colorSchema == BlackOnWhite , onCheck = ColorSchemaChanged BlackOnWhite } [] , radioBox { key = ColorSchema , label = [ text "White on Black" ] , description = [ text "For digital output. Printing this with an inkjet printer is not a good idea." ] , value = "wob" , checked = model.parameters.rendering.colorSchema == WhiteOnBlack , onCheck = ColorSchemaChanged WhiteOnBlack } [] ] , choiceField model { key = ColorSchema , title = [ text "Color Schema" ] , description = [ text "Color schema of the template." ] , attrs = [] , choices = [ { label = [ text "Black on White" ] , description = [ text "Select this if you print the template with a regular printer." ] , value = colorSchemaToString BlackOnWhite } , { label = [ text "White on Black" ] , description = [ text "For digital output. Printing this with an inkjet printer is not a good idea." ] , value = colorSchemaToString WhiteOnBlack } ] } ] ]
-
-
-
@@ -19,6 +19,30 @@ , max : Maybe a} type alias FixedLoop = { width : NumberConstraints Length , play : NumberConstraints Length } type alias FreeLoop = { width : NumberConstraints Length , play : NumberConstraints Length , overlap : NumberConstraints Length } type alias Loops = { fixed : FixedLoop , free : FreeLoop } type alias ShortPiece = { loops : Loops } type alias BuckleHole = { count : NumberConstraints Int , diameter : NumberConstraints Length
-
@@ -39,6 +63,7 @@type alias Parameters = { lugWidth : NumberConstraints Length , longPiece : LongPiece , shortPiece : ShortPiece , lining : NumberConstraints Length , thickness : NumberConstraints Length , rendering : Rendering
-
@@ -52,6 +77,19 @@ , longPiece ={ buckleHole = { count = { min = Just 0, max = Just 10 } , diameter = { min = Just (mm 1), max = Just (mm 10) } } } , shortPiece = { loops = { fixed = { width = { min = Just (mm 1), max = Just (mm 15) } , play = { min = Just (mm 0), max = Just (mm 10) } } , free = { width = { min = Just (mm 1), max = Just (mm 15) } , play = { min = Just (mm 0), max = Just (mm 10) } , overlap = { min = Just (mm 0), max = Just (mm 10) } } } } , lining = { min = Just (mm 0), max = Just (mm 5) }
-
-
-
@@ -16,6 +16,14 @@ | SurfaceThickness| LiningThickness | BuckleHoleCount | BuckleHoleDiameter | LoopThickness | HasFixedLoop | FixedLoopWidth | FixedLoopPlay | HasFreeLoop | FreeLoopWidth | FreeLoopPlay | FreeLoopOverlap | CanvasMargin | LineWidth | ColorSchema
-
@@ -38,6 +46,30 @@ "buckle-hole-count"BuckleHoleDiameter -> "buckle-hole-diameter" LoopThickness -> "loop-thickness" HasFixedLoop -> "has-fixed-loop" FixedLoopWidth -> "fixed-loop-width" FixedLoopPlay -> "fixed-loop-play" HasFreeLoop -> "has-free-loop" FreeLoopWidth -> "free-loop-width" FreeLoopPlay -> "free-loop-play" FreeLoopOverlap -> "free-loop-overlap" CanvasMargin -> "canvas-margin"
-
-
-
@@ -7,9 +7,10 @@ ---- SPDX-License-Identifier: MPL-2.0 module Parameters.Parser exposing (Error(..), parseInt, parseLength) module Parameters.Parser exposing (Error(..), parseBool, parseColorSchema, parseInt, parseLength) import Length exposing (Length, mm, toMM) import Parameters exposing (ColorSchema(..)) import Parameters.Constraints as Constraints
-
@@ -19,6 +20,8 @@ | BelowMin Float| AboveMax Float | NotALength | NotAnInt | NonexistentVariant String | NotABool parseInt : Constraints.NumberConstraints Int -> String -> Result Error Int
-
@@ -110,3 +113,29 @@ |> Maybe.map mm|> Result.fromMaybe NotALength |> min |> max parseBool : String -> Result Error Bool parseBool text = case text of "true" -> Ok True "false" -> Ok False _ -> Err NotABool parseColorSchema : String -> Result Error ColorSchema parseColorSchema text = case text of "white-on-black" -> Ok WhiteOnBlack "black-on-white" -> Ok BlackOnWhite _ -> Err (NonexistentVariant text)
-
-
-
@@ -10,7 +10,7 @@module Template exposing (template) import Length exposing (Length, toMM) import Parameters exposing (Parameters, canvasSizeDimension) import Parameters exposing (LoopStyle(..), Parameters, canvasSizeDimension) import String import Svg exposing (..) import Svg.Attributes exposing (..)
-
@@ -86,6 +86,9 @@ ]] , surfacePieces params (TopLeft ( margin, margin )) , linings params (TopRight ( canvasWidth - margin, margin )) -- TODO: Move below the linings , loops params (BottomRight ( canvasWidth - margin, canvasHeight - margin )) ]
-
@@ -604,3 +607,385 @@ , strokeWidth (toMM params.rendering.lineWidth |> String.fromFloat)] [] ] loops : Parameters -> Anchor -> Svg msg loops params anchor = let root = params.shortPiece.loops in if root.fixed == Nothing && root.free == Nothing then g [] [] else let gap = toMM params.rendering.gap lugWidth = toMM params.lugWidth strapThickness = toMM params.thickness + toMM params.lining widthModifier = case root.style of Simple -> 1.0 Folded -> 2.0 freeLoopLength = lugWidth * 2 + strapThickness * 2 + (root.free |> Maybe.map .play |> Maybe.map toMM |> Maybe.withDefault 0) + (root.free |> Maybe.map .overlap |> Maybe.map toMM |> Maybe.withDefault 0) freeLoopWidth = root.free |> Maybe.map .width |> Maybe.map toMM |> Maybe.withDefault 0 |> (*) widthModifier fixedLoopLength = lugWidth * 2 + strapThickness * 2 + (root.fixed |> Maybe.map .play |> Maybe.map toMM |> Maybe.withDefault 0) fixedLoopWidth = root.fixed |> Maybe.map .width |> Maybe.map toMM |> Maybe.withDefault 0 |> (*) widthModifier sectionWidth = Basics.max freeLoopLength fixedLoopLength headerHeight = 5.0 ( ox, oy ) = topLeftFor anchor (Size sectionWidth (headerHeight + gap / 2 + freeLoopWidth + gap + fixedLoopWidth)) in g [] [ text_ [ x (ox + sectionWidth / 2 |> String.fromFloat) , y (oy + 4 |> String.fromFloat) , fontSize "5" , fontWeight "100" , textAnchor "middle" , fill "currentColor" ] [ text ("Loops / t = " ++ (toMM root.thickness |> String.fromFloat) ++ "mm") ] , fixedLoop params (TopLeft ( ox, oy + headerHeight + gap / 2 )) , freeLoop params (TopLeft ( ox, oy + headerHeight + gap * 1.5 + fixedLoopWidth )) ] fixedLoop : Parameters -> Anchor -> Svg msg fixedLoop params anchor = case params.shortPiece.loops.fixed of Nothing -> g [] [] Just { width, play } -> let strapThickness = toMM params.thickness + toMM params.lining lugWidth = toMM params.lugWidth length = lugWidth * 2 + strapThickness * 2 + toMM play materialWidth = case params.shortPiece.loops.style of Simple -> toMM width Folded -> toMM width * 2 ( ox, oy ) = topLeftFor anchor (Size length materialWidth) hCutLine : Float -> Svg msg hCutLine yOffset = g [ fill "none" , stroke "currentColor" , strokeWidth (toMM params.rendering.lineWidth |> String.fromFloat) ] [ Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox, oy + yOffset ) , HorizontalLineTo Relative lugWidth ] ] [] , Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox + lugWidth, oy + yOffset ) , HorizontalLineTo Relative strapThickness ] ] [] , Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox + lugWidth + strapThickness, oy + yOffset ) , HorizontalLineTo Relative lugWidth ] ] [] , Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox + lugWidth * 2 + strapThickness, oy + yOffset ) , HorizontalLineTo Relative strapThickness ] ] [] , Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox + lugWidth * 2 + strapThickness * 2, oy + yOffset ) , HorizontalLineTo Relative (toMM play) ] ] [] ] in g [] [ hCutLine 0 , hCutLine materialWidth , case params.shortPiece.loops.style of Simple -> g [ fill "none" , stroke "currentColor" , strokeWidth (toMM params.rendering.lineWidth |> String.fromFloat) ] [ Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox, oy ) , VerticalLineTo Relative (toMM width) ] ] [] , Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox + length, oy ) , VerticalLineTo Relative (toMM width) ] ] [] ] Folded -> g [] [ g [ fill "none" , stroke "currentColor" , strokeWidth (toMM params.rendering.lineWidth |> String.fromFloat) , strokeDasharray "1 0.5" ] [ Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox, oy + toMM width / 2 ) , HorizontalLineTo Relative length ] ] [] , Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox, oy + toMM width * 1.5 ) , HorizontalLineTo Relative length ] ] [] ] , g [ fill "none" , stroke "currentColor" , strokeWidth (toMM params.rendering.lineWidth |> String.fromFloat) ] [ Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox, oy ) , VerticalLineTo Relative (toMM width * 2) ] ] [] , Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox + length, oy ) , VerticalLineTo Relative (toMM width * 2) ] ] [] ] ] ] freeLoop : Parameters -> Anchor -> Svg msg freeLoop params anchor = case params.shortPiece.loops.free of Nothing -> g [] [] Just { width, play, overlap } -> let strapThickness = toMM params.thickness + toMM params.lining lugWidth = toMM params.lugWidth length = lugWidth * 2 + strapThickness * 2 + toMM play + toMM overlap materialWidth = case params.shortPiece.loops.style of Simple -> toMM width Folded -> toMM width * 2 ( ox, oy ) = topLeftFor anchor (Size length materialWidth) hCutLine : Float -> Svg msg hCutLine yOffset = g [ fill "none" , stroke "currentColor" , strokeWidth (toMM params.rendering.lineWidth |> String.fromFloat) ] [ Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox, oy + yOffset ) , HorizontalLineTo Relative lugWidth ] ] [] , Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox + lugWidth, oy + yOffset ) , HorizontalLineTo Relative strapThickness ] ] [] , Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox + lugWidth + strapThickness, oy + yOffset ) , HorizontalLineTo Relative lugWidth ] ] [] , Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox + lugWidth * 2 + strapThickness, oy + yOffset ) , HorizontalLineTo Relative strapThickness ] ] [] , Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox + lugWidth * 2 + strapThickness * 2, oy + yOffset ) , HorizontalLineTo Relative (toMM play) ] ] [] , Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox + lugWidth * 2 + strapThickness * 2 + toMM play, oy + yOffset ) , HorizontalLineTo Relative (toMM overlap) ] ] [] ] in g [] [ hCutLine 0 , hCutLine materialWidth , Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox + toMM overlap, oy ) , VerticalLineTo Relative materialWidth ] , fill "none" , stroke "currentColor" , strokeWidth (toMM params.rendering.lineWidth |> String.fromFloat) , strokeDasharray "1 0.5" ] [] , case params.shortPiece.loops.style of Simple -> g [ fill "none" , stroke "currentColor" , strokeWidth (toMM params.rendering.lineWidth |> String.fromFloat) ] [ Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox, oy ) , VerticalLineTo Relative (toMM width) ] ] [] , Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox + length, oy ) , VerticalLineTo Relative (toMM width) ] ] [] ] Folded -> g [] [ g [ fill "none" , stroke "currentColor" , strokeWidth (toMM params.rendering.lineWidth |> String.fromFloat) , strokeDasharray "1 0.5" ] [ Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox, oy + toMM width / 2 ) , HorizontalLineTo Relative length ] ] [] , Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox, oy + toMM width * 1.5 ) , HorizontalLineTo Relative length ] ] [] ] , g [ fill "none" , stroke "currentColor" , strokeWidth (toMM params.rendering.lineWidth |> String.fromFloat) ] [ Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox, oy ) , VerticalLineTo Relative (toMM width * 2) ] ] [] , Svg.path [ Svg.Path.d [ MoveTo Absolute ( ox + length, oy ) , VerticalLineTo Relative (toMM width * 2) ] ] [] ] ] ]
-
-
-
@@ -27,6 +27,10 @@ ::slotted(x-radio-box) {margin: 0.1rem -0.5rem !important; } ::slotted(x-radio-box:last-child) { margin-bottom: 1.5rem !important; } ::slotted(input[aria-invalid="true"]) { border-color: oklch(40% 0.88 2deg); }
-