Skip to main content

HTML5 APIs - Geolocation, Canvas, and Local Storage πŸŒπŸŽ¨πŸ’Ύ

Mentor's Note: HTML5 APIs are like superpowers for your web pages! They give your websites abilities that were once only possible with native apps - from finding user locations to creating stunning graphics and storing data locally! πŸš€βœ¨

πŸ“š Educational Content: This comprehensive guide covers essential HTML5 APIs that enable modern web applications with location services, graphics, and data persistence.

🎯 Learning Objectives​

By the end of this lesson, students will be able to:

  • Implement Geolocation API to get user location
  • Create graphics and animations with Canvas API
  • Store and retrieve data using Local Storage and Session Storage
  • Handle API errors and browser compatibility
  • Build interactive applications using HTML5 APIs

🌟 The Scenario: Smart Weather App πŸŒ€οΈβ€‹

Mental Model for beginners: Think of HTML5 APIs as special tools that extend your website's capabilities! Imagine you're building a smart weather application... 🌈

  • Location Detection: Geolocation API - Find user's current location
  • Weather Visualization: Canvas API - Draw weather graphs and animations
  • Settings Storage: Local Storage - Save user preferences
  • Session Data: Session Storage - Track current weather session
  • The Result: A fully functional weather app! βœ…

πŸ“– HTML5 APIs Overview​

Why HTML5 APIs Matter:​

  • Enhanced Functionality: Access device features
  • Better User Experience: More interactive applications
  • Offline Capabilities: Store data locally
  • Rich Graphics: Create visual content
  • Modern Web Standards: Industry-standard capabilities

πŸ—ΊοΈ Geolocation API​

What is Geolocation?​

The Geolocation API allows websites to request and receive the user's geographical position.

Key Concepts:​

  • Permission-based: User must grant access
  • Multiple methods: GPS, WiFi, IP-based location
  • Accuracy levels: Varies by method
  • Privacy considerations: User consent required

Basic Geolocation Usage:​

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Geolocation Example</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.location-info {
background: #f0f8ff;
padding: 20px;
border-radius: 8px;
margin: 20px 0;
}
.coordinates {
font-family: monospace;
background: #e8e8e8;
padding: 10px;
border-radius: 4px;
}
.error {
background: #ffe6e6;
color: #d00;
padding: 10px;
border-radius: 4px;
}
button {
background: #007bff;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
button:hover {
background: #0056b3;
}
</style>
</head>
<body>
<h1>πŸ—ΊοΈ Geolocation Demo</h1>

<button onclick="getLocation()">Get My Location</button>

<div id="result"></div>

<script>
function getLocation() {
const resultDiv = document.getElementById('result');

// Check if geolocation is supported
if (!navigator.geolocation) {
resultDiv.innerHTML = '<div class="error">❌ Geolocation is not supported by your browser</div>';
return;
}

resultDiv.innerHTML = '<div>πŸ”„ Getting your location...</div>';

// Get current position
navigator.geolocation.getCurrentPosition(
// Success callback
function(position) {
const coords = position.coords;
const timestamp = new Date(position.timestamp);

resultDiv.innerHTML = `
<div class="location-info">
<h2>πŸ“ Your Location Found!</h2>
<div class="coordinates">
<strong>Latitude:</strong> ${coords.latitude.toFixed(6)}<br>
<strong>Longitude:</strong> ${coords.longitude.toFixed(6)}<br>
<strong>Accuracy:</strong> ${coords.accuracy.toFixed(2)} meters<br>
<strong>Altitude:</strong> ${coords.altitude ? coords.altitude.toFixed(2) + ' meters' : 'Not available'}<br>
<strong>Altitude Accuracy:</strong> ${coords.altitudeAccuracy ? coords.altitudeAccuracy.toFixed(2) + ' meters' : 'Not available'}<br>
<strong>Heading:</strong> ${coords.heading ? coords.heading.toFixed(2) + 'Β°' : 'Not available'}<br>
<strong>Speed:</strong> ${coords.speed ? (coords.speed * 3.6).toFixed(2) + ' km/h' : 'Not available'}<br>
<strong>Timestamp:</strong> ${timestamp.toLocaleString()}
</div>
</div>
`;
},
// Error callback
function(error) {
let errorMessage = '';
switch(error.code) {
case error.PERMISSION_DENIED:
errorMessage = '❌ User denied the request for Geolocation';
break;
case error.POSITION_UNAVAILABLE:
errorMessage = '❌ Location information is unavailable';
break;
case error.TIMEOUT:
errorMessage = '❌ The request to get location timed out';
break;
case error.UNKNOWN_ERROR:
errorMessage = '❌ An unknown error occurred';
break;
}
resultDiv.innerHTML = `<div class="error">${errorMessage}</div>`;
},
// Options
{
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 0
}
);
}

// Watch position (continuous tracking)
let watchId = null;

function startTracking() {
if (navigator.geolocation) {
watchId = navigator.geolocation.watchPosition(
function(position) {
console.log('New position:', position.coords);
},
function(error) {
console.error('Tracking error:', error);
}
);
}
}

function stopTracking() {
if (watchId !== null) {
navigator.geolocation.clearWatch(watchId);
watchId = null;
}
}
</script>
</body>
</html>

Geolocation Options:​

  • enableHighAccuracy: More accurate but slower
  • timeout: Maximum time to wait
  • maximumAge: Cache duration for position

🎨 Canvas API​

What is Canvas?​

The Canvas API provides a way to draw graphics using JavaScript and HTML.

Key Concepts:​

  • 2D Context: Drawing surface
  • Coordinate System: (0,0) at top-left
  • Drawing Methods: Shapes, text, images
  • Animation: Frame-by-frame rendering

Canvas Drawing Example:​

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas Drawing Demo</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 1000px;
margin: 0 auto;
padding: 20px;
}
.canvas-container {
border: 2px solid #333;
margin: 20px 0;
display: inline-block;
}
canvas {
display: block;
background: white;
}
.controls {
margin: 20px 0;
}
button {
background: #007bff;
color: white;
border: none;
padding: 8px 16px;
margin: 5px;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background: #0056b3;
}
.color-picker {
margin: 0 10px;
}
</style>
</head>
<body>
<h1>🎨 Canvas Drawing Demo</h1>

