Helping guide you through the never-ending forest of technology, into the open glade of easy to follow posts!
Creating an Interactive World Map: With Leaflet.js
Creating an Interactive World Map: With Leaflet.js

Creating an Interactive World Map: With Leaflet.js

I’ve been playing Dungeons and Dragons as a player for quite a while, but when the latest adventure came to a close I decided to step up to the plate and run the next campaign in my own Homebrew setting!

I really wanted to give my players a world map that allowed them to zoom and pan around to explore the world I had created with markers on towns and cities, but couldn’t find anything that fit the build, until I discovered Leaflet.js (which is even mobile-friendly!)

If you’re wanting to see the end results of this project before starting, you can see the map and code at the bottom of this post. This guide will work on both Mac and Windows and whilst the guide does involve typing a little bit of code, everything is detailed below. You’ll also need Photoshop, anything higher than CS2 will work.

Getting Your World Map Ready

For the purposes of this guide, I’m going to assume that you’ve already got a world map ready to work on! If you don’t currently have one then you can generate lovely looking maps on Azgaar’s Fantasy Map Generator.

After finalising your world map you need to convert your single image map into a collection of tiles–this is to save on bandwidth, but also provides tiles for the different zoom levels, as less detail is needed when zoomed out.

The first thing you’ll want to do is create a project folder, this will contain everything needed for the end result to upload!

To create the tiles you’ll need to use the photoshop-google-maps-tile-cutter script by bramus. This script is straightforward but can take a while depending on the size of your map. Other than the export path, you’ll want the script export settings to match the settings below. Additionally, you can change the background colour to match your water.

NOTE: Make sure that your map size is a multiple of 256, just increase your canvas size to the next multiple. (My map is 15360 x 15360)

This script also creates a Google Maps version of the image, however, due to some API changes it no longer works properly–this was the first route I went down before encountering these issues.

After you’ve created all of your tiles you’ll want to run the end results through a .png optimiser. This gets rid of unneeded data without any quality reduction. My program of choice for this is PNGYU which is based on pngquant and allows batch compressing!

To do this, drag the whole exported folder into PNGYU, and use the following settings.

When this has finished exporting, you’ll want to place the end result in its own folder within your project folder. I recommend naming this folder map, the end result should look something like this.

Getting Started With Leaflet.js

Now that you’ve tiled and compressed your map it’s now time to get started with Leaflet.js. The first thing you’ll want to do is jump over to their website, The website is extremely useful and well documented, so if you’re after additional features I recommend having a look!

Navigate to the downloads page and download the latest version (Leaflet 1.5.1 at the time of writing). After downloading you’ll want to open up your project folder and create a new folder called scripts. Then extract the .zip into that folder.

After doing this you’ll start creating the actual map! You can use any text editor, but I recommend using Notepad++ or Atom. Firstly create a new file in your chosen editor and insert the below text, with the only variable to change being the background to the same colour you used earlier.

