Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Tower of Hanoi with Phoenix LiveView

Wu Qing
November 06, 2019

Tower of Hanoi with Phoenix LiveView

Creating a Tower of Hanoi game with Phoenix LiveView. Drag-and-drop implemented with LiveView hooks
Presented at November 2019 meetup of Elixir Sydney
https://www.meetup.com/elixir-sydney/events/bckwkryzpbjb/

Wu Qing

November 06, 2019
Tweet

More Decks by Wu Qing

Other Decks in Programming

Transcript

  1. PHOENIX LIVEVIEW HOOKS const Hooks = { Disk: { mounted()

    { ... } }, DropContainer: { mounted() { ... } } } let liveSocket = new LiveSocket("/live", Socket, {hooks: Hooks}) liveSocket.connect()
  2. LIVEVIEW TEMPLATES WITH HOOKS <div class="subcontainer" phx-hook="DropContainer" phx-value-rodno="<%= @val %>">

    <div class="rod"> <div class="disk-container"> <%= for {n, index} <- Enum.with_index(@rod) do %> <%= if index === 0 do %> <div class="<%= "disk disk#{n}" %>" phx-hook="Disk" draggable="true"></div> <% else %> <div class="<%= "disk disk#{n}" %>"></div> <% end %> <% end %> </div> </div> </div>
  3. JAVASCRIPT DRAG AND DROP I const getRodNo = event =>

    event.target.closest(".subcontainer").getAttribute("phx-value-rodno") Disk: { mounted() { this.el.addEventListener("dragstart", event => { event.target.style.opacity = .7 const rod_no = getRodNo(event) event.dataTransfer.setData("text/plain", rod_no) }, false) this.el.addEventListener("dragend", event => { event.target.style.opacity = "" }, false) } }
  4. JAVASCRIPT DRAG AND DROP II DropContainer: { mounted() { this.el.addEventListener("dragover",

    event => { event.preventDefault() }, false) this.el.addEventListener("dragenter", event => { event.target.style.background = "lightgrey" }, false) this.el.addEventListener("dragleave", event => { event.target.style.background = "" }, false) ... } }
  5. JAVASCRIPT DRAG AND DROP III DropContainer: { mounted() { ...

    this.el.addEventListener("drop", event => { event.preventDefault() event.target.style.background = "" const from_rod_no = event.dataTransfer.getData("text/plain") const to_rod_no = getRodNo(event) this.pushEvent("move-disk", {from: from_rod_no, to: to_rod_no}) }, false) } }
  6. REFERENCES > 3blue1brown hanoi videw 1 > LiveView Documentation >

    HTML Drag and Drop API > Source for Tower of Hanoi with LiveView