Created
March 13, 2025 07:57
-
-
Save pemre/e2eaff50ed03e645eb982da230d9cebe to your computer and use it in GitHub Desktop.
Ultra simple experimental yen<>euro converter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="tr"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Yen-Euro Çevirici & OCR</title> | |
<style> | |
body { | |
font-family: Arial, sans-serif; | |
padding: 20px; | |
background-color: #f5f5f5; | |
color: #333; | |
transition: background-color 0.3s, color 0.3s; | |
} | |
@media (prefers-color-scheme: dark) { | |
body { | |
background-color: #121212; | |
color: #e0e0e0; | |
} | |
input, button, progress { | |
background-color: #333; | |
color: #e0e0e0; | |
border: 1px solid #444; | |
} | |
} | |
.container { | |
max-width: 400px; | |
margin: 0 auto; | |
} | |
/* Input ve OCR butonunu aynı satıra alıyoruz */ | |
.input-container { | |
display: flex; | |
align-items: center; | |
gap: 5px; | |
} | |
.input-container input[type="text"] { | |
flex: 1; | |
padding: 10px; | |
font-size: 1.2em; | |
box-sizing: border-box; | |
} | |
/* OCR butonunda sadece ikon, yazı yok */ | |
#ocr-button { | |
padding: 10px; | |
cursor: pointer; | |
border: none; | |
display: flex; | |
} | |
/* Çevrilmiş sonuç ve kur bilgisi */ | |
#conversion-info { | |
margin-top: 10px; | |
text-align: center; | |
} | |
#result { | |
font-size: 1.5em; | |
margin-bottom: 5px; | |
} | |
#rate-info { | |
font-size: 0.9em; | |
color: gray; | |
} | |
/* Toggle buton */ | |
#toggle-direction { | |
width: 100%; | |
margin-top: 10px; | |
padding: 10px; | |
font-size: 1em; | |
cursor: pointer; | |
border: none; | |
} | |
/* Manuel kur girişi */ | |
.manual-rate { | |
display: flex; | |
gap: 5px; | |
margin-top: 10px; | |
align-items: center; | |
} | |
.manual-rate label { | |
font-size: 0.9em; | |
} | |
.manual-rate input[type="number"] { | |
flex: 1; | |
padding: 10px; | |
font-size: 1em; | |
box-sizing: border-box; | |
} | |
/* Hesap makinesi alanı */ | |
.calculator { | |
margin-top: 15px; | |
} | |
.digits { | |
display: grid; | |
grid-template-columns: repeat(3, 1fr); | |
gap: 5px; | |
} | |
.bottom-row { | |
display: grid; | |
grid-template-columns: 1fr 1fr 1fr; | |
gap: 5px; | |
margin-top: 5px; | |
} | |
.special-buttons { | |
display: flex; | |
gap: 5px; | |
} | |
.special-buttons button { | |
flex: 1; | |
} | |
/* Özel renkli butonlar */ | |
#clear { | |
background-color: #d32f2f; /* doygun kırmızı */ | |
color: white; | |
} | |
#dot { | |
background-color: #64b5f6; /* mavi ton */ | |
color: white; | |
} | |
#backspace { | |
background-color: #ff9026; /* turuncu */ | |
color: white; | |
} | |
/* Diğer hesap makinesi butonları */ | |
.calculator button[data-value] { | |
padding: 15px; | |
font-size: 1em; | |
cursor: pointer; | |
border: none; | |
} | |
/* Online fetch butonu */ | |
#fetch-online-rate { | |
background-color: #027148; /* yesil */ | |
width: 100%; | |
margin-top: 10px; | |
padding: 10px; | |
font-size: 1em; | |
cursor: pointer; | |
border: none; | |
} | |
/* OCR progress ve durum */ | |
#ocr-progress-container { | |
margin-top: 10px; | |
display: none; | |
} | |
#ocr-progress { | |
width: 100%; | |
} | |
#ocr-status { | |
font-size: 0.9em; | |
margin-top: 5px; | |
text-align: center; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<h2>Yen-Euro Çevirici</h2> | |
<!-- Input ve OCR butonunun bulunduğu satır --> | |
<div class="input-container"> | |
<input type="text" id="amount-input" placeholder="Yen miktarını girin" readonly> | |
<button id="ocr-button" title="OCR"> | |
<svg | |
xmlns="http://www.w3.org/2000/svg" | |
viewBox="0 0 24 24" | |
width="1.5rem" | |
height="1.5rem" | |
{...props} | |
> | |
<circle cx="12" cy="12" r="3.2" fill="currentColor"></circle> | |
<path | |
fill="currentColor" | |
d="M9 2L7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2h-3.17L15 2zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5s5 2.24 5 5s-2.24 5-5 5" | |
></path> | |
</svg> | |
</button> | |
</div> | |
<!-- Çevrilmiş sonuç ve kur bilgisi --> | |
<div id="conversion-info"> | |
<div id="result">€ -</div> | |
<div id="rate-info">Kur: - (Son Fetch: -)</div> | |
</div> | |
<!-- Dönüş yönünü değiştiren toggle butonu --> | |
<button id="toggle-direction">¥ Yen → € Euro</button> | |
<!-- Manuel kur girişi ve online fetch butonu --> | |
<div class="manual-rate"> | |
<label for="manual-rate-input">Manuel Kur:</label> | |
<input type="number" id="manual-rate-input" step="any" placeholder="Kuru girin"> | |
<button id="fetch-online-rate">♻️</button> | |
</div> | |
<!-- Hesap makinesi alanı --> | |
<div class="calculator"> | |
<div class="digits"> | |
<button data-value="7">7</button> | |
<button data-value="8">8</button> | |
<button data-value="9">9</button> | |
<button data-value="4">4</button> | |
<button data-value="5">5</button> | |
<button data-value="6">6</button> | |
<button data-value="1">1</button> | |
<button data-value="2">2</button> | |
<button data-value="3">3</button> | |
</div> | |
<div class="bottom-row"> | |
<div class="special-buttons"> | |
<button id="clear">C</button> | |
<button id="dot">.</button> | |
</div> | |
<button data-value="0">0</button> | |
<button id="backspace">←</button> | |
</div> | |
</div> | |
<!-- OCR progress ve durum mesajı --> | |
<div id="ocr-progress-container"> | |
<progress id="ocr-progress" value="0" max="100"></progress> | |
<div id="ocr-status"></div> | |
</div> | |
<!-- Gizli dosya inputu --> | |
<input type="file" id="ocr-input" accept="image/*" style="display: none;"> | |
</div> | |
<!-- Tesseract.js kütüphanesi --> | |
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/tesseract.min.js"></script> | |
<script> | |
let conversionRate = null; // conversionRate, "yen per euro" olarak belirlenecek | |
let isYenToEuro = true; // Varsayılan: Girilen değer yen ise euroya çevrilecek | |
const inputField = document.getElementById('amount-input'); | |
document.addEventListener('DOMContentLoaded', () => { | |
const storedRate = localStorage.getItem('exchangeRate'); | |
const storedFetch = localStorage.getItem('lastFetch'); | |
if (storedRate) { | |
conversionRate = parseFloat(storedRate); | |
} | |
updateRateInfo(storedFetch); | |
updateConversion(); | |
// Hesap makinesi tuşları (data-value olan butonlar) | |
document.querySelectorAll('.calculator button[data-value]').forEach(btn => { | |
btn.addEventListener('click', () => { | |
inputField.value += btn.getAttribute('data-value'); | |
updateConversion(); | |
}); | |
}); | |
// Özel butonlar: Clear, Dot, Backspace | |
document.getElementById('clear').addEventListener('click', () => { | |
inputField.value = ''; | |
updateConversion(); | |
}); | |
document.getElementById('dot').addEventListener('click', () => { | |
if (!inputField.value.includes('.')) { | |
inputField.value += '.'; | |
updateConversion(); | |
} | |
}); | |
document.getElementById('backspace').addEventListener('click', () => { | |
inputField.value = inputField.value.slice(0, -1); | |
updateConversion(); | |
}); | |
// Dönüş yönü toggle butonu | |
document.getElementById('toggle-direction').addEventListener('click', () => { | |
isYenToEuro = !isYenToEuro; | |
if (isYenToEuro) { | |
document.getElementById('toggle-direction').textContent = "¥ Yen → € Euro"; | |
inputField.placeholder = "Yen miktarını girin"; | |
} else { | |
document.getElementById('toggle-direction').textContent = "€ Euro → ¥ Yen"; | |
inputField.placeholder = "Euro miktarını girin"; | |
} | |
updateConversion(); | |
}); | |
// Manuel kur inputu: değişince otomatik kaydet | |
document.getElementById('manual-rate-input').addEventListener('input', (e) => { | |
const val = parseFloat(e.target.value); | |
if (!isNaN(val) && val > 0) { | |
conversionRate = val; | |
localStorage.setItem('exchangeRate', conversionRate); | |
updateRateInfo(localStorage.getItem('lastFetch')); | |
updateConversion(); | |
} | |
}); | |
// Online kur fetch butonu | |
document.getElementById('fetch-online-rate').addEventListener('click', () => { | |
fetchOnlineRate(); | |
}); | |
// OCR buton işlemleri | |
const ocrButton = document.getElementById('ocr-button'); | |
const ocrInput = document.getElementById('ocr-input'); | |
const ocrProgressContainer = document.getElementById('ocr-progress-container'); | |
const ocrProgress = document.getElementById('ocr-progress'); | |
const ocrStatus = document.getElementById('ocr-status'); | |
ocrButton.addEventListener('click', () => { | |
console.log("OCR butonuna tıklandı."); | |
ocrInput.click(); | |
}); | |
ocrInput.addEventListener('change', (e) => { | |
const file = e.target.files[0]; | |
if (file) { | |
console.log("OCR için dosya seçildi:", file); | |
ocrProgressContainer.style.display = 'block'; | |
ocrProgress.value = 0; | |
ocrStatus.textContent = "OCR başlatılıyor..."; | |
Tesseract.recognize(file, 'eng', { | |
logger: m => { | |
console.log(m); | |
if (m.status === 'recognizing text') { | |
const prog = Math.round(m.progress * 100); | |
ocrProgress.value = prog; | |
ocrStatus.textContent = "OCR ilerleme: " + prog + "%"; | |
} | |
} | |
}).then(({ data: { text } }) => { | |
console.log("OCR sonucu:", text); | |
const match = text.match(/\d+[\d.,]*/); | |
if (match) { | |
let numStr = match[0].replace(/,/g, ''); | |
inputField.value = numStr; | |
updateConversion(); | |
ocrStatus.textContent = "OCR başarılı."; | |
} else { | |
ocrStatus.textContent = "Fiyat bulunamadı!"; | |
} | |
setTimeout(() => { | |
ocrProgressContainer.style.display = 'none'; | |
}, 2000); | |
}).catch(err => { | |
console.error(err); | |
ocrStatus.textContent = "OCR sırasında hata!"; | |
setTimeout(() => { | |
ocrProgressContainer.style.display = 'none'; | |
}, 2000); | |
}); | |
} else { | |
console.log("OCR için dosya seçilmedi."); | |
} | |
}); | |
}); | |
// Dönüşüm hesaplaması: | |
// conversionRate burada "yen per euro" olarak belirlendi. | |
function updateConversion() { | |
const inputValue = parseFloat(inputField.value); | |
const resultDiv = document.getElementById('result'); | |
if (!isNaN(inputValue) && conversionRate !== null) { | |
let converted; | |
if (isYenToEuro) { | |
// Yen → Euro: girilen yen miktarını, conversionRate'e bölüyoruz. | |
converted = inputValue / conversionRate; | |
resultDiv.textContent = "€ " + converted.toFixed(2); | |
} else { | |
// Euro → Yen: girilen euro miktarını conversionRate ile çarpıyoruz. | |
converted = inputValue * conversionRate; | |
resultDiv.textContent = "¥ " + converted.toFixed(2); | |
} | |
} else { | |
resultDiv.textContent = isYenToEuro ? "€ -" : "¥ -"; | |
} | |
} | |
// Online API ile kuru çekme (yeni endpoint) ve localStorage kaydı | |
// Gelen data.eur.jpy ters oranı veriyor; bu değerin tersini alıp 1 EUR'nun kaç yen ettiğini elde ediyoruz. | |
function fetchOnlineRate() { | |
fetch("https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/eur.json") | |
.then(response => response.json()) | |
.then(data => { | |
if (data && data.eur && data.eur.jpy) { | |
// 1 / data.eur.jpy ile kuru elde edip, 5 ondalık basamağa yuvarlıyoruz. | |
conversionRate = data.eur.jpy; | |
console.log('exchangeRate', conversionRate); | |
localStorage.setItem('exchangeRate', conversionRate); | |
const fetchDate = data.date; | |
localStorage.setItem('lastFetch', fetchDate); | |
document.getElementById('manual-rate-input').value = conversionRate; | |
updateRateInfo(fetchDate); | |
updateConversion(); | |
} else { | |
alert("Kur alınamadı."); | |
} | |
}) | |
.catch(err => { | |
console.error(err); | |
alert("Kur alınırken hata oluştu."); | |
}); | |
} | |
// Kur bilgisini ve son fetch zamanını güncelle (kuru 5 ondalık basamakla göster) | |
function updateRateInfo(fetchTime) { | |
const rateInfo = document.getElementById('rate-info'); | |
const rateText = conversionRate ? conversionRate : "-"; | |
const timeText = fetchTime ? fetchTime : "-"; | |
rateInfo.textContent = "Kur: " + rateText + " (Son güncelleme: " + timeText + ")"; | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment