From 019c7feef9ff8f8755a7b1af06264cf9087e05a7 Mon Sep 17 00:00:00 2001 From: almazlar Date: Sat, 7 Feb 2026 22:30:00 +0300 Subject: [PATCH] refactor: Extract inline styles and scripts into dedicated files, add image resizing, and enhance error handling. --- index.html | 219 ++--------------------------------------------------- script.js | 133 ++++++++++++++++++++++++++++++++ style.css | 125 ++++++++++++++++++++++++++++++ 3 files changed, 263 insertions(+), 214 deletions(-) create mode 100644 script.js create mode 100644 style.css diff --git a/index.html b/index.html index fb5eac8..25aa39d 100644 --- a/index.html +++ b/index.html @@ -5,133 +5,8 @@ AI Vision - @@ -158,97 +33,13 @@ Türkçe Çeviri
+ + - - // Görüntü seçildiğinde önizleme yap - function handlePreview(input) { - const file = input.files[0]; - if (!file) return; - - const reader = new FileReader(); - reader.onload = function (e) { - const img = document.getElementById('preview'); - img.src = e.target.result; - img.style.display = "block"; - base64Image = e.target.result.split(',')[1]; - document.getElementById('analyzeBtn').disabled = false; - document.getElementById('uploadText').innerText = file.name; - }; - reader.readAsDataURL(file); - } - - // Moondream ile analiz yap - async function analyzeImage() { - const btn = document.getElementById('analyzeBtn'); - const resultBox = document.getElementById('englishOutput'); - const resultText = document.getElementById('resultText'); - - btn.disabled = true; - btn.innerHTML = ' Düşünüyor...'; - resultBox.style.display = "block"; - resultText.innerText = "Görsel işleniyor, lütfen bekleyin..."; - - try { - const response = await fetch('https://ai.almazlar.com/ollama/api/generate', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - model: "moondream", - prompt: "Describe this image concisely but accurately in English.", - images: [base64Image], - stream: false - }) - }); - - const data = await response.json(); - rawDescription = data.response; - resultText.innerText = rawDescription; - document.getElementById('translateBtn').style.display = "block"; - } catch (err) { - resultText.innerText = "Hata: Sunucuya ulaşılamadı. Nginx veya Ollama ayarlarını kontrol edin."; - console.error(err); - } finally { - btn.innerHTML = "Yeniden Analiz Et"; - btn.disabled = false; - } - } - - // Llama 3 ile çeviri yap - async function translateText() { - const transBtn = document.getElementById('translateBtn'); - const trBox = document.getElementById('translationResult'); - const trText = document.getElementById('trText'); - - transBtn.disabled = true; - transBtn.innerHTML = ' Çevriliyor...'; - trBox.style.display = "block"; - trText.innerText = "Çeviri yapılıyor..."; - - try { - const response = await fetch('https://ai.almazlar.com/ollama/api/generate', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - model: "llama3", - prompt: `Translate the following description into natural Turkish. Only output the translation: "${rawDescription}"`, - stream: false - }) - }); - - const data = await response.json(); - trText.innerText = data.response; - } catch (err) { - trText.innerText = "Hata: Çeviri servisi yanıt vermiyor."; - } finally { - transBtn.disabled = false; - transBtn.innerHTML = "Türkçeye Çevir (Llama 3)"; - } - } - diff --git a/script.js b/script.js new file mode 100644 index 0000000..933adc7 --- /dev/null +++ b/script.js @@ -0,0 +1,133 @@ +let base64Image = ""; +let rawDescription = ""; + +// Görüntü seçildiğinde önizleme yap ve boyutlandır +function handlePreview(input) { + const file = input.files[0]; + if (!file) return; + + const reader = new FileReader(); + reader.onload = function (e) { + const img = new Image(); + img.onload = function () { + const canvas = document.createElement('canvas'); + let width = img.width; + let height = img.height; + const max_size = 1024; + + if (width > height) { + if (width > max_size) { + height *= max_size / width; + width = max_size; + } + } else { + if (height > max_size) { + width *= max_size / height; + height = max_size; + } + } + + canvas.width = width; + canvas.height = height; + const ctx = canvas.getContext('2d'); + ctx.drawImage(img, 0, 0, width, height); + + const previewImg = document.getElementById('preview'); + previewImg.src = canvas.toDataURL('image/jpeg', 0.8); + previewImg.style.display = "block"; + base64Image = previewImg.src.split(',')[1]; + + document.getElementById('analyzeBtn').disabled = false; + document.getElementById('uploadText').innerText = file.name; + document.getElementById('resetBtn').style.display = "block"; + }; + img.src = e.target.result; + }; + reader.readAsDataURL(file); +} + +// Moondream ile analiz yap +async function analyzeImage() { + const btn = document.getElementById('analyzeBtn'); + const resultBox = document.getElementById('englishOutput'); + const resultText = document.getElementById('resultText'); + + btn.disabled = true; + btn.innerHTML = ' Düşünüyor...'; + resultBox.style.display = "block"; + resultText.innerText = "Görsel işleniyor, lütfen bekleyin..."; + + try { + const response = await fetch('https://ai.almazlar.com/ollama/api/generate', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + model: "moondream", + prompt: "Describe this image concisely but accurately in English.", + images: [base64Image], + stream: false + }) + }); + + if (!response.ok) throw new Error(`Sunucu hatası: ${response.status}`); + + const data = await response.json(); + rawDescription = data.response; + resultText.innerText = rawDescription; + document.getElementById('translateBtn').style.display = "block"; + } catch (err) { + resultText.innerText = `Hata: ${err.message}. Lütfen bağlantıyı veya model ayarlarını kontrol edin.`; + console.error(err); + } finally { + btn.innerHTML = "Yeniden Analiz Et"; + btn.disabled = false; + } +} + +// Llama 3 ile çeviri yap +async function translateText() { + const transBtn = document.getElementById('translateBtn'); + const trBox = document.getElementById('translationResult'); + const trText = document.getElementById('trText'); + + transBtn.disabled = true; + transBtn.innerHTML = ' Çevriliyor...'; + trBox.style.display = "block"; + trText.innerText = "Çeviri yapılıyor..."; + + try { + const response = await fetch('https://ai.almazlar.com/ollama/api/generate', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + model: "llama3", + prompt: `Translate the following description into natural Turkish. Only output the translation: "${rawDescription}"`, + stream: false + }) + }); + + if (!response.ok) throw new Error(`Çeviri hatası: ${response.status}`); + + const data = await response.json(); + trText.innerText = data.response; + } catch (err) { + trText.innerText = `Hata: ${err.message}`; + } finally { + transBtn.disabled = false; + transBtn.innerHTML = "Türkçeye Çevir (Llama 3)"; + } +} + +// Uygulamayı sıfırla +function resetApp() { + document.getElementById('fileInput').value = ""; + document.getElementById('preview').style.display = "none"; + document.getElementById('preview').src = ""; + document.getElementById('englishOutput').style.display = "none"; + document.getElementById('translationResult').style.display = "none"; + document.getElementById('analyzeBtn').disabled = true; + document.getElementById('uploadText').innerText = "📷 Görseli seçmek için buraya tıklayın"; + document.getElementById('resetBtn').style.display = "none"; + base64Image = ""; + rawDescription = ""; +} diff --git a/style.css b/style.css new file mode 100644 index 0000000..6c4bc50 --- /dev/null +++ b/style.css @@ -0,0 +1,125 @@ +:root { + --bg: #0f1117; + --card: #161b22; + --accent: #58a6ff; + --success: #238636; + --text: #c9d1d9; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; + background: var(--bg); + color: var(--text); + display: flex; + justify-content: center; + padding: 20px; + line-height: 1.6; +} + +.container { + background: var(--card); + padding: 2rem; + border-radius: 12px; + width: 100%; + max-width: 600px; + border: 1px solid #30363d; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5); +} + +h2 { + text-align: center; + color: var(--accent); + margin-top: 0; +} + +.upload-section { + border: 2px dashed #30363d; + padding: 30px; + text-align: center; + border-radius: 8px; + cursor: pointer; + transition: 0.3s; + margin-bottom: 20px; +} + +.upload-section:hover { + border-color: var(--accent); + background: #1c2128; +} + +#preview { + max-width: 100%; + border-radius: 8px; + margin: 15px 0; + display: none; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); +} + +button { + background: var(--accent); + color: white; + border: none; + padding: 12px; + border-radius: 6px; + cursor: pointer; + font-weight: 600; + width: 100%; + font-size: 1rem; + transition: 0.2s; +} + +button:disabled { + background: #21262d; + color: #8b949e; + cursor: not-allowed; +} + +#translateBtn { + background: var(--success); + margin-top: 15px; + display: none; +} + +.result-box { + margin-top: 25px; + background: #0d1117; + padding: 20px; + border-radius: 8px; + border-left: 4px solid var(--accent); +} + +.label { + font-size: 0.75rem; + color: #8b949e; + text-transform: uppercase; + letter-spacing: 1px; + margin-bottom: 8px; + display: block; +} + +#translationResult { + margin-top: 20px; + color: #acb6c2; + border-left: 4px solid var(--success); +} + +.loader { + display: inline-block; + width: 12px; + height: 12px; + border: 2px solid #fff; + border-bottom-color: transparent; + border-radius: 50%; + animation: rotation 1s linear infinite; + margin-right: 8px; +} + +@keyframes rotation { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } +}