From 11d64e5a569eceda6eef4ffe993bbe27da752552 Mon Sep 17 00:00:00 2001 From: Sean Doyle Date: Sun, 26 May 2019 22:12:01 -0400 Subject: [PATCH] Add panning and zooming to SVG map element This commit adds a dependency on the [`svg-pan-zoom` package][svg-pan-zoom]. The plus and minus buttons introduced in the previous commit are decorated with `data-action` declarations which route `click` events to the `seats#zoomIn` and `seats#zoomOut` actions, respectively. When navigating to other floors (i.e. navigations that trigger `seats#discardMap`), [destroy the `svg-pan-zoom` provided instance] during Stimulus' [`disconnect` lifecycle method][disconnect], which is invoked during Turbolinks-initiated page visits, even for elements annotated with `data-turbolinks-permanent`. This commit wraps the collection of `` elements in an outer [`` element][g-element] (as suggested by [aritutta/svg-pan-zoom#146]). [svg-pan-zoom]: https://github.com/ariutta/svg-pan-zoom/tree/3.6.0 [g-element]: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/g [aritutta/svg-pan-zoom#146]: https://github.com/ariutta/svg-pan-zoom/issues/146 [destroy]: https://github.com/ariutta/svg-pan-zoom/tree/3.6.0#public-api [disconnect]: https://stimulusjs.org/reference/lifecycle-callbacks#disconnection --- .../controllers/seats_controller.js | 24 ++++++++++++ app/views/seats/_frame.html.erb | 38 ++++++++++--------- package.json | 1 + yarn.lock | 5 +++ 4 files changed, 51 insertions(+), 17 deletions(-) diff --git a/app/javascript/controllers/seats_controller.js b/app/javascript/controllers/seats_controller.js index e855d915..2b4c96ae 100644 --- a/app/javascript/controllers/seats_controller.js +++ b/app/javascript/controllers/seats_controller.js @@ -1,12 +1,28 @@ import { Controller } from "stimulus" +import svgPanZoom from "svg-pan-zoom" export default class extends Controller { static targets = [ "map", "seat", "selection" ] connect() { + this.map = svgPanZoom(this.mapTarget, { + viewportSelector: "#map-viewport", + center: true, + fit: true, + zoomEnabled: false, + zoomScaleSensitivity: 0.75, + minZoom: 1.0, + maxZoom: 8, + }) this.selectSeats() } + disconnect() { + if (!this.mapTarget.hasAttribute("data-turbolinks-permanent")) { + this.map.destroy() + } + } + discardMap() { this.mapTarget.removeAttribute("data-turbolinks-permanent") } @@ -42,4 +58,12 @@ export default class extends Controller { seat.setAttribute("aria-hidden", false) }) } + + zoomIn() { + this.map.zoomIn() + } + + zoomOut() { + this.map.zoomOut() + } } diff --git a/app/views/seats/_frame.html.erb b/app/views/seats/_frame.html.erb index 60800c9b..0104c841 100644 --- a/app/views/seats/_frame.html.erb +++ b/app/views/seats/_frame.html.erb @@ -91,28 +91,31 @@ - <% seats.each do |seat| %> - - - - - <% end %> + + <% seats.each do |seat| %> + + + + + <% end %> +