<!DOCTYPE html>
<html = style="height: 100%;">
		<title>DnD World Map</title>
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<link rel="stylesheet" href="scripts/leaflet.css">
		<script src="scripts/leaflet.js"></script>
	<body style="height: 100%;margin: 0;">
		<div id="map" style="width: 100%; height: 100%; background: #000000;"></div>
		<script type="text/javascript">
	//Creating the Map
		var map ='map').setView([0, 0], 0);
		L.tileLayer('map/{z}/{x}/{y}.png', {
			continuousWorld: false,
			noWrap: true,	
			minZoom: 0,
			maxZoom: 10,
	//Coordinate Finder
		var marker = L.marker([0, 0], {
			draggable: true,
		marker.bindPopup('LatLng Marker').openPopup();
		marker.on('dragend', function(e) {

After adding this to the file, save it to your project folder and name it index.html. If you open the file now you should be greeted by your world map! There are a couple of variables that you will need to adjust depending on the size of your world map image.

For me, the Photoshop Script created folders from 0 to 6 – which correspond to different zoom levels. Your index.html file will open to your map at zoom level 0, which for me was far too zoomed out! To fix this I changed the minZoom variable to 3–which corresponds to pressing the + button 3 times. Adjust this until you are happy with the minimum zoom value.

You will also notice that if you press the ‘Zoom In’ button several times your map will disappear completely. This is because you will only be able to zoom in the number of folders available. To fix this, you will want to set your maxZoom to the highest folder number–for me this valve is 6. If you don’t like how close you can zoom in, decrease this number further.

After you’re happy with the minimum and maximum zoom levels you can then delete the folders outside of this range, this will save you space by not uploading unnecessary files.

Creating Map Markers

Now that you’ve added and configured your map in Leaflet.js it’s time to add some markers! You’ll notice that there is already one marker in the centre of your map named LatLng. This is what you’ll be using to create additional markers.

For this section I recommend creating a spreadsheet to list all of your different towns and places that you are wanting to put markers on. The spreadsheet should include:

  • A unique ID
  • X Coordinate (First number in bracket)
  • Y Coordinate (Second number in bracket)

Drag the marker around the map and make note of the X,Y coordinates and give each location a unique ID–I went from East to West across my map to make sure I collated all places. Don’t worry if you miss any, you can come back and add them later!

Now that you’ve created a list of all your markers/waypoints you can begin to add them to the map! You will need to create an individual line for each, and you will want to add them underneath //Markers in your HTML file. Here are several examples from my map from the above spreadsheet.

var el_gulndar = L.marker([36.0135, -106.3916]).bindPopup('<b>Gulndar</b>').addTo(map);
var el_teglhus = L.marker([44.4965, -100.7666]).bindPopup('<b>Teglhus</b>').addTo(map);
var el_ochri_college = L.marker([48.5166,-103.4692]).bindPopup('<b>Ochri College</b>').addTo(map);

As you can see in my example, it has created three markers on my world map which when clicked on show their place-name. The generic syntax for creating these markers is as follows, with the words in capitals needing to be changed.

var UNIQUE ID = L.marker([X VALUE, Y VALUE]).bindPopup('PLACE NAME').addTo(map)

After you’re happy that you have all of your markers in the right place and working, you can delete the text between //Coordinate Finder and //Markers as this is no longer required.

Grouping Markers

After adding your markers your world map might look messy due to the number of markers covering it, this is where grouping markers together is extremely useful!

The first stage to grouping your markers will be to remove some code from each marker. Currently, your markers include .addTo(map) which means that marker will be visible. Remove .addTo(map) from all of your markers, but make sure to leave the ; at the end of each line. This means that all markers will now disappear from your map.

How you decide to group your markers is entirely up to you! I broke mine up into the following categories:

  • Mage Colleges
  • Trading Posts
  • Cities
  • Towns
  • Forts/Castles
  • Temples

Once you have finalised your groups you’ll want to create your group variables–you will need one of these for each group. At the bottom of your marker section add the following code, again with the variables you need to change in capitals:

//Marker Groups
    var mg_GROUPNAME = L.layerGroup([LIST,OF,MARKERS]);
    var mg_ANOTHERGROUP = L.layerGroup([SOME,MORE,PLACES]);
//Marker Overlay
    var overlays={
    L.control.layers(null, overlays).addTo(map);

After changing all of the above variables the full marker code looked like this:

	var el_gulndar = L.marker([36.4919, -114.038]).bindPopup('<b>Gulndar</b>');
	var el_teglhus = L.marker([45.3058, -108.413]).bindPopup('<b>Teglhus</b>');
	var el_ochri_college = L.marker([48.5166,-111.2255]).bindPopup('<b>Ochri College</b>');
//Marker Groups
	var mg_towns = L.layerGroup([el_gulndar,el_teglhus]);
	var mg_towers = L.layerGroup([el_ochri_college]);
//Marker Overlay
	var overlays={
		"Towns" : mg_towns,
		"Towers" : mg_towers,
	L.control.layers(null, overlays).addTo(map);

When you now load your map, you will notice that all of your markers have disappeared! In order to see the markers, use the menu at the top right of the screen to hide and show marker groups!

Now depending on how you’re planning to use this map, you’ll either want to upload the contents of your project folder to the root directory of your website. This will mean the map will load instantly when you type in your url.

If you are wanting to do something similar to the below map, instead rename and upload the whole project folder then create an iframe on your website site using the below code structure:

<iframe src="https://URL/PROJECT FOLDER" width="100%" height="600"></iframe>

This project has been something I was really happy to complete. After nearly giving up I am extremely happy that I found Leaflet.js! I know that the above can be a little bit confusing so if you have any questions, drop a comment below and I’d be more than happy to answer them!

Project Result

This is now my updated map, which was built using Campaign Cartographer 3, on the version for my party the map has more than two zoom levels, but to save on bandwidth I have limited this demo version to only two. This version also features some additional features to the above tutorial such as custom map pins, I will update the tutorial to include this when I get a free moment. 🙂

Project Code

<!DOCTYPE = html>
<html style="height: 100%;">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="scripts/leaflet.css">
        <script src="scripts/leaflet.js"></script>

    <body style="height: 100%; margin: 0;">
        <div id="map" style="width: 100%; height: 100%; background: #53679f;"></div>
        <script type="text/javascript">
        //Creating the Map
            var map ='map').setView([0, 0], 0);
            L.tileLayer('tiles/{z}/{x}/{y}.png', {
                continuousWorld: false,
                noWrap: true,
                minZoom: 3,
                maxZoom: 6,
            var el_gulndar = L.marker([36.0135, -106.3916]).bindPopup('<b>Gulndar</b>');
            var el_teglhus = L.marker([44.4965, -100.7666]).bindPopup('<b>Teglhus</b>');
            var el_ochri_college = L.marker([48.5166,-103.4692]).bindPopup('<b>Ochri College</b>');
            var el_circle_of_the_land = L.marker([32.2871,-85.8691]).bindPopup('<b>Druid Camp</b>');
            var el_westhaven = L.marker([18.3128,-109.6875]).bindPopup('<b>Westhaven</b>');
            var el_glaenarm = L.marker([19.394,-92.5488]).bindPopup('<b>Glaenarm</b>');
            var el_mirstone = L.marker([14.4346,-64.9511]).bindPopup('<b>Mirstone</b>');
            var el_butterpond = L.marker([2.8991,-120.6738]).bindPopup('<b>Butterpond</b>');
            var el_pirin_post = L.marker([10.9196,-87.6269]).bindPopup('<b>Pirn Post</b>');
            var el_mistrith_keep = L.marker([-2.1088,-93.6035]).bindPopup('<b>Mistrith Keep</b>')
            var el_zimban = L.marker([-18.0623,-106.6113]).bindPopup('<b>Zimban</b>');
            var el_noblar = L.marker([-7.2752,-88.8574]).bindPopup('<b>Noblar</b>');
            var el_hommet_post = L.marker([-13.4751,-95.4052]).bindPopup("<b>Hommet's Trading Post</b>");
            var el_fangdor_fortress = L.marker([-12.8974,-125.332]).bindPopup('<b>Fangdor Fortress</b>');
            var el_tel_kibil = L.marker([-20.8793,-79.8925]).bindPopup('<b>Tel Kibil</b>');
            var el_saradim = L.marker([-37.7185,-107.4902]).bindPopup('<b>Saradim</b>');
            var el_ankoret = L.marker([-30.1451,-95.1855]).bindPopup('<b>Ankoret</b>');
            var el_bulasi_stables = L.marker([-41.9676,-94.2187]).bindPopup('<b>Bulasi Stables</b>');
            var el_cinders_college = L.marker([-50.5971,-91.4721]).bindPopup('<b>Cinders College</b>');
            var el_delarin_stronghold = L.marker([-36.7388,-83.9355]).bindPopup('<b>Delarin Stronghold</b>');
            var el_the_golden_palace = L.marker([-26.0567,-69.3237]).bindPopup('<b>The Golden Palace</b>');
            var el_the_soot_healer = L.marker([-0.2536,-70.9497]).bindPopup('<b>The Soot Healer</b>');
            var el_yarrow = L.marker([-26.1948,-52.8002]).bindPopup('<b>Yarrow</b>');
            var el_harron = L.marker([-42.8598,-44.165]).bindPopup('<b>Harron</b>');
            var el_tenbrie = L.marker([-55.8136,-46.0986]).bindPopup('<b>Tenbrie</b>');
            var el_umberlee = L.marker([-51.9442,-35.4638]).bindPopup('<b>Temple of Umberlee</b>');
            var el_dawsbury_post = L.marker([-17.4345,-40.6274]).bindPopup('<b>Dasbury Post</b>');
            var el_whitebridge_pass = L.marker([-3.8423,-40.5615]).bindPopup('<b>Whitebridge Pass</b>');
            var el_reedwater = L.marker([21.5144,-27.1801]).bindPopup('<b>Reedwater</b>');
            var el_nythi_asari = L.marker([-25.0258,-25.1147]).bindPopup('<b>Nythi Asari</b>');
            var el_layla_asari = L.marker([-12.1252,-12.788]).bindPopup('<b>Layla Asari</b>');
            var el_mystra = L.marker([-9.1671,-27.3339]).bindPopup('<b>Temple of Mystra</b>');
            var el_helm = L.marker([-0.2197,-53.4811]).bindPopup('<b>Temple of Helm</b>');
            var el_circle_of_the_moon = L.marker([-39.3852,-37.2656]).bindPopup('<b>Druid Camp</b>');
        //Maystrus Isle
            var ma_emyi_dorei = L.marker([9.2973,-0.1977]).bindPopup('<b>Emyi Dorei</b>');
            var ma_seiche_college = L.marker([26.3524,1.7138]).bindPopup('<b>Seiche College</b>');
        //Amspar Key
            var am_port_clulx = L.marker([-41.4262,-17.1606]).bindPopup('<b>Port Clulx</b>');
            var am_port_khel = L.marker([-28.8446,6.8994]).bindPopup('<b>Port Khel</b>');
            var or_jarrens_outpost = L.marker([14.4346,36.4746]).bindPopup("<b>Jarren's Outpost</b>");
            var or_myrefall = L.marker([13.5819,21.0058]).bindPopup('<b>Myrefall</b>');
            var or_hythe = L.marker([9.102,55.8105]).bindPopup('<b>Hythe</b>');
            var or_pavvs_stable = L.marker([-2.3065,42.2094]).bindPopup("<b>Pavv's Stable</b>");
            var or_guthram = L.marker([-4.5435,54.9975]).bindPopup('<b>Guthram</b>');
            var or_ballymena = L.marker([-12.0393,33.6621]).bindPopup('<b>Ballymena</b>');
            var or_eastcliff_crossroad = L.marker([-28.1495,35.2441]).bindPopup('<b>Eastcliff Crossroad</b>');
            var or_erast = L.marker([-34.3071,60.1611]).bindPopup('<b>Erast</b>');
            var or_grasshope = L.marker([-37.3177,20.2368]).bindPopup('<b>Grasshope</b>');
            var or_thornheart_college = L.marker([-44.9803,31.311]).bindPopup('<b>Thornheart College</b>');
            var or_torrine = L.marker([-22.1467,61.7431]).bindPopup('<b>Torrine</b>');
            var or_port_venzor = L.marker([-30.4486,87.2534]).bindPopup('<b>Port Venzor</b>');
            var or_greenflower = L.marker([-42.391,76.8603]).bindPopup('<b>Greenflower</b>');
            var or_bellmare = L.marker([-30.6946,125.0683]).bindPopup('<b>Bellmare: City of Fire</b>');
            var or_anyor = L.marker([-15.0296,111.3793]).bindPopup('<b>Anyor</b>');
            var or_aynor_post = L.marker([-10.5958,122.5854]).bindPopup('<b>Aynor Post</b>');
            var or_ormskirk = L.marker([-2.7455,111.1376]).bindPopup('<b>Ormskirk</b>');
            var or_garens_well = L.marker([9.1888,106.5893]).bindPopup("<b>Garen's Well</b>");
            var or_port_wormbourne = L.marker([20.3652,131.7919]).bindPopup("<b>Port Wormbourne</b>");
            var or_tamsworth = L.marker([20.5916,117.7075]).bindPopup("<b>Tamsworth</b>");
            var or_nuxvar = L.marker([20.5505,103.0078]).bindPopup("<b>Nuxvar</b>");
            var or_orion = L.marker([29.3438,87.9565]).bindPopup("<b>Orion: Capital of Oakla</b>");
            var or_skystead_nook = L.marker([19.9113,80.4638]).bindPopup("<b>Skystead Nook</b>");
            var or_bramblewoods = L.marker([4.4778,73.7622]).bindPopup("<b>Bramble Woods</b>");
            var or_lancer_gate = L.marker([7.6238,69.6972]).bindPopup("<b>Lancer Gate</b>");
            var or_leira = L.marker([44.887,54.9755]).bindPopup("<b>Temple of Leira</b>");
            var or_kelemvor = L.marker([-12.1252,79.475]).bindPopup("<b>Shrine of Kelemvor</b>");
            var or_mask = L.marker([-42.9242,71.2792]).bindPopup("<b>Shine of Mask</b>");
            var or_palace_plenty = L.marker([-15.2205,12.1289]).bindPopup("<b>Eiflin: The Palace Plenty</b>");
            var or_eldath = L.marker([-1.9112,11.3818]).bindPopup("<b>Temple of Eldath</b>");
            var or_bhel_thoram = L.marker([28.652,39.0673]).bindPopup("<b>Bhel Thoram</b>");
            var or_kelgrum = L.marker([39.09563,52.0532]).bindPopup("<b>Kelgrum</b>");
            var or_gar_dural = L.marker([23.7652,58.3154]).bindPopup("<b>Gar Dural</b>");
            var or_bhel_thoram2 = L.marker([27.3717,76.5087]).bindPopup("<b>Bhel Thoram</b>");
            var or_dblook_college = L.marker([31.0152,100.0195]).bindPopup("<b>Dblook College</b>");
            var or_gilnium_vineyards = L.marker([35.2994,111.5991]).bindPopup("<b>Gilnium Vineyards</b>");
            var or_pine_castle = L.marker([-4.5216,89.3408]).bindPopup("<b>Pine Castle</b>");
            var or_fort_eaglecrest = L.marker([-8.2114,112.6538]).bindPopup("<b>Fort Eaglecrest</b>");
            var or_knifeedge_creek = L.marker([-20.8177,109.0942]).bindPopup("<b>Knife-edge Creek</b>");
            var or_healthy_horse_post = L.marker([-11.4154,58.8427]).bindPopup("<b>The Healthy Horse Post</b>");
            var or_malar = L.marker([52.6563,96.8774]).bindPopup("<b>Temple of Malar</b>");
            var or_kejgrav = L.marker([54.7246,73.3007]).bindPopup("<b>Kejgrav</b>");
            var or_rukule_cross = L.marker([47.2344,88.1103]).bindPopup("<b>Rukule Cross</b>");
            var or_norreborg = L.marker([43.0046,108.9843]).bindPopup("<b>Nørborg</b>");
            var or_world_rod = L.marker([43.7234,77.7512]).bindPopup("<b>World Rod?</b>");
        //Marker Groups
            var mg_mage_colleges = L.layerGroup([el_ochri_college,el_cinders_college,ma_seiche_college,or_thornheart_college,or_dblook_college]);
            var mg_trading_posts = L.layerGroup([el_pirin_post,el_hommet_post,el_bulasi_stables,el_dawsbury_post,or_jarrens_outpost,or_pavvs_stable,or_eastcliff_crossroad,or_aynor_post,or_garens_well,or_skystead_nook,or_gilnium_vineyards,or_healthy_horse_post,or_rukule_cross]);
            var mg_cities = L.layerGroup([el_gulndar,el_glaenarm,el_butterpond,el_noblar,el_ankoret,el_yarrow,el_tenbrie,el_layla_asari,ma_emyi_dorei,or_myrefall,or_hythe,or_ballymena,or_grasshope,or_torrine,or_port_venzor,or_bellmare,or_ormskirk,or_port_wormbourne,or_orion,or_bhel_thoram,or_bhel_thoram2,or_kejgrav]);
            var mg_towns = L.layerGroup([el_westhaven,el_mirstone,el_zimban,el_tel_kibil,el_saradim,el_harron,el_reedwater,el_nythi_asari,am_port_clulx,am_port_khel,or_guthram,or_erast,or_greenflower,or_anyor,or_tamsworth,or_nuxvar,or_bramblewoods,or_kelgrum,or_gar_dural,or_norreborg]);
            var mg_forts = L.layerGroup([el_teglhus,el_mistrith_keep,el_fangdor_fortress,el_delarin_stronghold,el_the_golden_palace,el_whitebridge_pass,or_lancer_gate,or_palace_plenty,or_pine_castle,or_fort_eaglecrest,or_knifeedge_creek]);
            var mg_temples = L.layerGroup([el_circle_of_the_land,el_the_soot_healer,or_eldath,el_mystra,el_helm,or_leira,or_kelemvor,el_circle_of_the_moon,el_umberlee,or_mask,or_malar,or_world_rod]);
        //Marker Overlay
            var overlays = {
					"Mage Colleges" : mg_mage_colleges,
					"Trading Posts" : mg_trading_posts,
					"Cities" : mg_cities,
					"Towns" : mg_towns,
					"Forts/Castles" : mg_forts,
					"Temples" : mg_temples,
        //Marker Group Control
            L.control.layers(null, overlays).addTo(map);

by Sam Brooks

Sam is the founder and editor for Tech Trail. With a background in Broadcast Engineering, and great enthusiasm for smart home and emerging technologies.

More by Sam →

  • Twitter
  • KoFi
  • Email

Sam Brooks

Sam is the founder and editor for Tech Trail. A Broadcast Engineer with a passion for technology and design. Working on the bleeding edge of technology Sam is exposed to a vast amount of emerging technologies and likes to keep up to date on the latest tech in general.


    1. Absolutely! If you just want to show someone else the map, just send them over the Project Folder and tell them to open the index.html file and it will display your map! Alternatively if you have a website, upload the whole project folder to your site (this is how I’ve done it). I uploaded my map to a folder on my website called dnd, and renamed the index.html to oakla.html, which can be viewed at as a full page map, then wherever I want to show the map as only part of the website I use an iframe with the above code as a template, for the above example the code is iframe src=”” width=”100%” height=”600″(with <> brackets surrounding it and a closing /iframe at the end. Please let me know if you need further details! I’m happy to help 🙂

      1. rumi waldman

        Hi, really love this project, it was exacly what I was looking for. I really wanted to try and make a free site and upload my map there yet had difficulties with many of the sites making services. When it came to uploading the map to the root directory as you said you’ve done. I was unable to reach it or upload to it my full folder.
        I tried using WP like I see you have done here yet my programing skills and site making skills are basically non-existent. I was wondering if maybe you can show how to make a site for the map for free. After my research, WP seemed like the most promising option but it was too much for me to understand. If you can help with that that would be amazing.

        1. Sam Brooks

          Hey Rumi,
          You don’t necessarily need access to the root folder, this was just done for simplicity, you just need to be able to upload the folder to your host just somewhere you can access the files within as part of your url.

          This may be slightly harder with a free website host, as they typically offer very limited functionality in the hope you buy their packages, so am unable to advice on this really.

          Once you’ve uploaded the above it’s very easy to include it on any site, for example if you add:

          <iframe src="" width="100%" height="600"></iframe>

          you will see my map on your site, just substitute the URL for your map’s address.

    1. Happy to help! I’ll write a quick overview here, but will write a full guide at some point!

      I firstly generated my map using Azgaar’s Fantasy Map Generator and set the colours to tritone for the water and a solid colour for the map, I exported this as well as the temperature and political maps.

      I took the end results into Photoshop, and created a small tileset (I’ll include further details in my write up) I place the towns and other markers throughout the map using stamps. After finalising my towns I used the pen tool to create the paths between towns.

      Hope that overview gives you some idea of how I made the map but will detail further in a post 🙂

    1. Hey Stef, never too late!

      1. You can absolutely change the markers, and have done this on the next iteration of this map, which looks like this

      I will create a new post at some point to detail this easier, but the steps involved are to create your new markers and put them in an icons folder within the project, then create a variable for each icon like so:

      Then add the respective variable to your markers, like so:

      After that your new markers should appear nicely on your map 🙂

      2. I’ve not tried to add hyperlinks to the markers so will have a look when I get a chance, but as an immediate solution you could add the link into the pop-up that appears, like so:

      Let me know if you need more information 🙂

      1. Elv

        Thank you so much for making this post, as it was exactly what I needed to get started myself.

        Previously I have been using other solutions for interactive maps (map plugins within WordPress), however this is going to be the route I go from now as it has dramatically improved my map in all the different ways!

        In addition to what you describe in the tutorial above, I have added a ruler so I can easily measure the distances on my map, and I have used my own pins for the various types of markers. (I plan to redo them to make it more obvious what they are). I also did some adjustments to the pop-up window, just to get the information showing the way I wanted. And last but not least, I spent some time setting up a complete spreadsheet that takes my raw data and puts it into a string that I can copy-paste into my HTML-document. My map I currently run directly from my Dropbox, so its safe and secure, and the loading speed is flawless.

        All in all, I am so incredibly satisfied right now, and I have you to thank for making me think I could do it, thanks to your tutorial. So many, many thanks! 😀

        I noticed you saying you would love to see examples, so here’s a peek at my map:
        And here’s a peek at my master spreadsheet which I then feed to my HTML:

        PS: Since I see you writing that you may make an updated version of this tutorial, I would like to mention that I struggled for a while in regards to getting the map tiles right and the organization of them and how that affected the setup in the HTML, so if anything, perhaps if you had a few more words on this part to explain that might help others too! 🙂

        Either way, awesome!
        Thank you again.
        – Elv

        1. Hey Elv,
          Thank you for your kind words and awesome example!

          In regards to your PS, the map tile organisation is based on the line L.tileLayer(’tiles/{z}/{x}/{y}.png’ which matches the folder structure exported🙂 So the first folder is “zoom level” then it’s co-ordinate based so folder 4/0/0 would be the 4th level of zoom in’s top left.

          Hope that explains it better 🙂

  1. Mojo

    Hi Sam, thanks for the tutorial! I’m running into a problem where when I zoom-in past the minZoom (which we set to 3), I’m just presented with nothing but the background colour (with no images). Any tips?

    1. Hey,
      The number of zoom levels you get is based on the size of your original image. You can see the number of zoom levels available to you in the images folder.
      If your min/max zoom level is smaller/larger than this you will be presented with only the background image as there are no map tiles to display. 🙂

      To get more levels of zoom, the easiest way is to scale up the size of your image and then re-export it!
      Hope this helps 🙂

Leave a Reply

Your email address will not be published.