<div class="controls">
<button onclick="drawRectangle()">Draw Rectangle</button>
<button onclick="drawCircle()">Draw Circle</button>
<button onclick="drawLine()">Draw Line</button>
<button onclick="drawText()">Draw Text</button>
<button onclick="drawGradient()">Draw Gradient</button>
<button onclick="drawImage()">Draw Image</button>
<button onclick="clearCanvas()">Clear Canvas</button>
<button onclick="startAnimation()">Start Animation</button>
<button onclick="stopAnimation()">Stop Animation</button>
</div>

<div class="canvas-container">
<canvas id="myCanvas" width="800" height="400"></canvas>
</div>

<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
let animationId = null;
let ballX = 50, ballY = 50, ballVX = 5, ballVY = 3;

// Draw Rectangle
function drawRectangle() {
ctx.fillStyle = '#007bff';
ctx.fillRect(50, 50, 200, 100);

ctx.strokeStyle = '#0056b3';
ctx.lineWidth = 3;
ctx.strokeRect(300, 50, 200, 100);
}

// Draw Circle
function drawCircle() {
ctx.beginPath();
ctx.arc(150, 250, 50, 0, 2 * Math.PI);
ctx.fillStyle = '#28a745';
ctx.fill();

ctx.beginPath();
ctx.arc(400, 250, 50, 0, 2 * Math.PI);
ctx.strokeStyle = '#dc3545';
ctx.lineWidth = 4;
ctx.stroke();
}

// Draw Line
function drawLine() {
ctx.beginPath();
ctx.moveTo(50, 350);
ctx.lineTo(750, 350);
ctx.strokeStyle = '#6c757d';
ctx.lineWidth = 2;
ctx.stroke();

// Draw arrow
ctx.beginPath();
ctx.moveTo(750, 350);
ctx.lineTo(740, 345);
ctx.lineTo(740, 355);
ctx.closePath();
ctx.fillStyle = '#6c757d';
ctx.fill();
}

