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
Image Compression Tool
Optimize your travel images for web and social media
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
Original Image
![Original image]()
Compressed 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();
}