diff --git a/src/Renderer/Arduino.fs b/src/Renderer/Arduino.fs index 5da8d06..7f6ed5b 100644 --- a/src/Renderer/Arduino.fs +++ b/src/Renderer/Arduino.fs @@ -6,7 +6,6 @@ open Fable.Import open Fable.Import.JohnnyFive open Fable.PowerPack open Types -open Fable.Import.JS [] type pin diff --git a/src/Renderer/Graphics.fs b/src/Renderer/Graphics.fs index acd94cb..d751da9 100644 --- a/src/Renderer/Graphics.fs +++ b/src/Renderer/Graphics.fs @@ -69,6 +69,8 @@ module Numeric = /// Custom Visualisations ///////////////////////// +let private removeMM (x:float<_>) = float x + module Grid = open Types @@ -82,12 +84,12 @@ module Grid = TransformLayer: D3.Selection } - let private removeMM (x:float<_>) = float x - let create (layout:Layout) (dimension:float) = let container = createElement "div" - container.Element.attr("class", unbox "visualisation-grid") |> ignore + container.Element.attr("class", unbox "visualisation-grid") + .style("width", unbox layout.Width) + .style("height", unbox layout.Height) |> ignore let grid = { X = D3.Scale.Globals @@ -172,7 +174,6 @@ module Grid = .append("image") .attr("xlink:href", unbox imageBase64 ) .attr("preserveAspectRatio", unbox "none") - // .attr("transform", unbox (sprintf "translate(%i,%i)" layout.Margin.Left layout.Margin.Top )) .attr("opacity", unbox 0.5) .attr("width", unbox (layout.Width - layout.Margin.Left - layout.Margin.Right)) .attr("height", unbox (layout.Height - layout.Margin.Top - layout.Margin.Bottom)) |> ignore @@ -184,7 +185,6 @@ module Grid = ?enter() ?append("line") ?attr("class", "line line--x") - // ?attr("transform", unbox (sprintf "translate(%i,%i)" layout.Margin.Left layout.Margin.Top )) ?attr("x1", id) ?attr("x2", id) ?attr("y1", 0) @@ -197,7 +197,6 @@ module Grid = ?enter() ?append("line") ?attr("class", "line line--y") - // ?attr("transform", unbox (sprintf "translate(%i,%i)" layout.Margin.Left layout.Margin.Top )) ?attr("x1", 0) ?attr("x2", layout.Width - layout.Margin.Left - layout.Margin.Right) ?attr("y1", id) @@ -207,14 +206,9 @@ module Grid = match transform with | None -> () | Some x -> - let matrix = - [| x.[0]; x.[3]; 0.; x.[6] - x.[1]; x.[4]; 0.; x.[7] - 0.; 0.; 1.; 0. - x.[2]; x.[5]; 0.; 1. |] |> Array.map(fun i -> D3.Globals.round(i,6.)) - let mString = (sprintf "matrix3d(%A)" matrix).Replace("[", "").Replace("]", "") - D3.Globals.select("#transform-layer").style("transform", unbox mString) |> ignore - + let mString = ("matrix3d(" + (x |> Array.rev |> Array.map (fun x -> x.ToString()) |> Array.fold(fun x s -> s + "," + x) "") + ")").Replace(",)", ")") + printfn "Applying matrix... %s" mString + grid.TransformLayer.style("transform", unbox mString) |> ignore grid let withOverlayAdjustment layout grid = @@ -233,7 +227,6 @@ module Grid = let sourcePoints = getBounds() let mutable targetPoints = getBounds() - printfn "Source %A" sourcePoints let moveHandle (x:float) (y:float) = match movingHandle with @@ -243,12 +236,10 @@ module Grid = let rect = svg.getBoundingClientRect() let xFromOrigin = (float x - float rect.left) let yFromOrigin = (float y - rect.top) - printfn "%A %A" xFromOrigin yFromOrigin D3.Globals.select(sprintf ".handle-%i" (int h)) .attr("transform", unbox (sprintf "translate(%f,%f)" xFromOrigin yFromOrigin)) |> ignore targetPoints.[int h] <- [| xFromOrigin ; yFromOrigin |] - printfn "%A %A" sourcePoints targetPoints let x = Numeric.transform sourcePoints targetPoints let matrix = [| x.[0]; x.[3]; 0.; x.[6] @@ -256,6 +247,7 @@ module Grid = 0.; 0.; 1.; 0. x.[2]; x.[5]; 0.; 1. |] |> Array.map(fun i -> D3.Globals.round(i,6.)) let mString = (sprintf "matrix3d(%A)" matrix).Replace("[", "").Replace("]", "") + printfn "Matrix: %s" mString D3.Globals.select("#transform-layer").style("transform", unbox mString) |> ignore // Grab behaviour for grab handles @@ -285,11 +277,89 @@ module Grid = |> toReactElement -module Angle = - - let create () = 2 +module Vertical = + open GraphElement -module Vertical = + type VerticalGraph = { + Container: GraphElement + Svg: D3.Selection + Axis: D3.Scale.Linear + } - let create () = 2 \ No newline at end of file + let create layout zLimit = + let parent = createElement "div" + let svg = parent |> appendSvg layout "vertical" + let z = D3.Scale.Globals.linear() + .range([|layout.Margin.Top |> float; float (layout.Height - layout.Margin.Bottom)|]).domain([|0. ; zLimit |]) + + { Container = parent; Svg = svg; Axis = z } + + let withPlatformAngle layout angle (g:VerticalGraph) = + let stage = g.Svg.append("g") + .attr("class",unbox "rotating-stage") + .style("transform-origin", unbox "bottom right") + let woodWidth, woodHeight = 50,10 + stage.append("rect") + .attr("class", unbox "woodblock") + .style("transform", unbox (sprintf "translate(%ipx,%ipx)" (layout.Margin.Left + (woodWidth / 2)) (layout.Height - layout.Margin.Bottom - woodHeight))) + .attr("height", unbox woodHeight) + .attr("width", unbox <| (layout.Width - layout.Margin.Left - layout.Margin.Right) / 2) |> ignore + stage.append("line") + .attr("class", unbox "stage") + .attr("x1", unbox layout.Margin.Left) + .attr("x2", unbox <| layout.Width - layout.Margin.Right) + .attr("y1", unbox (layout.Height - layout.Margin.Bottom)) + .attr("y2", unbox (layout.Height - layout.Margin.Bottom)) |> ignore + stage.style("transform", unbox (sprintf "rotate(%fdeg)" angle)) |> ignore + g + + let withCurrentPosition (position:float) (g:VerticalGraph) = + g.Svg.append("circle") + .attr("r", unbox 4) + ?attr("cx", unbox 10) + ?attr("cy", unbox (position |> float |> g.Axis.Invoke)) |> ignore + + let withAxis layout (g:VerticalGraph) = + let zAxis = D3.Svg.Globals + .axis() + .scale(g.Axis) + .orient("right") + .tickSize(float (layout.Width - layout.Margin.Left - layout.Margin.Right)) + g.Svg.append("g") + .attr("class", unbox "z axis") + .attr("transform", unbox ("translate(" + (layout.Margin.Left.ToString()) + ",0)")) + ?call(zAxis) + ?append("text") + ?attr("transform", "rotate(-90)") + ?attr("y", 6) + ?attr("dy", ".71em") + ?style("text-anchor", "end") + |> ignore + g + + let withDrillHeight layout height (g:VerticalGraph) = + let currentHeight = g.Svg.append("g") + currentHeight.append("line") + .attr("class", unbox "drill-height") + .attr("x1", unbox layout.Margin.Left) + .attr("x2", unbox <| layout.Width - layout.Margin.Right) + .attr("y1", unbox (height |> removeMM |> g.Axis.Invoke)) + .attr("y2", unbox (height |> removeMM |> g.Axis.Invoke)) |> ignore + currentHeight.append("line") + .attr("class", unbox "drill-vertical-alignment") + .attr("y1", unbox layout.Margin.Top) + .attr("y2", unbox <| layout.Height - layout.Margin.Bottom) + .attr("x1", unbox <| layout.Margin.Left + (layout.Width - layout.Margin.Left - layout.Margin.Right) / 2 ) + .attr("x2", unbox <| layout.Margin.Left + (layout.Width - layout.Margin.Left - layout.Margin.Right) / 2 ) |> ignore + g + + let toReact vert = + vert.Container |> toReactElement + + let complete layout zLimit angle height = + create layout zLimit + |> withPlatformAngle layout angle + |> withAxis layout + |> withDrillHeight layout height + |> toReact \ No newline at end of file diff --git a/src/Renderer/View.fs b/src/Renderer/View.fs index 36b2747..2e086b9 100644 --- a/src/Renderer/View.fs +++ b/src/Renderer/View.fs @@ -48,7 +48,7 @@ module Layout = module Components = let card (title:string) content = - R.div [ Class "card" ] [ + R.div [ Class "card card-secondary" ] [ R.h3 [] [ unbox title ] content ] @@ -97,6 +97,7 @@ module Pages = .Split(',') |> Array.map float |> Software.MatrixTransform.create + printfn "%A" matrix matrix |> Software.SaveCalibrationPosition |> SoftwareMsg |> dispatch let calibrate dispatch model = @@ -160,7 +161,7 @@ module Pages = ] let grid model : React.ReactElement = - let layout : Graphics.GraphElement.Layout = { Height = 300; Width = 300; Margin = { Top = 0; Bottom = 25; Left = 0; Right = 25 } } + let layout : Graphics.GraphElement.Layout = { Height = 400; Width = 400; Margin = { Top = 10; Bottom = 25; Left = 0; Right = 25 } } let imageBase64,matrix = match model.Software.Calibration with | Software.ImageCalibration s -> @@ -174,20 +175,25 @@ module Pages = |> Graphics.Grid.withOverlay layout imageBase64 matrix |> Graphics.Grid.toReact + let verticalGraph : React.ReactElement = + let layout : Graphics.GraphElement.Layout = { Height = 200; Width = 200; Margin = {Top = 0; Left = 0; Right = 25; Bottom = 10 } } + Graphics.Vertical.complete layout 120. 12.21 12. let control (onClick:AppMsg->DOMAttr) (model:AppModel) = R.section [ Id "control-view"; ClassName "main-section" ] [ - R.h1 [] [ unbox "Control" ] - R.hr [] - - Components.container [ - Components.row [ - R.div [ Class "eight columns" ] [ - R.label [] [ unbox "Top View" ] - R.ofFunction grid model [] - // R.ofFunction Graphing.drawVerticalAxis model [] - ] - R.div [ Class "four columns" ] [ + Components.container [ + Components.row [ + R.div [ Class "eight columns" ] [ + R.label [] [ R.str "Top View" ] + R.ofFunction grid model [] + ] + R.div [ Class "four columns" ] [ + R.label [] [ R.str "Vertical" ] + verticalGraph + ] + ] + Components.row [ + R.div [ Class "twelve columns" ] [ Components.card "Manual Controls" (R.div [] [ R.button [ onClick <| HardwareMsg (Hardware.StartMoving (MovementDirection.Y,1.)) ] [ R.str "North" ] diff --git a/src/Styles/_Components.scss b/src/Styles/_Components.scss index 37008ce..8b2f66a 100644 --- a/src/Styles/_Components.scss +++ b/src/Styles/_Components.scss @@ -11,6 +11,12 @@ } } +.card-secondary { + border: 0.75px solid $accent-color; + background-color: $accent-color; + color: $primary-color-text; +} + // Drop zone for files .drop-zone { width: 100%; diff --git a/src/Styles/_TransformCanvas.scss b/src/Styles/_TransformCanvas.scss index 6f4a07b..ea3682c 100644 --- a/src/Styles/_TransformCanvas.scss +++ b/src/Styles/_TransformCanvas.scss @@ -1,4 +1,5 @@ .visualisation-grid { + overflow: hidden; position: relative; svg { position: absolute; @@ -15,7 +16,7 @@ .handle { fill: none; pointer-events: all; - stroke: red; + stroke: $primary-color-dark; stroke-width: 2px; cursor: move; } @@ -36,10 +37,36 @@ #transform-layer { .line--x, .line--y { - stroke: red; + stroke: $primary-color-dark; stroke-opacity: .25; stroke-width: 1px; stroke-linecap: square; } } +} + +#vertical { + .rotating-stage { + transform-origin: bottom right; + .stage { + stroke: #000; + } + .woodblock { + fill: $primary-color; + } + } + .axis { + fill: none; + line { + stroke: grey; + opacity: 0.5; + } + text { + fill: grey; + } + } + .drill-height, .drill-vertical-alignment { + stroke:$primary-color-dark; + stroke-dasharray: 5,5; + } } \ No newline at end of file