// Draw Text
function drawText() {
ctx.font = 'bold 36px Arial';
ctx.fillStyle = '#333';
ctx.fillText('Canvas Text', 50, 100);

ctx.font = '24px Georgia';
ctx.strokeStyle = '#007bff';
ctx.lineWidth = 2;
ctx.strokeText('Outlined Text', 50, 150);

// Text with gradient
const gradient = ctx.createLinearGradient(0, 0, 400, 0);
gradient.addColorStop(0, '#ff0000');
gradient.addColorStop(0.5, '#00ff00');
gradient.addColorStop(1, '#0000ff');

ctx.font = 'bold 48px Arial';
ctx.fillStyle = gradient;
ctx.fillText('Gradient Text!', 50, 250);
}

// Draw Gradient
function drawGradient() {
// Linear gradient
const linearGradient = ctx.createLinearGradient(500, 50, 700, 150);
linearGradient.addColorStop(0, '#ff0000');
linearGradient.addColorStop(0.5, '#00ff00');
linearGradient.addColorStop(1, '#0000ff');

ctx.fillStyle = linearGradient;
ctx.fillRect(500, 50, 200, 100);

// Radial gradient
const radialGradient = ctx.createRadialGradient(600, 250, 20, 600, 250, 80);
radialGradient.addColorStop(0, '#ffff00');
radialGradient.addColorStop(0.5, '#ff8800');
radialGradient.addColorStop(1, '#ff0000');

ctx.fillStyle = radialGradient;
ctx.beginPath();
ctx.arc(600, 250, 80, 0, 2 * Math.PI);
ctx.fill();
}

// Draw Image
function drawImage() {
const img = new Image();
img.onload = function() {
ctx.drawImage(img, 50, 180, 150, 100);

// Draw part of image
ctx.drawImage(img, 100, 50, 100, 100, 250, 180, 100, 100);
};
img.src = 'https://picsum.photos/seed/canvas-demo/300/200.jpg';
}

// Clear Canvas
function clearCanvas() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}

// Animation
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);

// Draw bouncing ball
ctx.beginPath();
ctx.arc(ballX, ballY, 20, 0, 2 * Math.PI);
ctx.fillStyle = '#007bff';
ctx.fill();

// Update position
ballX += ballVX;
ballY += ballVY;

// Bounce off walls
if (ballX + 20 > canvas.width || ballX - 20 < 0) {
ballVX = -ballVX;
}
if (ballY + 20 > canvas.height || ballY - 20 < 0) {
ballVY = -ballVY;
}

animationId = requestAnimationFrame(animate);
}

function startAnimation() {
if (!animationId) {
animate();
}
}

function stopAnimation() {
if (animationId) {
cancelAnimationFrame(animationId);
animationId = null;
}
}

// Interactive drawing
let isDrawing = false;
let lastX = 0;
let lastY = 0;

canvas.addEventListener('mousedown', function(e) {
isDrawing = true;
const rect = canvas.getBoundingClientRect();
lastX = e.clientX - rect.left;
lastY = e.clientY - rect.top;
});

canvas.addEventListener('mousemove', function(e) {
if (!isDrawing) return;

const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;

ctx.beginPath();
ctx.moveTo(lastX, lastY);
ctx.lineTo(x, y);
ctx.strokeStyle = '#333';
ctx.lineWidth = 2;
ctx.stroke();

lastX = x;
lastY = y;
});

canvas.addEventListener('mouseup', function() {
isDrawing = false;
});

canvas.addEventListener('mouseout', function() {
isDrawing = false;
});
</script>
</body>
</html>

πŸ’Ύ Web Storage API​

What is Web Storage?​

Web Storage provides mechanisms for storing data locally in the browser.

Two Types:​

  • Local Storage: Persistent data (no expiration)
  • Session Storage: Data for current session only

