Spaces:
Sleeping
Sleeping
| <html lang="id"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| <title>Deteksi Tumor Otak</title> | |
| <style> | |
| /* === GLOBAL === */ | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| font-family: 'Poppins', sans-serif; | |
| } | |
| body { | |
| background-color: #0b1120; | |
| color: white; | |
| overflow-x: hidden; | |
| } | |
| h1, h2, h3 { | |
| color: #00ffff; | |
| } | |
| button { | |
| background-color: transparent; | |
| border: 2px solid #00ffff; | |
| color: #00ffff; | |
| padding: 12px 24px; | |
| font-size: 1rem; | |
| border-radius: 10px; | |
| cursor: pointer; | |
| transition: 0.3s; | |
| } | |
| button:hover { | |
| background-color: #00ffff; | |
| color: #0b1120; | |
| transform: scale(1.05); | |
| } | |
| section { | |
| display: none; | |
| min-height: 100vh; | |
| padding: 40px; | |
| text-align: center; | |
| justify-content: center; | |
| align-items: center; | |
| flex-direction: column; | |
| } | |
| section.active { | |
| display: flex; | |
| } | |
| .neon-text { | |
| text-shadow: 0 0 5px rgb(255, 255, 255), 0 0 10px rgb(0, 255, 255); | |
| color: #000000; | |
| } | |
| .btn-group { | |
| display: flex; | |
| gap: 20px; | |
| margin-top: 30px; | |
| justify-content: center; | |
| flex-wrap: wrap; | |
| } | |
| /* === HALAMAN UTAMA === */ | |
| #home h1 { | |
| font-size: 3rem; | |
| margin-bottom: 10px; | |
| } | |
| #home img { | |
| width: 340px; | |
| margin-top: 30px; | |
| filter: drop-shadow(0 0 8px rgba(28, 131, 131, 0.3)); | |
| opacity: 0.9; | |
| } | |
| /* === HALAMAN INFO === */ | |
| .info-container { | |
| max-width: 800px; | |
| margin: 30px auto; | |
| background: rgba(0, 255, 255, 0.05); | |
| border: 1px solid rgba(0, 255, 255, 0.2); | |
| border-radius: 15px; | |
| padding: 30px 40px; | |
| text-align: left; | |
| box-shadow: 0 0 20px rgba(0, 255, 255, 0.1); | |
| backdrop-filter: blur(6px); | |
| } | |
| .info-paragraph { | |
| font-size: 1.05rem; | |
| line-height: 1.8; | |
| color: #e0faff; | |
| margin-bottom: 20px; | |
| text-align: justify; | |
| text-shadow: 0 0 5px rgba(0, 255, 255, 0.2); | |
| } | |
| .info-list { | |
| list-style: none; | |
| margin-top: 10px; | |
| margin-bottom: 25px; | |
| padding-left: 0; | |
| } | |
| .info-list li { | |
| background: rgba(0, 255, 255, 0.08); | |
| border-left: 3px solid #00ffff; | |
| margin-bottom: 12px; | |
| padding: 12px 18px; | |
| border-radius: 10px; | |
| color: #ccf9ff; | |
| font-size: 1rem; | |
| transition: all 0.3s ease; | |
| } | |
| /* === HALAMAN SCAN === */ | |
| #scan .scan-frame { | |
| width: 400px; | |
| height: 300px; | |
| border: 3px dashed #00ffff; | |
| border-radius: 20px; | |
| margin: 30px auto; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| color: #00ffff; | |
| font-size: 1.1rem; | |
| text-align: center; | |
| overflow: hidden; | |
| } | |
| #scan img { | |
| width: 100%; | |
| height: 100%; | |
| object-fit: cover; | |
| } | |
| .alert { | |
| color: #ff6666; | |
| margin-top: 10px; | |
| font-size: 0.95rem; | |
| } | |
| /* === HASIL SCAN === */ | |
| #result .result-box { | |
| border: 2px solid #00ffff; | |
| border-radius: 20px; | |
| padding: 20px; | |
| width: 400px; | |
| margin-top: 20px; | |
| background-color: rgba(0, 255, 255, 0.1); | |
| } | |
| .spinner { | |
| border: 4px solid rgba(0, 255, 255, 0.2); | |
| border-top: 4px solid #00ffff; | |
| border-radius: 50%; | |
| width: 60px; | |
| height: 60px; | |
| animation: spin 1s linear infinite; | |
| margin: 20px auto; | |
| } | |
| @keyframes spin { | |
| from { transform: rotate(0deg); } | |
| to { transform: rotate(360deg); } | |
| } | |
| /* === HISTORY === */ | |
| #history table { | |
| width: 85%; | |
| margin: 0 auto; | |
| border-collapse: collapse; | |
| color: white; | |
| } | |
| #history th, #history td { | |
| border: 1px solid #00ffff; | |
| padding: 12px; | |
| text-align: center; | |
| } | |
| #history th { | |
| background-color: rgba(0, 255, 255, 0.2); | |
| } | |
| /* Thumbnail */ | |
| .thumb { | |
| width: 70px; | |
| height: 70px; | |
| object-fit: cover; | |
| border-radius: 10px; | |
| border: 1px solid rgba(0, 255, 255, 0.4); | |
| transition: 0.3s ease; | |
| } | |
| .thumb:hover { | |
| transform: scale(1.8); | |
| border-color: #00ffff; | |
| z-index: 5; | |
| } | |
| #clearHistory { | |
| border: 2px solid #ff4444; | |
| color: #ff4444; | |
| } | |
| #clearHistory:hover { | |
| background-color: #ff4444; | |
| color: white; | |
| } | |
| #footer { | |
| position: fixed; | |
| bottom: 10px; | |
| width: 100%; | |
| text-align: center; | |
| font-size: 0.9rem; | |
| color: #00ffff; | |
| opacity: 0.6; | |
| } | |
| /*=== Responsive untuk tablet dan HP ===*/ | |
| @media (max-width: 1024px) { | |
| section { | |
| padding: 60px 30px; | |
| } | |
| #home img { | |
| width: 280px; | |
| } | |
| h1 { | |
| font-size: 2rem; | |
| } | |
| p, li { | |
| font-size: 1rem; | |
| } | |
| button { | |
| font-size: 0.9rem; | |
| padding: 10px 20px; | |
| } | |
| table { | |
| font-size: 0.9rem; | |
| } | |
| } | |
| /*=== Responsive untuk HP kecil ===*/ | |
| @media (max-width: 600px) { | |
| body { | |
| font-size: 16px; | |
| overflow-x: hidden; | |
| } | |
| nav { | |
| flex-direction: column; | |
| text-align: center; | |
| padding: 15px; | |
| } | |
| nav a { | |
| margin: 8px 0; | |
| font-size: 1rem; | |
| } | |
| #home { | |
| text-align: center; | |
| } | |
| #home img { | |
| width: 200px; | |
| margin: 20px auto; | |
| } | |
| section { | |
| padding: 40px 20px; | |
| } | |
| h1 { | |
| font-size: 1.6rem; | |
| } | |
| p, li { | |
| font-size: 0.95rem; | |
| text-align: justify; | |
| } | |
| button { | |
| width: 100%; | |
| font-size: 1rem; | |
| } | |
| #scanFrame img { | |
| width: 100%; | |
| max-width: 300px; | |
| height: auto; | |
| } | |
| table { | |
| width: 100%; | |
| font-size: 0.8rem; | |
| border-collapse: collapse; | |
| } | |
| th, td { | |
| padding: 8px 6px; | |
| } | |
| .thumb { | |
| width: 45px; | |
| height: 45px; | |
| } | |
| /* Responsive Tabel */ | |
| .table-container { | |
| overflow-x: auto; | |
| width: 100%; | |
| } | |
| #history table { | |
| display: block; | |
| overflow-x: auto; | |
| white-space: nowrap; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- HOME --> | |
| <section id="home" class="active"> | |
| <div> | |
| <h1 class="neon-text">Brain Tumor Detection</h1> | |
| <p>Simulasi pendeteksian tumor otak</p> | |
| <img src="download.jpg" alt="Brain Image" /> | |
| <div class="btn-group"> | |
| <button onclick="showPage('scan')">Mulai Scan</button> | |
| <button onclick="showPage('history')">History</button> | |
| <button onclick="showPage('info')">Tentang</button> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- INFO --> | |
| <section id="info"> | |
| <h2 class="neon-text">Tentang Aplikasi</h2> | |
| <div class="info-container"> | |
| <p class="info-paragraph"> | |
| <strong>Brain Tumor Detection</strong> adalah aplikasi berbasis kecerdasan buatan (AI) | |
| yang dirancang untuk membantu mendeteksi adanya tumor pada otak manusia secara cepat dan akurat. | |
| Aplikasi ini bekerja dengan cara menganalisis gambar hasil pemindaian otak | |
| (seperti hasil <b>USG</b>, <b>MRI</b>, atau <b>CT Scan</b>) yang diunggah oleh pengguna. | |
| </p> | |
| <p class="info-paragraph"> | |
| Melalui proses analisis citra digital dan model machine learning, aplikasi ini dapat: | |
| </p> | |
| <ul class="info-list"> | |
| <li>🧠 Mengidentifikasi ada atau tidaknya tumor otak dalam gambar.</li> | |
| <li>🔬 Menentukan jenis tumor (jinak atau ganas).</li> | |
| <li>📍 Menunjukkan lokasi atau posisi tumor pada area otak.</li> | |
| <li>📏 Mengestimasi ukuran atau luas area tumor.</li> | |
| </ul> | |
| <p class="info-paragraph"> | |
| Tujuan utama dari aplikasi ini adalah membantu tenaga medis maupun pasien dalam | |
| <b>deteksi dini tumor otak</b>, sehingga proses diagnosis dan penanganan dapat dilakukan | |
| dengan lebih cepat dan tepat. | |
| </p> | |
| <button onclick="showPage('home')">Kembali ke Menu</button> | |
| </div> | |
| </section> | |
| <!-- SCAN --> | |
| <section id="scan"> | |
| <h2 class="neon-text">Proses Pemindaian</h2> | |
| <div class="scan-frame" id="scanFrame">Upload Gambar MRI di Sini</div> | |
| <input type="file" id="fileInput" accept="image/*" style="display:none" /> | |
| <button onclick="document.getElementById('fileInput').click()">Upload Gambar</button> | |
| <button onclick="simulateScan()">Mulai Deteksi</button> | |
| <button onclick="showPage('home')">Kembali</button> | |
| <div class="alert" id="alertMsg"></div> | |
| </section> | |
| <!-- RESULT --> | |
| <section id="result"> | |
| <h2 class="neon-text">Hasil Pemindaian</h2> | |
| <div class="spinner" id="loadingSpinner" style="display:none"></div> | |
| <div class="result-box" id="resultBox" style="display:none;"> | |
| <p><strong>Hasil:</strong> <span id="resultText">Menganalisis...</span></p> | |
| <p><strong>Jenis Tumor:</strong> <span id="tumorType">-</span></p> | |
| <p><strong>Tingkat Kepercayaan:</strong> <span id="confidence">-</span></p> | |
| <p><strong>Tanggal Deteksi:</strong> <span id="date"></span></p> | |
| </div> | |
| <div class="btn-group"> | |
| <button onclick="showPage('home')">Kembali ke Menu</button> | |
| </div> | |
| </section> | |
| <!-- HISTORY --> | |
| <section id="history"> | |
| <h2 class="neon-text">History</h2> | |
| <table> | |
| <thead> | |
| <tr> | |
| <th>No</th> | |
| <th>Gambar</th> | |
| <th>Hasil</th> | |
| <th>Jenis Tumor</th> | |
| <th>Persentase(%)</th> | |
| <th>Tanggal</th> | |
| </tr> | |
| </thead> | |
| <tbody id="historyTable"></tbody> | |
| </table> | |
| <div class="btn-group" style="margin-top:20px"> | |
| <button id="clearHistory" onclick="clearHistory()">Hapus History</button> | |
| <button onclick="showPage('home')">Kembali</button> | |
| </div> | |
| </section> | |
| <div id="footer">© 2025 Brain Tumor Detection By Team-FTI</div> | |
| <script> | |
| const apiUrl = 'https://vincentcps-aibraintumor.hf.space/predict'; | |
| let uploadedFile = null; | |
| let uploadedImageSrc = ''; | |
| let historyData = []; | |
| function showPage(pageId) { | |
| document.querySelectorAll('section').forEach(sec => sec.classList.remove('active')); | |
| document.getElementById(pageId).classList.add('active'); | |
| document.getElementById('alertMsg').textContent = ''; | |
| } | |
| document.getElementById('fileInput').addEventListener('change', e => { | |
| const file = e.target.files[0]; | |
| const frame = document.getElementById('scanFrame'); | |
| if (file) { | |
| const reader = new FileReader(); | |
| reader.onload = evt => { | |
| uploadedImageSrc = evt.target.result; | |
| frame.innerHTML = `<img src="${evt.target.result}" alt="MRI Preview"/>`; | |
| }; | |
| reader.readAsDataURL(file); | |
| uploadedFile = file; | |
| } else { | |
| frame.textContent = 'Unggah Gambar MRI di Sini'; | |
| uploadedFile = null; | |
| uploadedImageSrc = ''; | |
| } | |
| }); | |
| function simulateScan() { | |
| const alert = document.getElementById('alertMsg'); | |
| if (!uploadedFile) { | |
| alert.textContent = '⚠️ Silakan unggah gambar MRI terlebih dahulu.'; | |
| return; | |
| } | |
| showPage('result'); | |
| const spinner = document.getElementById('loadingSpinner'); | |
| const resultBox = document.getElementById('resultBox'); | |
| spinner.style.display = 'block'; | |
| resultBox.style.display = 'none'; | |
| setTimeout(() => { | |
| spinner.style.display = 'none'; | |
| resultBox.style.display = 'block'; | |
| const result = Math.random() > 0.5 ? 'Tumor Terdeteksi' : 'Tidak Ada Tumor'; | |
| const confidence = (80 + Math.random() * 20).toFixed(2) + '%'; | |
| const date = new Date().toLocaleString('id-ID'); | |
| const tumorTypes = ['Glioma (Ganas)', 'Meningioma (Jinak)', 'Pituitary Tumor (Sedang)']; | |
| let tumorType = '-'; | |
| if (result === 'Tumor Terdeteksi') { | |
| tumorType = tumorTypes[Math.floor(Math.random() * tumorTypes.length)]; | |
| } | |
| document.getElementById('resultText').textContent = result; | |
| document.getElementById('tumorType').textContent = tumorType; | |
| document.getElementById('confidence').textContent = confidence; | |
| document.getElementById('date').textContent = date; | |
| addToHistory(result, tumorType, confidence, date); | |
| uploadedFile = null; | |
| const fileInput = document.getElementById('fileInput'); | |
| const frame = document.getElementById('scanFrame'); | |
| fileInput.value = ''; | |
| frame.textContent = 'Unggah Gambar MRI di Sini'; | |
| }, 2500); | |
| } | |
| function addToHistory(result, tumorType, confidence, date) { | |
| historyData.push({ result, tumorType, confidence, date }); | |
| renderHistory(); | |
| } | |
| function renderHistory() { | |
| const tbody = document.getElementById('historyTable'); | |
| tbody.innerHTML = ''; | |
| historyData.forEach((item, i) => { | |
| tbody.innerHTML += ` | |
| <tr> | |
| <td>${i + 1}</td> | |
| <td>${item.result}</td> | |
| <td>${item.tumorType}</td> | |
| <td>${item.confidence}</td> | |
| <td>${item.date}</td> | |
| </tr> | |
| `; | |
| }); | |
| } | |
| function clearHistory() { | |
| if (confirm('Apakah Anda yakin ingin menghapus semua riwayat deteksi?')) { | |
| historyData = []; | |
| renderHistory(); | |
| } | |
| } | |
| </script> | |
| </body> | |
| </html> | |