Build a Tilemap with Angular 6

Using touch and mouse events for web and mobile

Gabrielle Huëbra
B2Expand
3 min readAug 17, 2018

--

My goal was to show a tilemap and be able to select some tiles, whether it was on desktop or mobile. I stumbled upon a problem that included the touch event, some CSS and many div tags.

MouseEvent

My goal

Beginning with the desktop, I used MouseEvents. mousedown and mouseup are used to begin and end the selection, and mouseenter to give the row and column of the last tile.

tilemap.component.html

I bind each MouseEvent to each tile.

tilemap.component.css
tilemap.component.ts

This may seems like much, but don’t worry, it is simple. When we press the mouse button, we begin selecting the tiles. I keep the bounds and I update the tiles consequently (the selected property). It continues until we release the button, and the selection stops. It worked great on desktop 👌.

On browser

Then, I switched to responsive design mode on Firefox to see what happens. If I click, it selects a tile, alright, but if I keep going to select several tiles, it doesn’t work 😭.

With responsive design mode

The Problem

The problem comes from the way the TouchEvent is implemented. You see, there is an order in which the events are fired.

So when I tried to select some tiles, only touchstart and touchmove had been fired at this point, and mouseenter could not possibly be fired.

To resolve this problem, I had to use these TouchEvents.

TouchEvent

We can implement the TouchEvents on the TilemapComponent, and not on each tile element, thanks to the changedTouches property which gives the global coordinates of the touch

tilemap.component.ts (part)

You can see much of my type assertion for the TouchEvents use any : that’s because on desktop Firefox, TouchEvent is undefined 🙄. Besides, we need the type TouchEvent or any in order to use event.changedTouches.

document.elementFromPoint()

My solution was to use the document.elementFromPoint(x,y). This function allows us to get the element with the higher z-index (usually the most nested one). As I can have some Elements before my tiles (as a div showing an image upon my selection), I have to check if the parentElement (the element behind) is my tile or not.

So, I’ve got my tile. Now I need a way to identify it. I could not have access to the object inside the tiles array, only the HTML Element representing this tile. I just had to give my tiles some id that could inform of the row and the column and my problem was solved. I could get this id back and slice it to have the row and the column of the tile.

tilemap.component.html (part)

So, here you go 😁, a foundation upon which many things can be built. Now it’s your turn.

--

--