Storage Example:​

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Web Storage Demo</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.storage-demo {
background: #f8f9fa;
padding: 20px;
border-radius: 8px;
margin: 20px 0;
}
.form-group {
margin: 15px 0;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
input, textarea {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
box-sizing: border-box;
}
button {
background: #007bff;
color: white;
border: none;
padding: 10px 20px;
margin: 5px;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background: #0056b3;
}
.storage-info {
background: #e8f5e8;
padding: 15px;
border-radius: 4px;
margin: 10px 0;
}
.error {
background: #ffe6e6;
color: #d00;
padding: 10px;
border-radius: 4px;
}
.data-item {
background: white;
padding: 10px;
margin: 5px 0;
border-radius: 4px;
border: 1px solid #ddd;
}
</style>
</head>
<body>
<h1>πŸ’Ύ Web Storage Demo</h1>

<div class="storage-demo">
<h2>πŸ“ User Preferences Form</h2>

<div class="form-group">
<label for="username">Username:</label>
<input type="text" id="username" placeholder="Enter your username">
</div>

<div class="form-group">
<label for="email">Email:</label>
<input type="email" id="email" placeholder="Enter your email">
</div>

<div class="form-group">
<label for="theme">Theme:</label>
<select id="theme">
<option value="light">Light</option>
<option value="dark">Dark</option>
<option value="blue">Blue</option>
</select>
</div>

<div class="form-group">
<label for="notes">Notes:</label>
<textarea id="notes" rows="4" placeholder="Enter your notes"></textarea>
</div>

<button onclick="saveToLocalStorage()">πŸ’Ύ Save to Local Storage</button>
<button onclick="saveToSessionStorage()">πŸ“‹ Save to Session Storage</button>
<button onclick="loadFromStorage()">πŸ“‚ Load from Storage</button>
<button onclick="clearStorage()">πŸ—‘οΈ Clear Storage</button>
<button onclick="showStorageInfo()">ℹ️ Show Storage Info</button>
</div>

<div id="result"></div>

<script>
// Save to Local Storage
function saveToLocalStorage() {
try {
const userData = {
username: document.getElementById('username').value,
email: document.getElementById('email').value,
theme: document.getElementById('theme').value,
notes: document.getElementById('notes').value,
timestamp: new Date().toISOString()
};

localStorage.setItem('userPreferences', JSON.stringify(userData));

showResult('βœ… Data saved to Local Storage!', 'success');
} catch (error) {
showResult('❌ Error saving to Local Storage: ' + error.message, 'error');
}
}

// Save to Session Storage
function saveToSessionStorage() {
try {
const sessionData = {
username: document.getElementById('username').value,
email: document.getElementById('email').value,
theme: document.getElementById('theme').value,
notes: document.getElementById('notes').value,
timestamp: new Date().toISOString()
};

sessionStorage.setItem('sessionData', JSON.stringify(sessionData));

showResult('βœ… Data saved to Session Storage!', 'success');
} catch (error) {
showResult('❌ Error saving to Session Storage: ' + error.message, 'error');
}
}

// Load from Storage
function loadFromStorage() {
try {
// Try Local Storage first
let userData = localStorage.getItem('userPreferences');

if (userData) {
const data = JSON.parse(userData);
document.getElementById('username').value = data.username || '';
document.getElementById('email').value = data.email || '';
document.getElementById('theme').value = data.theme || 'light';
document.getElementById('notes').value = data.notes || '';

showResult('βœ… Data loaded from Local Storage!', 'success');
} else {
// Try Session Storage
let sessionData = sessionStorage.getItem('sessionData');

if (sessionData) {
const data = JSON.parse(sessionData);
document.getElementById('username').value = data.username || '';
document.getElementById('email').value = data.email || '';
document.getElementById('theme').value = data.theme || 'light';
document.getElementById('notes').value = data.notes || '';

showResult('βœ… Data loaded from Session Storage!', 'success');
} else {
showResult('ℹ️ No data found in storage', 'info');
}
}
} catch (error) {
showResult('❌ Error loading from storage: ' + error.message, 'error');
}
}

// Clear Storage
function clearStorage() {
localStorage.clear();
sessionStorage.clear();

// Clear form
document.getElementById('username').value = '';
document.getElementById('email').value = '';
document.getElementById('theme').value = 'light';
document.getElementById('notes').value = '';

showResult('πŸ—‘οΈ Storage cleared!', 'success');
}

// Show Storage Info
function showStorageInfo() {
const info = [];

// Local Storage info
info.push('<h3>πŸ“¦ Local Storage</h3>');
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
const value = localStorage.getItem(key);
info.push(`<div class="data-item"><strong>${key}:</strong> ${value}</div>`);
}

// Session Storage info
info.push('<h3>πŸ“‹ Session Storage</h3>');
for (let i = 0; i < sessionStorage.length; i++) {
const key = sessionStorage.key(i);
const value = sessionStorage.getItem(key);
info.push(`<div class="data-item"><strong>${key}:</strong> ${value}</div>`);
}

// Storage quota
if ('storage' in navigator && 'estimate' in navigator.storage) {
navigator.storage.estimate().then(function(estimate) {
info.push(`<h3>πŸ’Ύ Storage Quota</h3>`);
info.push(`<div class="storage-info">`);
info.push(`<strong>Usage:</strong> ${(estimate.usage / 1024 / 1024).toFixed(2)} MB<br>`);
info.push(`<strong>Quota:</strong> ${(estimate.quota / 1024 / 1024).toFixed(2)} MB<br>`);
info.push(`<strong>Available:</strong> ${((estimate.quota - estimate.usage) / 1024 / 1024).toFixed(2)} MB`);
info.push(`</div>`);

document.getElementById('result').innerHTML = info.join('');
});
} else {
document.getElementById('result').innerHTML = info.join('');
}
}

