From b13ac4ec21b83b51ebd5ccacc70f518bed03d9b2 Mon Sep 17 00:00:00 2001 From: Anton Khorev Date: Sat, 23 Dec 2023 20:38:32 +0300 Subject: [PATCH] Add border/casing/line attribute support to svg map keys --- app/helpers/svg_helper.rb | 34 ++++++++++- app/views/site/key.html.erb | 6 +- test/helpers/svg_helper_test.rb | 99 +++++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+), 6 deletions(-) create mode 100644 test/helpers/svg_helper_test.rb diff --git a/app/helpers/svg_helper.rb b/app/helpers/svg_helper.rb index abb512f0d..21b7c91ad 100644 --- a/app/helpers/svg_helper.rb +++ b/app/helpers/svg_helper.rb @@ -1,7 +1,35 @@ module SvgHelper - def solid_svg_tag(width, height, fill, **options) - tag.svg :width => width, :height => height, **options do - tag.rect :width => "100%", :height => "100%", :fill => fill + def key_svg_tag(**options) + border_width = options["border"] ? (options["border-width"] || 1) : 0 + rect_attrs = { + :width => "100%", + :height => "100%", + :fill => options["fill"] || "none" + } + if border_width.positive? + rect_attrs[:x] = rect_attrs[:y] = format("%g", 0.5 * border_width) + rect_attrs[:width] = options["width"] - border_width + rect_attrs[:height] = options["height"] - border_width end + svg_attrs = options.slice("width", "height", "opacity", :class) + + tag.svg(**svg_attrs) do + concat tag.rect(**rect_attrs, **stroke_attrs(options, "border")) if options["fill"] || options["border"] + concat tag.line(:x2 => "100%", :y1 => "50%", :y2 => "50%", **stroke_attrs(options, "line")) if options["line"] + if options["casing"] + casing_width = options["casing-width"] || 1 + y_top = 0.5 * casing_width + y_bottom = options["height"] - (0.5 * casing_width) + concat tag.g(tag.line(:x2 => "100%", :y1 => y_top, :y2 => y_top) + + tag.line(:x2 => "100%", :y1 => y_bottom, :y2 => y_bottom), + **stroke_attrs(options, "casing")) + end + end + end + + private + + def stroke_attrs(attrs, prefix) + attrs.select { |key| key.start_with?(prefix) }.transform_keys { |key| key.delete_prefix(prefix).prepend("stroke") } end end diff --git a/app/views/site/key.html.erb b/app/views/site/key.html.erb index 28e364685..82105097e 100644 --- a/app/views/site/key.html.erb +++ b/app/views/site/key.html.erb @@ -4,10 +4,10 @@ <% layer_data.each do |entry| %> <%= tag.tr :class => "mapkey-table-entry", :data => { :layer => layer_name, :zoom_min => entry["min_zoom"], :zoom_max => entry["max_zoom"] } do %> - <% if entry["width"] && entry["height"] && entry["fill"] %> - <%= solid_svg_tag entry["width"], entry["height"], entry["fill"], :class => "d-block mx-auto" %> - <% else %> + <% if entry["image"] %> <%= image_tag "key/#{layer_name}/#{entry['image']}", :class => "d-block mx-auto" %> + <% else %> + <%= key_svg_tag :class => "d-block mx-auto", **entry %> <% end %> diff --git a/test/helpers/svg_helper_test.rb b/test/helpers/svg_helper_test.rb new file mode 100644 index 000000000..14c08539c --- /dev/null +++ b/test/helpers/svg_helper_test.rb @@ -0,0 +1,99 @@ +require "test_helper" + +class SvgHelperTest < ActionView::TestCase + def test_key_fill + svg = key_svg_tag("width" => 60, "height" => 40, "fill" => "green") + expected = <<~HTML.gsub(/\n\s*/, "") + + + + HTML + assert_dom_equal expected, svg + end + + def test_key_border + svg = key_svg_tag("width" => 60, "height" => 40, "border" => "red") + expected = <<~HTML.gsub(/\n\s*/, "") + + + + HTML + assert_dom_equal expected, svg + end + + def test_key_border_width + svg = key_svg_tag("width" => 60, "height" => 40, "border" => "red", "border-width" => 3) + expected = <<~HTML.gsub(/\n\s*/, "") + + + + HTML + assert_dom_equal expected, svg + end + + def test_key_border_with_integer_coords + svg = key_svg_tag("width" => 60, "height" => 40, "border" => "red", "border-width" => 2) + expected = <<~HTML.gsub(/\n\s*/, "") + + + + HTML + assert_dom_equal expected, svg + end + + def test_key_border_fractional_width + svg = key_svg_tag("width" => 60, "height" => 40, "border" => "red", "border-width" => 1.5) + expected = <<~HTML.gsub(/\n\s*/, "") + + + + HTML + assert_dom_equal expected, svg + end + + def test_key_line + svg = key_svg_tag("width" => 80, "height" => 20, "line" => "blue") + expected = <<~HTML.gsub(/\n\s*/, "") + + + + HTML + assert_dom_equal expected, svg + end + + def test_key_line_width + svg = key_svg_tag("width" => 80, "height" => 20, "line" => "blue", "line-width" => 3) + expected = <<~HTML.gsub(/\n\s*/, "") + + + + HTML + assert_dom_equal expected, svg + end + + def test_key_casing + svg = key_svg_tag("width" => 80, "height" => 20, "casing" => "yellow") + expected = <<~HTML.gsub(/\n\s*/, "") + + + + + + + HTML + assert_dom_equal expected, svg + end + + def test_key_casing_width + svg = key_svg_tag("width" => 80, "height" => 20, "casing" => "yellow", "casing-width" => 5) + expected = <<~HTML.gsub(/\n\s*/, "") + + + + + + + HTML + assert_dom_equal expected, svg + end +end -- 2.39.5