Interactive front-end game, written in ReactJS, utilising the Mapbox GL JS API. Deployed on AWS S3 + CloudFront.
This project is a ReactJS version of an another HTML-CSS-JavaScript project, which I originally created for Code Institute's Web Development Course.
Not for public use.
© 2023 Szilvia Csernusne Berczes. All rights reserved.
Wireframes were created in Balsamiq.
Seven colours were needed to paint the countries on the map. I chose these vibrant colours to convey playfulness, as well as to cater for users with visual imparements. See more info here
Colours for correct and incorrect choices are the traditional red/green colours, their specific bright tones were chosen to stand out from their background.
Map colours:
Background and feedback colours:
I selected the font named Nunito from the Google Fonts library for its simplicity and legibility yet fairly informal look.
Mapbox allows to custom style its maps in Mapbox Studio. I used the freely available country-boundaries-v1 tileset and coloured the countries with the chosen colours with the help of the tileset's color-group property. This property makes sure that no adjacent countries will be coloured the same.
The exit, info, checkmark, cross and star icons were all downloaded from svgrepo. Credits to individual icons are given in the credits section.
For favicons, I created a small logo in Figma and used the RealFaviconGenerator to convert it to favicons.
The main data source for this project is Mapbox's country-boundaries-v1 tileset. The tileset's countries and territories are defined in the ISO 3166-1 country code standard, including alternate worldviews. I filter for some of the conflicting worldviews to avoid ambiguity. Data in this tileset is based on information obtained from officially recognized local or international entities. The displayed country boundaries and the identification of countries / territories are coming from this dataset.
- The game should test the players' knowledge of the world's countries.
- The game should be visually appealing.
- It should give simple, clear instructions.
- The countries should be visually distinguishable.
- It should include animations to raise interest.
- It should be interactive.
- Player should be given feedback about the chosen country.
- High scores should be retained in the browser if settings allow.
- The game should look well and run on a wide range of devices.
- The game should be fun to play.
- Countries should be colourful and easy to recognise.
- The rules should be easy to follow.
- It should give feedback about the chosen country.
- It should retain high scores.
- The game should look well and run on a wide range of devices.
When visiting the first time, it takes a while (depending on network speed) to load all source code and tilesets from Mapbox. While waiting for loading, an animation is used to fill the time. Once the map is ready, it appears on the screen and the game can be started with the PLAY
button.
The first time a user visits the site, an animation gives brief instructions on how to play the game. Later on, the animation will not show again but the instructions will be available when clicking the question mark icon in the top right corner. In case the user clears up the site's localStorage, the animation will show again as if they were visiting for the first time.
Another feature is the option to play with sounds. If the user clicks the muted speaker
icon in the top right corner, the background music will start, as well as all sound effects will be enabled. The sounds can be muted any time by clicking the active speaker
icon.
The first step in the game is to choose which region the player wants to test their knowledge on. Once chosen, an animation will bring the map closer to that region. The region's countries become selectable while all countries outside the region become blurred.
The player has to select the country that appears at the top. If the selection is correct, the country is coloured green and a green checkmark signals that the score has been registered. In case the selection is incorrect, the country becomes red and an animation flies the map to the correct country. This feedback allows the player to improve their knowledge.
Correct Choice | Incorrect Choice |
---|---|
After 10 countries have been chosen, the score is displayed. For the first time, this is all the feedback the user is given.
From the second round on, at the end of the round, a View your best scores here
button appears which can be clicked to display the user's best scores. From this time on, the best scores can be reached anytime throughout the game via the star icon.
The scores are stored in localStorage, so if the localStorage gets cleared, the highest scores would be lost.
Three types of error messages can be delivered to the user depending on the issue
- a
Not Found
page in case of an invalid URL was typed in, - a
No Support
page in case the user uses an old browser that does not support Mapbox GL GS, - an
Error page
an error page for other error scenarios including the failure to connect to the COUNT API as well as the Mapbox API.
The game supports desktop, laptop, tablet and mobile phone device interactions. The first click on the PLAY
button determines whether mouse/trackpad or touch interactions get enabled. This differentiation was needed to allow multi-touch zooming and panning, tapping, double-clicking, click-and-panning as well as scroll zooming functionalities on the map.
If the PLAY
button was clicked with a mouse or trackpad:
- a hovering effect is being applied,
- double clicking / double tapping is required to select a country,
- zooming in and out of the map as well as panning is available depending on the tool used:
- scrolling to zoom and grab-and-pan with a mouse,
- two-finger zoom and double-tap-pan with a trackpad.
If the PLAY
button was clicked on a touch device:
- a firm tap or a slightly longer than usual (50ms long) tap is required to select a country.
- zooming in and out as well as panning the map is available in the usual ways:
- zooming in and out with two or more fingers,
- panning and rotating the map with sustained and moving touch with one or more fingers.
-
There are many options to widen the game's functionality. Capital cities, flags and more regions - Australia, Oceania and Antarctica could be included as well as small islands and micro countries. Worldviews could be a dynamic feature depending on the location of the user. A new option with the US states could be part of the game too.
-
Automatic testing with Cypress, to which support is provided by Mapbox.
-
The font was chosen for having a simple design and clean contours to maximise legibility.
-
For font sizes,
rem
was used throughout the site to allow the text to scale according to the users' preferred default font size. -
The map can be zoomed in and out when the player has to find a country to cater for easier access.
-
Images have
alt
labels and svg tags are marked witharia
labels. -
Chrome Dev Tools' Lighthouse score is 100% for accessibility for both mobile and desktop devices.
-
Mapbox Studio allows to test map designs for 8 types of visual impairments. This is how the map looks across all tests:
The site was built with JavaScript using the ReactJS framework. Styling was achieved with React's built in CSS Modules.
-
Redux library vesrion ^8.0.5 - for state management
-
React Router DOM version ^6.10.0 - for routing
-
React Query version ^3.39.3 - for fetching data
-
use-sound npm package version ^4.0.1 - for playing audio in ReactJS
-
Mapbox GL JS API - used for every map-based functionality.
-
Mapbox Studio - to create map design.
-
Count API - this is my own API, used to keep track of the number of page loads.
-
EmailJS - to send updates about website usage.
-
Google Fonts - for texts.
-
Balsamiq - to create wireframes.
-
Figma - to create colour palette and image for favicons.
-
RealFaviconGenerator - to generate favicons.
-
Multi Device Website Mockup - to create site visuals for responsive design.
-
Gyazo - for adding
.gif
files to this README file. -
Git & Github - for version control, safe storage and deployment.
-
VS Code - for local development.
-
Google Dev Tools - for testing and troubleshooting.
The project was created with create-react-app. See the generic create-react-app documentation here.
The project is deployed on AWS. For the deployment process, I took the following (main) steps:
- I built the React App with the
npm run build
command. - Created a bucket for this project (map-it.szilvia-csernus) then uploaded the
build
folder into the newly created bucket. - Enabled this S3 bucket for Static Website Hosting, noted the URL endpoint which had been created.
- Set up a new CloudFront Distribution in the European and American regions, I set the origin domain to the S3 bucket URL endpoint. I noted the CloudFront distribution domain name.
- In AWS Route 53, where I already had a hosted zone (inc. a wildcard SSL certificate for *.szilvia-csernus.co.uk), I created an "A record" for the sub-domain
map-it
, i.e.map-it.szilvia-csernus.co.uk
and set the alias target to the CloudFront distribution domain name.
To re-deploy the project, the following steps need to be taken:
- Building the React app again
- Uploading the new build files to the S3 bucket.
- Invalidating the CloudFront cache to ensure the new files are served and AWS re-populates the caches.
Originally, this project was deployed on Firebase
. The running project is slightly slower then the AWS one and only available in the European reagion but still available here: https://map-it-aa424.web.app/
Re-deployment to Firebase:
npm run build
firebase hosting:disable
firebase deploy
-
Data for country centroids for displaying the names of the countries: https://github.com/gavinr/world-countries-centroids/blob/master/dist/countries.geojson - MIT Licence, Copyright (c) 2021 Gavin Rehkemper
-
Country info including region info: https://github.com/annexare/Countries/blob/master/data/countries.json - MIT Licence, Copyright (c) 2014 Annexare Studio
-
Exit icon: https://www.svgrepo.com/svg/170342/exit-hand-drawn-interface-symbol-variant
-
Check icon: https://www.svgrepo.com/svg/404945/check-mark
-
Cross icon: https://www.svgrepo.com/svg/470906/times
-
Question mark icon: https://www.svgrepo.com/svg/491697/question-circle
-
Star icon: https://www.svgrepo.com/svg/509256/star
-
Sound icon: https://www.svgrepo.com/svg/442013/sound
-
Mute icon: https://www.svgrepo.com/svg/441980/mute
-
Background music: Carefree Kevin MacLeod (incompetech.com) Licensed under Creative Commons: By Attribution 4.0 License http://creativecommons.org/licenses/by/4.0/ Music promoted on https://www.chosic.com/free-music/all/ https://www.chosic.com/download-audio/25863/
-
Alternative background music (currently not active): Weekend by LesFM | https://lesfm.net/acoustic-background-music/ Music promoted by https://www.chosic.com/free-music/all/ Creative Commons CC BY 3.0 https://creativecommons.org/licenses/by/3.0/ https://www.chosic.com/download-audio/29586/
-
Correct choice sound effect: Sound Effect by Liecio from Pixabay
-
'clink' sound: Sound Effect from Pixabay
-
Incorrect choice sound effect: Sound Effect from Pixabay
-
High score sound: Sound Effect by UNIVERSFIELD from Pixabay
-
Choose region sound: Sound Effect from Pixabay
-
Play Button / New Game sound: Sound Effect from Pixabay
-
Base code for rotating globe is adapted from one of Mapbox's example codes, which I also reference in the code.
-
Base code for hovering effect is adapted from one of Mapbox's example codes, which I also reference in the code.
-
For the intro animation I used ideas from: https://css-tricks.com/animating-with-clip-path/ - animating with clip-path https://www.youtube.com/watch?v=zadj2i5wUyc - animating with gradients by Colt Steele
-
Adding drop-shadow filter to svg icons: https://css-tricks.com/adding-shadows-to-svg-icons-with-css-and-svg-filters/
-
Geolocation coordinate finder: http://bboxfinder.com/
-
Clamp() calculator for responsive font sizes: https://grizhlie-clamp-calculator.netlify.app/
-
Use of useQuery() from the react-query library: https://tylerclark.dev/react-query/ https://blog.bitsrc.io/how-to-start-using-react-query-4869e3d5680d
I would like to thank the following contributors:
-
Chris Wong from Mapbox for giving guidance on the implementation of the Mapbox GL JS API through Mapbox's dedicated discord channel.
-
Tim Nelson and Manuel Perez Romero for giving useful feedback throughout the development and testing processes.
-
My family and friends for taking the time to test the game.
-
Code Institute's Slack Community for continuous support.
This project was created as a portfolio project. All parts of the project form the intellectual property of the developer.
Not for public use.
©2023 Szilvia Csernusne Berczes. All rights reserved.