// Show result message
function showResult(message, type) {
const resultDiv = document.getElementById('result');
const className = type === 'error' ? 'error' : 'storage-info';
resultDiv.innerHTML = `<div class="${className}">${message}</div>`;
}

// Auto-save functionality
let autoSaveTimer;

function setupAutoSave() {
const inputs = document.querySelectorAll('input, textarea, select');

inputs.forEach(input => {
input.addEventListener('input', function() {
clearTimeout(autoSaveTimer);
autoSaveTimer = setTimeout(function() {
saveToLocalStorage();
showResult('πŸ’Ύ Auto-saved!', 'success');
}, 2000);
});
});
}

// Load data on page load
window.addEventListener('load', function() {
loadFromStorage();
setupAutoSave();
});

// Storage event listener (for cross-tab communication)
window.addEventListener('storage', function(e) {
console.log('Storage changed:', e);
if (e.key === 'userPreferences') {
showResult('πŸ”„ Data updated in another tab!', 'info');
}
});
</script>
</body>
</html>

πŸ”„ Storage Event Handling​

Cross-Tab Communication:​

// Listen for storage changes in other tabs
window.addEventListener('storage', function(event) {
console.log('Storage changed:', event);
console.log('Key:', event.key);
console.log('Old value:', event.oldValue);
console.log('New value:', event.newValue);
console.log('URL:', event.url);

if (event.key === 'userPreferences') {
// Reload preferences
loadUserPreferences();
}
});

πŸ“Š Storage Limits and Best Practices​

Storage Limits:​

  • Local Storage: ~5-10 MB per domain
  • Session Storage: ~5-10 MB per domain
  • Browser dependent: Varies by browser

Best Practices:​

  • Check availability: Test for support
  • Handle errors: Use try-catch blocks
  • Data validation: Validate stored data
  • Security: Don't store sensitive data
  • Performance: Minimize storage operations

πŸ§ͺ Quick Quiz​

Test Your Knowledge!​

Question 1: Which method gets the user's current position?

  • A) navigator.getPosition()
  • B) navigator.geolocation.getCurrentPosition()
  • C) navigator.location.get()
  • D) geolocation.getCurrentPosition()

Question 2: What is the default origin point for Canvas coordinates?

  • A) Center of canvas
  • B) Bottom-left corner
  • C) Top-left corner
  • D) Top-right corner

Question 3: Which storage type persists after browser closes?

  • A) Session Storage
  • B) Local Storage
  • C) Memory Storage
  • D) Cache Storage

Question 4: What does ctx.arc() create?

  • A) A rectangle
  • B) A circle or arc
  • C) A line
  • D) A triangle

Question 5: How do you clear a canvas?

  • A) canvas.clear()
  • B) ctx.clearRect()
  • C) ctx.empty()
  • D) canvas.reset()

πŸ’» Practice Exercises​

Exercise 1: Location-Based Weather App​

Create a weather app that:

  1. Gets user's location
  2. Shows coordinates
  3. Displays weather based on location
  4. Saves user preferences

Exercise 2: Canvas Drawing Game​

Build a drawing game with:

  1. Different drawing tools
  2. Color selection
  3. Clear and save functionality
  4. Shape drawing tools

Exercise 3: Personal Notes App​

