![]() Similarly, we can run our formula in the opposite direction to determine the geographic latitude and longitude of a pixel position on the screen, useful for zooming in and inspecting points on the map:Ĭonst screenX = canvasX / scale - offsetXĬonst screenY = canvasY / scale - offsetY Similarly, since zoom level follows an exponential scale, we determine a corresponding scale factor to resize between zoom levels.Ĭonst scale = TILE_SIZE * Math.pow(2, zoom) Where offsetX and offsetY represent a pixel offset from the top-left corner of the canvas, based on the current viewport center, zoom level, and viewport size. ![]() Once we have a pair of cartesian coordinates, we can then scale and translate them to screen-space display values based on the user’s viewport state:Ĭonst = projectCoordinates()Ĭonst screenX = (canvasX + offsetX) * scaleĬonst screenY = (canvasY + offsetY) * scale For example, we go from 1 tile (1x1) at zoom level 0, to 4 tiles (2x2) at zoom level 1, to 16 tiles (4x4) at zoom level 2, etc. ![]() We also mentioned that our zoom level follows an exponential scale: each whole number zoom level increase then represents a doubling of the tile count in each dimension. This is helpful to understand how exponential zoom levels affect map projection and rendering.Įach tile is 256x256 pixels, and at the lowest zoom level 0, the entire map can fit on a single tile. It’s worth mentioning briefly that most web maps are built as a grid of tiles, and Felt is no exception. Lastly, we distinguish between our different coordinate systems as world-space (geographic latitude/longitude pairs) and screen-space (display x/y pairs), since everything in Felt exists in a geographic context but ultimately must be drawn on the user’s display in pixels.ĭon’t worry if these concepts are a bit confusing at first, this stuff is tricky! Hopefully they will become clearer as we go on. Note: zoom levels follow an exponential scale, since maps require a relatively very wide range of zoom levels from global to street-level Users can affect the viewport state by panning or zooming around the canvas with a variety of gestures, or resizing their browser window. Along with the viewport size, the center coordinate and zoom level are referred to as the viewport state. The current viewport is determined by the geographic coordinate (latitude and longitude) that sits at the center of the viewport, and a numeric value indicating the current zoom level. Next, we have the viewport, which refers to the region of the canvas that is visible to the user at any given moment. There’s a lot going on in a canvas UI like Felt, so it’s important to settle on some terminology to start:įirst we have the canvas itself, referring in our case to the two-dimensional representation of the world map as a whole, including any shapes drawn by the user. We’ll cover some core concepts around canvas UIs and coordinate systems, talk a bit about gestures and viewport transformations, and lastly discuss some of the tricks we use to make our maps feel lightning fast. In this article, I’ll share a bit about how we built a special canvas from the ground up to power Felt’s geospatial drawing tools. Whether it’s a map or an illustration, we like to refer to this design pattern as a “canvas UI”, mimicking the experience of moving around and manipulating a physical canvas. Most of us have used mapping applications like Google Earth or Apple Maps which let you pan and zoom around the globe or even design tools like Figma and Photoshop which let you jump around and draw on 2d artboards.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |