Plan Your Trip & Optimize Your Memories

All-in-one tool to plan your travel budget and compress your travel photos for easy sharing
Bhoppers.com – Travel Tools

Travel Budget Planner

Plan your trip expenses and stay within your budget

Daily Expenses

Budget Summary

Accommodation Total: $0
Food Total: $0
Transportation Total: $0
Activities Total: $0
Miscellaneous Total: $0
One-Time Expenses: $0
Total Estimated Cost: $0

Currency Converter

Get real-time exchange rates for your selected currency

Getting latest exchange rates…
100 USD = 85.00 EUR
Exchange rates update in real-time
Using reliable exchange rate API

Travel Itinerary Planner

Plan your day-by-day activities and make the most of your trip

Day 1

09:00 AM
01:00 PM

Day 2

10:00 AM

Image Compression Tool

Optimize your travel images for web and social media

Drag & Drop Your Image Here

or click to browse your files

Compression Options

Web Optimization

Balanced quality and compression for websites

Social Media

Higher compression for faster sharing

Print Quality

Minimal compression for high-quality prints

Custom

Adjust compression settings manually

0 KB
Original Size
0 KB
Compressed Size
0%
Size Reduction

Original Image

Compressed Image

`], { type: 'text/html' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `${destination.replace(/\s+/g, '_')}_Itinerary.html`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); }); document.getElementById('print-itinerary-btn').addEventListener('click', function() { window.print(); }); // Add event listeners to existing buttons document.querySelectorAll('.add-activity-btn').forEach(btn => { btn.addEventListener('click', addActivity); });// Image compression functionality let originalImage = null; let compressedImageBlob = null; let selectedCompressionOption = 'web'; document.getElementById('drop-zone').addEventListener('click', () => { document.getElementById('image-input').click(); }); document.getElementById('image-input').addEventListener('change', handleImageSelect); // Compression option selection document.querySelectorAll('.compression-option').forEach(option => { option.addEventListener('click', function() { document.querySelectorAll('.compression-option').forEach(el => { el.classList.remove('selected'); }); this.classList.add('selected'); selectedCompressionOption = this.getAttribute('data-option'); // Show/hide custom settings if (selectedCompressionOption === 'custom') { document.getElementById('custom-settings').style.display = 'block'; } else { document.getElementById('custom-settings').style.display = 'none'; } }); }); // Compression level display document.getElementById('compression-level').addEventListener('input', function() { document.getElementById('compression-value').textContent = this.value; }); // Drag and drop functionality const dropZone = document.getElementById('drop-zone'); dropZone.addEventListener('dragover', (e) => { e.preventDefault(); dropZone.style.borderColor = '#4361ee'; }); dropZone.addEventListener('dragleave', () => { dropZone.style.borderColor = '#8d99ae'; }); dropZone.addEventListener('drop', (e) => { e.preventDefault(); dropZone.style.borderColor = '#8d99ae'; if (e.dataTransfer.files.length) { document.getElementById('image-input').files = e.dataTransfer.files; handleImageSelect({target: document.getElementById('image-input')}); } }); function handleImageSelect(e) { const file = e.target.files[0]; if (file && file.type.match('image.*')) { const reader = new FileReader(); reader.onload = function(event) { originalImage = new Image(); originalImage.onload = function() { document.getElementById('original-image').src = event.target.result; document.getElementById('original-image').style.display = 'block'; document.getElementById('original-size').textContent = (file.size / 1024).toFixed(2) + ' KB'; }; originalImage.src = event.target.result; }; reader.readAsDataURL(file); } } function getCompressionSettings() { switch(selectedCompressionOption) { case 'web': return { quality: 0.7, maxWidth: 1200, maxHeight: 800 }; case 'social': return { quality: 0.5, maxWidth: 1080, maxHeight: 1080 }; case 'print': return { quality: 0.9, maxWidth: 2400, maxHeight: 1600 }; case 'custom': return { quality: document.getElementById('compression-level').value / 100, maxWidth: parseInt(document.getElementById('max-width').value), maxHeight: parseInt(document.getElementById('max-height').value) }; default: return { quality: 0.7, maxWidth: 1200, maxHeight: 800 }; } } document.getElementById('compress-image-btn').addEventListener('click', compressImage); function compressImage() { if (!originalImage) { alert('Please select an image first.'); return; } const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); const settings = getCompressionSettings(); // Calculate new dimensions while maintaining aspect ratio let width = originalImage.width; let height = originalImage.height; if (width > settings.maxWidth) { height = (settings.maxWidth / width) * height; width = settings.maxWidth; } if (height > settings.maxHeight) { width = (settings.maxHeight / height) * width; height = settings.maxHeight; } canvas.width = width; canvas.height = height; ctx.drawImage(originalImage, 0, 0, width, height); canvas.toBlob(function(blob) { compressedImageBlob = blob; const compressedUrl = URL.createObjectURL(blob); document.getElementById('compressed-image').src = compressedUrl; document.getElementById('compressed-image').style.display = 'block'; const originalSize = parseFloat(document.getElementById('original-size').textContent); const compressedSize = (blob.size / 1024).toFixed(2); const reduction = ((originalSize - compressedSize) / originalSize * 100).toFixed(2); document.getElementById('compressed-size').textContent = compressedSize + ' KB'; document.getElementById('reduction').textContent = reduction + '%'; document.getElementById('download-btn').style.display = 'block'; }, 'image/jpeg', settings.quality); } document.getElementById('download-btn').addEventListener('click', downloadImage); function downloadImage() { if (!compressedImageBlob) return; const link = document.createElement('a'); link.href = URL.createObjectURL(compressedImageBlob); link.download = 'compressed-image.jpg'; link.click(); }// NEW: Budget save, print, and download functionality document.getElementById('save-budget-btn').addEventListener('click', function() { const budgetData = { destination: document.getElementById('destination').value, currency: document.getElementById('currency').value, startDate: document.getElementById('start-date').value, endDate: document.getElementById('end-date').value, days: document.getElementById('days').value, accommodationPerDay: document.getElementById('accommodation-per-day').value, foodPerDay: document.getElementById('food-per-day').value, transportationPerDay: document.getElementById('transportation-per-day').value, activitiesPerDay: document.getElementById('activities-per-day').value, miscPerDay: document.getElementById('misc-per-day').value, oneTimeExpenses: document.getElementById('one-time-expenses').value, accommodationTotal: document.getElementById('accommodation-total').textContent, foodTotal: document.getElementById('food-total').textContent, transportationTotal: document.getElementById('transportation-total').textContent, activitiesTotal: document.getElementById('activities-total').textContent, miscTotal: document.getElementById('misc-total').textContent, oneTimeTotal: document.getElementById('one-time-total').textContent, totalCost: document.getElementById('total-cost').textContent }; localStorage.setItem('travelBudget', JSON.stringify(budgetData)); alert('Budget saved successfully! You can reload it when you return.'); }); document.getElementById('print-budget-btn').addEventListener('click', function() { window.print(); }); document.getElementById('download-budget-btn').addEventListener('click', function() { const destination = document.getElementById('destination').value || 'My Trip'; const currencySymbol = getCurrencySymbol(); // Create a text representation of the budget let budgetText = `TRAVEL BUDGET: ${destination}\n\n`; budgetText += `Dates: ${document.getElementById('start-date').value} to ${document.getElementById('end-date').value}\n`; budgetText += `Duration: ${document.getElementById('days').value} days\n\n`; budgetText += "DAILY EXPENSES:\n"; budgetText += `Accommodation: ${currencySymbol}${document.getElementById('accommodation-per-day').value}/day\n`; budgetText += `Food: ${currencySymbol}${document.getElementById('food-per-day').value}/day\n`; budgetText += `Transportation: ${currencySymbol}${document.getElementById('transportation-per-day').value}/day\n`; budgetText += `Activities: ${currencySymbol}${document.getElementById('activities-per-day').value}/day\n`; budgetText += `Miscellaneous: ${currencySymbol}${document.getElementById('misc-per-day').value}/day\n\n`; budgetText += `One-time Expenses: ${currencySymbol}${document.getElementById('one-time-expenses').value}\n\n`; budgetText += "BUDGET SUMMARY:\n"; budgetText += `Accommodation Total: ${document.getElementById('accommodation-total').textContent}\n`; budgetText += `Food Total: ${document.getElementById('food-total').textContent}\n`; budgetText += `Transportation Total: ${document.getElementById('transportation-total').textContent}\n`; budgetText += `Activities Total: ${document.getElementById('activities-total').textContent}\n`; budgetText += `Miscellaneous Total: ${document.getElementById('misc-total').textContent}\n`; budgetText += `One-Time Expenses: ${document.getElementById('one-time-total').textContent}\n`; budgetText += `TOTAL ESTIMATED COST: ${document.getElementById('total-cost').textContent}\n`; // Create a downloadable file const blob = new Blob([budgetText], { type: 'text/plain' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `${destination.replace(/\s+/g, '_')}_Budget.txt`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); });// Initialize the app // Set default dates const today = new Date(); const nextWeek = new Date(); nextWeek.setDate(today.getDate() + 7); document.getElementById('start-date').valueAsDate = today; document.getElementById('end-date').valueAsDate = nextWeek; calculateDays(); // Initialize currency converter with sample conversion document.getElementById('convert-currency-btn').click(); // Load saved budget if exists const savedBudget = localStorage.getItem('travelBudget'); if (savedBudget) { const budgetData = JSON.parse(savedBudget); document.getElementById('destination').value = budgetData.destination || ''; document.getElementById('currency').value = budgetData.currency || 'USD'; document.getElementById('start-date').value = budgetData.startDate || ''; document.getElementById('end-date').value = budgetData.endDate || ''; document.getElementById('days').value = budgetData.days || 1; document.getElementById('accommodation-per-day').value = budgetData.accommodationPerDay || 0; document.getElementById('food-per-day').value = budgetData.foodPerDay || 0; document.getElementById('transportation-per-day').value = budgetData.transportationPerDay || 0; document.getElementById('activities-per-day').value = budgetData.activitiesPerDay || 0; document.getElementById('misc-per-day').value = budgetData.miscPerDay || 0; document.getElementById('one-time-expenses').value = budgetData.oneTimeExpenses || 0; // Calculate to update the summary calculateBudget(); }
Shopping Cart
Scroll to Top