169 lines
6.9 KiB
HTML
169 lines
6.9 KiB
HTML
<!-- Description: Pokémon GO Level Calculator -->
|
|
<!-- Author: Justin Oros -->
|
|
<!-- Source: https://github.com/JustinOros -->
|
|
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Pokémon GO Level Calculator</title>
|
|
|
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
|
<link rel="icon" type="image/png" sizes="32x32" href="pogo-32.png">
|
|
<link rel="icon" type="image/png" sizes="192x192" href="pogo-192.png">
|
|
<link rel="apple-touch-icon" sizes="180x180" href="pogo-180.png">
|
|
<link rel="icon" type="image/png" sizes="512x512" href="pogo-512.png">
|
|
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<style>
|
|
body { font-family: 'Inter', sans-serif; }
|
|
body::before {
|
|
content: '';
|
|
position: fixed;
|
|
top: 0; left: 0;
|
|
width: 100%; height: 100%;
|
|
background-image: radial-gradient(circle at 1px 1px, rgba(0,0,0,0.05) 1px, transparent 0);
|
|
background-size: 20px 20px;
|
|
opacity: 0.5;
|
|
z-index: -1;
|
|
}
|
|
.cursor-pointer { cursor: pointer; }
|
|
#edit-xp {
|
|
display: inline-block;
|
|
transform: scaleX(-1);
|
|
}
|
|
</style>
|
|
</head>
|
|
<body class="bg-slate-50 flex items-center justify-center min-h-screen p-4">
|
|
|
|
<div class="w-full max-w-md bg-white rounded-2xl shadow-xl p-6 md:p-8 border border-slate-200 text-center">
|
|
|
|
<img src="pogo.png" alt="Pokémon GO" class="mx-auto mb-4 w-32 h-auto">
|
|
|
|
<h1 class="text-2xl md:text-3xl font-bold text-slate-900 mb-4">Pokémon GO Level Calculator</h1>
|
|
<p class="text-slate-500 mb-6">Enter your total XP to see your level</p>
|
|
|
|
<div class="flex gap-2 mb-4 justify-center">
|
|
<input type="text" id="xp-input" placeholder="e.g., 123,456,789"
|
|
class="flex-1 px-4 py-3 border border-slate-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-400 text-center text-lg">
|
|
|
|
<button id="calculate-btn"
|
|
class="w-12 h-12 bg-green-500 hover:bg-green-600 text-white font-bold rounded-lg transition-transform transform hover:scale-105">
|
|
GO!
|
|
</button>
|
|
</div>
|
|
|
|
<div id="result" class="mt-8 hidden">
|
|
<div class="relative w-full h-16 bg-slate-200 rounded-lg overflow-hidden">
|
|
<div id="progress-bar" class="absolute top-0 left-0 h-full bg-green-500"></div>
|
|
<div id="level-text" class="absolute inset-0 flex items-center justify-center text-3xl font-bold text-black"></div>
|
|
</div>
|
|
<div class="flex justify-between text-xs text-slate-500 mt-1">
|
|
<span id="level-left"></span>
|
|
<span id="level-right"></span>
|
|
</div>
|
|
|
|
<div id="extra-info" class="mt-3 text-sm text-slate-600">
|
|
<p>
|
|
If you average
|
|
<span id="xp-per-day">15,000</span> XP per day,
|
|
you will reach the next level in
|
|
<span id="days-next">0</span> and level 80 in
|
|
<span id="days-80">0</span>. <span id="edit-xp" class="ml-1 text-blue-500 cursor-pointer">✏️</span>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
const xpThresholds = [
|
|
0, 1000, 3000, 6000, 10000, 15000, 21000, 28000, 36000, 45000,
|
|
55000, 65000, 75000, 85000, 100000, 120000, 140000, 160000, 185000, 210000,
|
|
260000, 335000, 435000, 560000, 710000, 900000, 1100000, 1350000, 1650000, 2000000,
|
|
2500000, 3000000, 3750000, 4750000, 6000000, 7500000, 9500000, 12000000, 15000000, 20000000,
|
|
26000000, 33500000, 42500000, 43500000, 66500000, 82000000, 100000000, 121000000, 146000000, 176000000,
|
|
206000000, 236000000, 266000000, 296000000, 326000000, 356000000, 386000000, 416000000, 446000000, 476000000,
|
|
506000000, 536000000, 566000000, 596000000, 626000000, 656000000, 686000000, 716000000, 746000000, 776000000,
|
|
806000000, 836000000, 866000000, 896000000, 926000000, 956000000, 986000000, 1016000000, 1046000000, 1076000000,
|
|
];
|
|
|
|
let avgXpPerDay = 15000;
|
|
let currentXp = 0;
|
|
let currentLevel = 1;
|
|
|
|
function calculateLevel(xp) {
|
|
let level = 1;
|
|
for (let i = 0; i < xpThresholds.length; i++) {
|
|
if (xp >= xpThresholds[i]) {
|
|
level = i + 1;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
return level;
|
|
}
|
|
|
|
function formatDays(days) {
|
|
if (days > 365) {
|
|
return (days / 365).toFixed(1) + ' years';
|
|
}
|
|
return days.toLocaleString() + ' days';
|
|
}
|
|
|
|
function updateExtraInfo() {
|
|
let nextLevelXp = (currentLevel < xpThresholds.length) ? xpThresholds[currentLevel] : currentXp;
|
|
let xpToNext = Math.max(0, nextLevelXp - currentXp);
|
|
let xpTo40 = Math.max(0, xpThresholds[39] - currentXp); // Level 40
|
|
let xpTo80 = Math.max(0, xpThresholds[79] - currentXp);
|
|
|
|
let daysNext = Math.ceil(xpToNext / avgXpPerDay);
|
|
let days40 = Math.ceil(xpTo40 / avgXpPerDay);
|
|
let days80 = Math.ceil(xpTo80 / avgXpPerDay);
|
|
|
|
const nextText = currentLevel < 40
|
|
? `If you average ${avgXpPerDay.toLocaleString()} XP per day, you will reach the next level in ${formatDays(daysNext)}, level 40 in ${formatDays(days40)}, and level 80 in ${formatDays(days80)}.`
|
|
: `If you average ${avgXpPerDay.toLocaleString()} XP per day, you will reach the next level in ${formatDays(daysNext)} and level 80 in ${formatDays(days80)}.`;
|
|
|
|
document.getElementById('extra-info').innerHTML = `<p>${nextText} <span id="edit-xp" class="ml-1 text-blue-500 cursor-pointer">✏️</span></p>`;
|
|
}
|
|
|
|
document.getElementById('calculate-btn').addEventListener('click', () => {
|
|
let xp = document.getElementById('xp-input').value.replace(/,/g,'').trim();
|
|
if (!xp || isNaN(xp)) {
|
|
alert('Please enter a valid number for XP.');
|
|
return;
|
|
}
|
|
currentXp = parseInt(xp, 10);
|
|
|
|
currentLevel = calculateLevel(currentXp);
|
|
let nextLevelXp = (currentLevel < xpThresholds.length) ? xpThresholds[currentLevel] : currentXp;
|
|
let currentLevelXp = xpThresholds[currentLevel - 1];
|
|
let progress = (currentXp - currentLevelXp) / (nextLevelXp - currentLevelXp) * 100;
|
|
|
|
document.getElementById('progress-bar').style.width = progress + '%';
|
|
document.getElementById('level-text').textContent = `Level ${currentLevel}`;
|
|
document.getElementById('level-left').textContent = currentLevel;
|
|
document.getElementById('level-right').textContent = (currentLevel < xpThresholds.length) ? currentLevel + 1 : currentLevel;
|
|
|
|
document.getElementById('result').classList.remove('hidden');
|
|
|
|
updateExtraInfo();
|
|
});
|
|
|
|
document.getElementById('xp-input').addEventListener('input', (e)=>{
|
|
e.target.value = e.target.value.replace(/[^0-9,]/g,'');
|
|
});
|
|
|
|
document.getElementById('edit-xp').addEventListener('click', () => {
|
|
let newVal = prompt("Enter your average XP per day:", avgXpPerDay);
|
|
if (newVal && !isNaN(newVal) && parseInt(newVal) > 0) {
|
|
avgXpPerDay = parseInt(newVal, 10);
|
|
updateExtraInfo();
|
|
}
|
|
});
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|