Objective:
You and a partner will create a location-based app that allows users to find routes to a selected destination using a free mapping API (such as OpenStreetMap), the Geolocation API to get the user's current location, and a Route Finding API (such as OpenRouteService or GraphHopper) to calculate the best route. The app should be able to display a map, show the user's location, and calculate the optimal route to the chosen destination.
Steps:
Set up the HTML structure:
- Create an
index.html
file. - Add a map container to display the map (using a
div
orcanvas
element). - Add an input field to allow the user to enter a destination address or select a point on the map.
- Include a button to calculate the route.
- Display the route on the map with clear directions.
- Create an
Install/Include Required Libraries:
- Use OpenStreetMap for map rendering (e.g., through a library like Leaflet.js).
To get started with Leaflet, go here Leaflet Tutorials
- Add routing functionality with a Route Finding API (Try Leaflet Routing Machine, or if not working, OpenRouteService or GraphHopper)
- Get the user's current position using a Geolocation API.
- Use a Geocoding API to convert an address into geographic coordinates. Try Leaflet Geosearch, or if not working the Geolocation feature of openrouteservice or grasshopper.
Sample Code for LeafletYou may want to include these libraries via CDN in your
index.html
(Note: the Leaflet website may have more updated links than these):<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css"/> <script src="https://unpkg.com/leaflet/dist/leaflet.js">script> <script src="https://unpkg.com/leaflet-routing-machine/dist/leaflet-routing-machine.js">script> <script src="https://unpkg.com/leaflet-geosearch/dist/geosearch.js">script>
- Use OpenStreetMap for map rendering (e.g., through a library like Leaflet.js).
Integrate the Mapping Service:
- Use Leaflet.js to render the map on your web page.
- Set up the map to display OpenStreetMap tiles.
- Use your routing API to create interactive routing functionality.
Example code to set up the map in Leaflet Routing Machine:
const map = L.map('map').setView([51.505, -0.09], 13); // Example coordinates L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors' }).addTo(map);
Get the User’s Location:
- Use the Geolocation API to find the user's current location.
- Use the
navigator.geolocation.getCurrentPosition
function to retrieve the coordinates and display them on the map. - Place a marker on the map showing the user's current location.
Example code to get the user's location and show it on a Leaflet map:
navigator.geolocation.getCurrentPosition(function(position) { const userLat = position.coords.latitude; const userLon = position.coords.longitude; L.marker([userLat, userLon]).addTo(map).bindPopup("You are here").openPopup(); map.setView([userLat, userLon], 13); });
Enable Destination Selection:
- Allow the user to either input a destination address or click on the map to select a destination.
- If using an input field, use a Geocoding API to convert the address into geographic coordinates.
Integrate the Route Finding API:
- Use a Route Finding API (e.g., OpenRouteService or GraphHopper) to calculate the route between the user's current location and the destination.
- Ensure the route is displayed on the map using Leaflet Routing Machine.
Example code to fetch the route using OpenRouteService:
fetch(`https://api.openrouteservice.org/v2/directions/driving-car?api_key=YOUR_API_KEY&start=${userLon},${userLat}&end=${destLon},${destLat}`) .then(response => response.json()) .then(data => { const route = data.features[0].geometry.coordinates; L.polyline(route.map(coord => [coord[1], coord[0]]), {color: 'blue'}).addTo(map); }) .catch(error => console.error('Error fetching route:', error));
Route Display and Interaction:
- Once the route is fetched from the Route Finding API, display it on the map using Leaflet and Leaflet Routing Machine.
- Allow the user to see the step-by-step directions or a preview of the total route.
Advanced Features (Choose One):
- Add different travel modes (e.g., walking, cycling, driving) and allow the user to choose the mode of transportation.
- Interactive Map: Allow the user to drag the destination marker and update the route accordingly.
- Display estimated time and distance for the route.
Responsive Design:
- Make sure that the map and controls are responsive and look good on different screen sizes.
PWA/Lighthouse/Valid Code:
- Turn your app into a PWA
- Validate HTML and CSS
- Get 4/4 Greens on Lighthouse
- Ensure no JS errors
Marking Criteria (/35):
Map Display (5 points):
- Correctly integrates OpenStreetMap using Leaflet.js.
- Displays the user's location as a marker on the map.
Geolocation Integration (5 points):
- Uses the Geolocation API to get the user's current location and display it on the map.
Route Finding Functionality (5 points):
- Correctly integrates a Route Finding API (e.g., OpenRouteService, GraphHopper) to calculate routes.
- Displays the route on the map with Leaflet Routing Machine.
User Interaction (5 points):
- Allows the user to input a destination or select one by clicking on the map.
- Provides clear and easy-to-read directions or a route preview.
Design and Responsiveness (5 points):
- The app is visually appealing and works well on both desktop and mobile devices.
- The interface is easy to use and intuitive.
Advanced Feature (5 points):
- 1 advanced feature added successfully
PWA/Lighthouse/Valid Code (5 points):
- meets all criteria described above
Additional Notes:
- API Keys: Some services like OpenRouteService require an API key. You will need to sign up for free API access and use the key in their code.
Objective:
In this assignment, you will build a real-time, multi-user Tic Tac Toe game using Back4App, which is based on the Parse Platform. You will leverage Back4App's backend services (such as the Parse Database) to store and manage the game state, allowing two players to join a game session and interact with each other in real-time.
Steps to Complete the Assignment:
Step 1: Set Up Back4App
Create a Back4App Project:
- Go to Back4App,create a new account if you don't have one, and create a new project.
- Get your Application ID and JavaScript Key from the Back4App dashboard. You'll use these to connect your app to Back4App.
Set Up the Database:
- In the Back4App dashboard, create a Game class to store each game’s state (board, players, and winner). Create a "custom" class and put it in public mode.
- Add the following columns (fields) to the Game class:
- board (Array): Tracks the game board with values such as 'X', 'O', or an empty string.
- currentPlayer (String): Tracks which player’s turn it is ('X' or 'O').
- players (Array): Tracks the players (two players maximum).
- winner (String): Stores the winner ('X', 'O', or 'Draw').
Step 2: Add the Parse SDK to Your Web App
Include the Back4App SDK:
You must integrate the Parse SDK into your application to interact with Back4App's data storage and services. Add the following script tag to your HTML file to include the Parse JavaScript SDK:<script src="https://npmcdn.com/parse/dist/parse.min.js"></script>
Initialize Back4App: Add the following code in your JavaScript file to initialize the connection to Back4App:
Parse.initialize("YOUR_APP_ID", "YOUR_JAVASCRIPT_KEY"); Parse.serverURL = 'https://parseapi.back4app.com/';
Step 3: Create the Game UI
HTML Structure:
Create an HTML file (index.html
) for the Tic Tac Toe grid:<div id="game"> <h1>Tic Tac Toe</h1> <div id="board"> <div class="cell" data-index="0"></div> <div class="cell" data-index="1"></div> <div class="cell" data-index="2"></div> <div class="cell" data-index="3"></div> <div class="cell" data-index="4"></div> <div class="cell" data-index="5"></div> <div class="cell" data-index="6"></div> <div class="cell" data-index="7"></div> <div class="cell" data-index="8"></div> </div> <button id="reset-btn">Reset Game</button> </div>
CSS Styling:
Add CSS to style the Tic Tac Toe board:#game { text-align: center; } #board { display: grid; grid-template-columns: repeat(3, 100px); grid-template-rows: repeat(3, 100px); gap: 5px; } .cell { width: 100px; height: 100px; border: 1px solid #000; display: flex; justify-content: center; align-items: center; font-size: 2rem; cursor: pointer; }
Step 4: Add JavaScript for Game Logic
Create a New Game:
To create a new game, you'll save the game state in the Game class on Back4App.let currentPlayer = 'X'; let gameId = ''; // Unique game ID let players = 0; // Track the number of players const Game = Parse.Object.extend("Game"); // Create a new game session async function createGame() { try { const game = new Game(); game.set('board', [ '', '', '', '', '', '', '', '', '' ] ); game.set('currentPlayer', currentPlayer); game.set('players', [currentPlayer] ); game.set('winner', null); const gameObject = await game.save(); gameId = gameObject.id; players = 1; // First player has joined } catch (error) { console.error("Error creating game:", error); } }
Join an Existing Game:
Players can join an existing game by searching for an active game session.// Join an existing game async function joinGame(gameKey) { try { const gameQuery = new Parse.Query(Game); const game = await gameQuery.get(gameKey); if (!game) { alert('Game does not exist!'); return; } players = 2; currentPlayer = game.get('currentPlayer') === 'X' ? 'O' : 'X'; } catch (error) { console.error("Error joining game:", error); } }
Update the Board:
When a player makes a move, update the board in Back4App and switch the current player.// Update the game board async function updateBoard(index) { try { const gameQuery = new Parse.Query(Game); const game = await gameQuery.get(gameId); const board = game.get('board'); if (board[index] !== '' || game.get('winner')) { return; } const newBoard = [...board]; newBoard[index] = currentPlayer; game.set('board', newBoard); game.set('currentPlayer', currentPlayer === 'X' ? 'O' : 'X'); await game.save(); checkWinner(newBoard); } catch (error) { console.error("Error updating board:", error); } } // updateBoard // Check for a winner async function checkWinner(board) { const winPatterns = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], // Rows [0, 3, 6], [1, 4, 7], [2, 5, 8], // Columns [0, 4, 8], [2, 4, 6] // Diagonals ]; for (var i = 0; i < winPatterns.length; i++) { var a = winPatterns[i][0]; var b = winPatterns[i][1]; var c = winPatterns[i][2]; if (board[a] && board[a] === board[b] && board[a] === board[c]) { try { var gameQuery = new Parse.Query(Game); var game = await gameQuery.get(gameId); game.set('winner', currentPlayer); await game.save(); alert(currentPlayer + " wins!"); } catch (error) { console.error("Error saving winner:", error); } return; } } // Check for draw if (board.every(function (cell) { return cell !== ''; })) { try { var gameQuery = new Parse.Query(Game); var game = await gameQuery.get(gameId); game.set('winner', 'Draw'); await game.save(); alert("It's a draw!"); } catch (error) { console.error("Error saving draw result:", error); } } } // checkWinner // Render the game board async function renderBoard() { try { const gameQuery = new Parse.Query(Game); const game = await gameQuery.get(gameId); const board = game.get('board'); const cells = document.querySelectorAll('.cell'); board.forEach(function (cell, index) { cells[index].innerHTML = cell; }); } catch (error) { console.error("Error rendering board:", error); } } // renderBoard // start when the page loads window.onload = function () { initializeGame(); }; // Initialize the game function initializeGame() { document.querySelectorAll('.cell').forEach(function (cell) { cell.addEventListener('click', function (e) { var index = e.target.getAttribute('data-index'); updateBoard(index); }); }); document.getElementById('reset-btn').addEventListener('click', function () { resetGame(); }); createGame(); } // initializeGame
Step 5: Enable Live Queries for Real-Time Updates
To Enable Live Queries in Back4App- Go to your Back4App Dashboard → App Settings → Server Settings
- Under Live Queries, enable it for the Game class.
- Make sure WebSockets are enabled in your app.
Step 5: Deploy Your Game
- Deploy to Hosting:
- Back4App offers hosting capabilities. Alternatively, you can use platforms like GitHub Pages, Netlify, or Firebase Hosting for simple front-end deployment.
- Use the respective deployment method to get your game live on the web.
Evaluation Criteria:
- Real-Time Functionality: The game state updates in real-time for both players.
- Game Logic: Correct implementation of the game rules, including determining the winner or draw.
- Back4App Integration: Proper use of Back4App to store and retrieve game data.
- UI/UX: A user-friendly and responsive game interface.
- Code Structure: Well-organized and readable JavaScript code.
Bonus:
- Add player names to the game.
- Implement a chat feature so players can communicate.
- Add sound effects and animations for when a player wins or the game ends in a draw.
Objective:
Build a weather dashboard application that fetches data from multiple APIs to display current weather conditions, a 7-day forecast, and weather maps. Students will integrate at least one weather API (suggested: Open Meteo) and provide interactive features like a search bar to allow users to find weather information for different locations.
Steps:
Set up the HTML structure:
- Create an
index.html
file. - Add a search bar at the top of the page where users can input a city or location name.
- Suggest locations as the user types. Use a location API (suggest: locationiq.com)
- Display current weather information (temperature, humidity, wind speed, etc.) for the searched location.
- Below the current weather, display a 7-day forecast (including daily high/low temperatures, weather conditions, and icons for each day).
- Include a section to display a weather map (using a weather API map or Google Maps).
- Create an
Style the application (CSS):
- Ensure that the layout is responsive, meaning it works well on both desktop and mobile devices.
- Use modern design principles (e.g., clean typography, card layouts, color schemes related to weather).
- Make sure there’s a distinct visual separation between the current weather and forecast sections.
Basic functionality with JavaScript:
Write a function to fetch weather data from the chosen weather API:
- Fetch current weather and a 7-day forecast for the city entered in the search bar.
- Display the weather data in the correct format (e.g., temperature in Celsius or Fahrenheit, weather conditions, etc.).
- Use icons provided by the API (such as clear skies, rain, etc.) to show the weather condition.
Write a function to update the UI with weather information:
- After the user enters a city name and submits the search, update the current weather and forecast sections dynamically with the retrieved data.
Implement additional features:
- Geolocation support: Allow the user to click a button to get the weather for their current location (use the browser's geolocation API).
- Unit toggle: Let users toggle between Celsius and Fahrenheit for temperature units.
- Hourly Forecast: Add an hourly forecast section if your chosen API supports it.
Display a weather map:
- Integrate a weather map (using APIs like OpenWeatherMap or another service like Google Maps for location visualization).
- Add a simple interactive map showing weather patterns, such as precipitation or temperature overlays, for the current location or searched city.
Testing:
- Test the application by searching for different cities and checking if the weather data updates correctly.
- Ensure that geolocation, unit toggling, and map features work as expected.
Evaluation Criteria:
Weather Information Display (5 points):
- Current weather and 7-day forecast are displayed correctly with relevant details (temperature, conditions, wind speed, etc.).
- Icons are used to represent different weather conditions.
Search Functionality (5 points):
- Users can enter a city or location, and the app updates with relevant weather information.
- Proper handling of errors when searching for invalid locations (e.g., “City not found”).
UI/UX Design (5 points):
- The design is responsive and user-friendly, with modern styling.
- Data is presented in a clear, accessible format, and there are no visual clutter issues.
Weather Map (5 points):
- A map is displayed and shows relevant weather information for the searched location.
API Integration (5 points):
- The app correctly interfaces with the weather API(s), including handling API requests and parsing JSON data.
Additional Features (up to 5 points):
- Geolocation Support: Users can see the weather for their current location.
- Unit Toggle: Allows users to switch between Celsius and Fahrenheit.
- Hourly Forecast: Displays an hourly forecast.
Additional Notes:
- API Key: Services like Open Mateo, and OpenWeatherMap, require you to register for an API key to make requests.
Design and build an original app that implements the skills you have learned in this course.
Basic technical criteria for assignment:
- requires JavaScript coding
- interface with an API (Maps, or any other API) OR store data in a cloud database (Firebase, or another cloud storage system)
- has a responsive design that is easy to use
- meets basic modern design principles
- be deployed to the web (Firebase Deploy, Heroku, maybe Glitch?)
- Installable PWA
- Get green on all Lighthouse criteria
- Works offline by caching all key resources, and all recent fetches that are made
Advanced technical criteria for assignment:
- Innovative use of an API (Maps, or any other API)
- Amazing design and user friendliness
- Innovative use of storing data in a cloud database (Firebase, or another cloud storage system)
- Include some form of user interaction the prevents errors from happening, or error checks and cleans data.
Bonus marks available
- +2%: Self defined, Ms. Wear approved.
Some Interesting API's
Marking Criteria: Marking Criteria Web Dev 12 Final Project