Skip to content

Instantly share code, notes, and snippets.

@pemre
Created March 13, 2025 07:57
Show Gist options
  • Save pemre/e2eaff50ed03e645eb982da230d9cebe to your computer and use it in GitHub Desktop.
Save pemre/e2eaff50ed03e645eb982da230d9cebe to your computer and use it in GitHub Desktop.
Ultra simple experimental yen<>euro converter
<!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