Create a notes application:

  1. Save notes to local storage
  2. Organize notes by categories
  3. Search functionality
  4. Export/import features

πŸš€ Common Mistakes & Solutions​

Mistake 1: Not checking API support​

// ❌ Wrong
navigator.geolocation.getCurrentPosition(success, error);

// βœ… Correct
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(success, error);
} else {
console.log('Geolocation not supported');
}

Mistake 2: Not handling storage errors​

// ❌ Wrong
localStorage.setItem('data', JSON.stringify(largeObject));

// βœ… Correct
try {
localStorage.setItem('data', JSON.stringify(largeObject));
} catch (error) {
console.error('Storage quota exceeded');
}

Mistake 3: Canvas context issues​

// ❌ Wrong
const canvas = document.getElementById('canvas');
canvas.fillRect(10, 10, 50, 50);

// βœ… Correct
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.fillRect(10, 10, 50, 50);

🌟 Real-World Examples​

Example 1: Location-Based Services​

  • Food delivery: Find nearest restaurants
  • Ride sharing: Track driver location
  • Weather apps: Local weather information
  • Social media: Location-based posts

Example 2: Canvas Applications​

  • Photo editors: Image manipulation
  • Games: 2D game graphics
  • Charts: Data visualization
  • Drawing apps: Creative tools

Example 3: Storage Solutions​

  • Shopping carts: Save cart items
  • User preferences: Theme settings
  • Offline apps: Cache data
  • Form data: Auto-save functionality

πŸ“‹ Implementation Checklist​

Geolocation Implementation:​

  • Check browser support
  • Handle user permissions
  • Implement error handling
  • Consider privacy implications
  • Test on different devices

Canvas Implementation:​

  • Get 2D context
  • Handle responsive sizing
  • Optimize drawing operations
  • Implement animations properly
  • Consider accessibility

Storage Implementation:​

  • Choose appropriate storage type
  • Handle storage limits
  • Implement error handling
  • Validate stored data
  • Consider security implications

🎯 Summary​

HTML5 APIs provide powerful capabilities for modern web applications:

Key Takeaways:​

  • Geolocation: Access user location with permission
  • Canvas: Create graphics and animations
  • Storage: Store data locally in browser
  • Error Handling: Always handle API errors
  • Browser Support: Check for API availability

Next Steps:​

  • Practice with real-world projects
  • Explore advanced API features
  • Learn about other HTML5 APIs
  • Build complete applications

Remember:​

  • User Privacy: Always respect user permissions
  • Performance: Optimize API usage
  • Compatibility: Test across browsers
  • Security: Protect user data

πŸ”— Additional Resources​

Documentation:​

Tutorials:​

Tools:​


πŸ“Š HTML5 API Ecosystem Overview​


πŸ’Ύ Storage Decision Flowchart​


"HTML5 APIs transform the web from static pages to interactive applications that rival native software!" πŸš€βœ¨

πŸ“ Visit Us

🏫 VD Computer Tuition Surat

VD Computer Tuition
πŸ“ Address
2/66 Faram Street, Rustompura
Surat – 395002, Gujarat, India
πŸ“ž Phone / WhatsApp
+91 84604 41384
🌐 Website

Computer Classes & Tuition β€” Areas We Serve in Surat

Adajanβ€’Althanβ€’Amroliβ€’Athwaβ€’Athwalinesβ€’Bhagalβ€’Bhatarβ€’Bhestanβ€’Canal Roadβ€’Chowkβ€’Citylightβ€’Dumasβ€’Gaurav Pathβ€’Ghod Dod Roadβ€’Haziraβ€’Jahangirpuraβ€’Kamrejβ€’Kapodraβ€’Katargamβ€’Limbayatβ€’Magdallaβ€’Majura Gateβ€’Mota Varachhaβ€’Nanpuraβ€’New Citylightβ€’Olpadβ€’Palβ€’Pandesaraβ€’Parle Pointβ€’Piplodβ€’Punaβ€’Randerβ€’Ring Roadβ€’Rustampuraβ€’Sachinβ€’Salabatpuraβ€’Sarthanaβ€’Sosyo Circleβ€’Udhnaβ€’Varachhaβ€’Ved Roadβ€’Vesuβ€’VIP Road
πŸ“ž Call SirπŸ’¬ WhatsApp Sir