PROMPTER
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Gültekin Prompter v3</title>
<style>
body, html {
margin: 0; padding: 0;
background-color: #000;
color: #fff;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
height: 100%;
overflow: hidden;
}
/* Editör Ekranı */
#editor-screen {
display: flex;
flex-direction: column;
height: 100vh;
padding: 20px;
box-sizing: border-box;
gap: 15px;
}
/* Üst Dosya & Hafıza Yönetim Paneli */
#file-controls {
display: flex;
flex-wrap: wrap;
gap: 10px;
background-color: #111;
padding: 15px;
border-radius: 10px;
border: 1px solid #333;
align-items: center;
}
.file-btn {
background-color: #333;
color: #fff;
border: none;
padding: 12px 16px;
border-radius: 8px;
font-size: 16px;
font-weight: bold;
cursor: pointer;
display: flex;
align-items: center;
gap: 5px;
}
.file-btn:active { background-color: #555; }
.btn-save { background-color: #28a745; }
.btn-import { background-color: #17a2b8; }
.btn-export { background-color: #6c757d; }
.btn-delete { background-color: #dc3545; padding: 12px; }
#saved-scripts {
flex-grow: 1;
background-color: #222;
color: #fff;
border: 1px solid #444;
padding: 12px;
border-radius: 8px;
font-size: 16px;
min-width: 150px;
}
textarea {
flex-grow: 1;
background-color: #1a1a1a;
color: #fff;
font-size: 24px;
padding: 20px;
border: 2px solid #333;
border-radius: 10px;
resize: none;
outline: none;
}
.start-btn {
background-color: #007bff;
color: white;
font-size: 24px;
font-weight: bold;
padding: 20px;
border: none;
border-radius: 10px;
cursor: pointer;
}
/* Prompter Ekranı */
#prompter-screen {
display: none;
height: 100vh;
overflow-y: hidden;
position: relative;
}
#text-container {
padding: 60px 40px 300px 40px;
font-size: 70px;
font-weight: bold;
line-height: 1.4;
text-align: center;
white-space: pre-wrap;
position: absolute;
top: 0;
left: 0;
right: 0;
}
.mirrored {
transform: scaleX(-1);
}
/* Kontrol Paneli */
#controls {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
background-color: rgba(30, 30, 30, 0.95);
padding: 15px 25px;
border-radius: 20px;
display: flex;
gap: 12px;
z-index: 100;
box-shadow: 0px 4px 15px rgba(0,0,0,0.5);
align-items: center;
}
.ctrl-btn {
background-color: #444;
color: white;
border: none;
border-radius: 8px;
padding: 15px 18px;
font-size: 18px;
font-weight: bold;
cursor: pointer;
min-width: 70px;
white-space: nowrap;
}
.ctrl-btn:active { background-color: #666; }
#play-btn { background-color: #007bff; min-width: 110px; font-size: 20px; }
#play-btn.playing { background-color: #dc3545; }
#edit-btn { background-color: #ffc107; color: black; }
#fullscreen-btn { background-color: #6c757d; min-width: 130px; }
.nav-btn { background-color: #17a2b8; }
.marker {
position: fixed;
top: 50%;
width: 20px;
height: 4px;
background-color: rgba(255, 0, 0, 0.5);
z-index: 50;
}
.marker-left { left: 0; }
.marker-right { right: 0; }
</style>
</head>
<body>
<div id="editor-screen">
<div id="file-controls">
<button class="file-btn btn-save" onclick="saveToMemory()">💾 Hafızaya Kaydet</button>
<select id="saved-scripts" onchange="loadFromMemory()">
<option value="">-- Hafızadan Metin Seç / Aç --</option>
</select>
<button class="file-btn btn-delete" onclick="deleteFromMemory()" title="Seçili metni hafızadan sil">🗑️</button>
<div style="width: 1px; height: 30px; background-color: #444; margin: 0 5px;"></div>
<button class="file-btn btn-import" onclick="document.getElementById('file-input').click()">📥 .txt İçe Aktar</button>
<input type="file" id="file-input" accept=".txt" style="display: none;" onchange="importFromFile(event)">
<button class="file-btn btn-export" onclick="exportToFile()">📤 .txt İndir</button>
</div>
<textarea id="text-input" placeholder="Prompter metnini buraya yapıştır veya üstten bir dosya / kayıtlı metin aç..."></textarea>
<button class="start-btn" onclick="startPrompter()">PROMPTER'A GEÇ</button>
</div>
<div id="prompter-screen">
<div class="marker marker-left"></div>
<div class="marker marker-right"></div>
<div id="text-container"></div>
<div id="controls">
<button class="ctrl-btn" id="edit-btn" onclick="goToEditor()">✎ Düzenle</button>
<button class="ctrl-btn" onclick="changeFont(-5)">A-</button>
<button class="ctrl-btn" onclick="changeFont(5)">A+</button>
<button class="ctrl-btn nav-btn" onclick="manualScroll(50)">▲ Yukarı</button>
<button class="ctrl-btn nav-btn" onclick="manualScroll(-50)">▼ Aşağı</button>
<button class="ctrl-btn" onclick="changeSpeed(-0.5)">Yavaş</button>
<button class="ctrl-btn" id="play-btn" onclick="togglePlay()">Start</button>
<button class="ctrl-btn" onclick="changeSpeed(0.5)">Hızlı</button>
<button class="ctrl-btn" onclick="toggleMirror()">Ayna</button>
<button class="ctrl-btn" id="fullscreen-btn" onclick="toggleFullscreen()">⛶ Tam Ekran</button>
</div>
</div>
<script>
let isPlaying = false;
let speed = 1.5;
let fontSize = 70;
let scrollPosition = 0;
let animationFrameId;
const textContainer = document.getElementById('text-container');
const prompterScreen = document.getElementById('prompter-screen');
const fullscreenBtn = document.getElementById('fullscreen-btn');
const textInput = document.getElementById('text-input');
const savedScriptsSelect = document.getElementById('saved-scripts');
// Sayfa yüklendiğinde hafızadaki metinleri listeye çek
window.onload = function() {
updateSavedScriptsList();
};
// --- HAFIZA (LOCALSTORAGE) İŞLEMLERİ ---
function saveToMemory() {
const text = textInput.value.trim();
if (!text) {
alert("Kaydetmek için önce bir metin yazmalısınız!");
return;
}
const name = prompt("Bu metin için kısa bir isim girin (Örn: Sahne 1, Röportaj vb.):");
if (!name) return;
let saved = JSON.parse(localStorage.getItem('gultekin_prompter_scripts') || '{}');
saved[name] = text;
localStorage.setItem('gultekin_prompter_scripts', JSON.stringify(saved));
updateSavedScriptsList();
savedScriptsSelect.value = name;
alert(`"${name}" başarıyla hafızaya kaydedildi!`);
}
function loadFromMemory() {
const selectedName = savedScriptsSelect.value;
if (!selectedName) return;
let saved = JSON.parse(localStorage.getItem('gultekin_prompter_scripts') || '{}');
if (saved[selectedName]) {
textInput.value = saved[selectedName];
}
}
function deleteFromMemory() {
const selectedName = savedScriptsSelect.value;
if (!selectedName) {
alert("Lütfen önce silmek istediğiniz metni listeden seçin.");
return;
}
if (confirm(`"${selectedName}" hafızadan silinecek. Emin misiniz?`)) {
let saved = JSON.parse(localStorage.getItem('gultekin_prompter_scripts') || '{}');
delete saved[selectedName];
localStorage.setItem('gultekin_prompter_scripts', JSON.stringify(saved));
updateSavedScriptsList();
textInput.value = "";
}
}
function updateSavedScriptsList() {
let saved = JSON.parse(localStorage.getItem('gultekin_prompter_scripts') || '{}');
savedScriptsSelect.innerHTML = '<option value="">-- Hafızadan Metin Seç / Aç --</option>';
for (let name in saved) {
let option = document.createElement('option');
option.value = name;
option.textContent = "📑 " + name;
savedScriptsSelect.appendChild(option);
}
}
// --- DOSYA (TXT) İÇE & DIŞA AKTARMA İŞLEMLERİ ---
function importFromFile(event) {
const file = event.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = function(e) {
textInput.value = e.target.result;
};
reader.readAsText(file);
}
function exportToFile() {
const text = textInput.value.trim();
if (!text) {
alert("İndirilecek bir metin bulunamadı!");
return;
}
const blob = new Blob([text], { type: 'text/plain;charset=utf-8' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'prompter-metni.txt';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
// --- PROMPTER KONTROL İŞLEMLERİ ---
function startPrompter() {
const text = textInput.value;
if (!text.trim()) {
alert("Lütfen önce bir metin girin veya hafızadan açın!");
return;
}
document.getElementById('editor-screen').style.display = 'none';
prompterScreen.style.display = 'block';
textContainer.innerText = text;
scrollPosition = window.innerHeight * 0.7;
textContainer.style.top = scrollPosition + 'px';
}
function goToEditor() {
if(isPlaying) togglePlay();
document.getElementById('editor-screen').style.display = 'flex';
prompterScreen.style.display = 'none';
}
function scrollText() {
if (isPlaying) {
scrollPosition -= speed;
textContainer.style.top = scrollPosition + 'px';
animationFrameId = requestAnimationFrame(scrollText);
}
}
function togglePlay() {
const playBtn = document.getElementById('play-btn');
isPlaying = !isPlaying;
if (isPlaying) {
playBtn.innerText = "Stop";
playBtn.classList.add("playing");
scrollText();
} else {
playBtn.innerText = "Start";
playBtn.classList.remove("playing");
cancelAnimationFrame(animationFrameId);
}
}
function manualScroll(amount) {
if (isPlaying) {
togglePlay();
}
scrollPosition += amount;
textContainer.style.top = scrollPosition + 'px';
}
function changeSpeed(amount) {
speed += amount;
if (speed < 0.5) speed = 0.5;
if (speed > 10) speed = 10;
const playBtn = document.getElementById('play-btn');
let oldText = playBtn.innerText;
playBtn.innerText = "Hız: " + speed.toFixed(1);
setTimeout(() => { playBtn.innerText = oldText; }, 1000);
}
function changeFont(amount) {
fontSize += amount;
if (fontSize < 30) fontSize = 30;
if (fontSize > 150) fontSize = 150;
textContainer.style.fontSize = fontSize + 'px';
}
function toggleMirror() {
textContainer.classList.toggle('mirrored');
}
function toggleFullscreen() {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen().then(() => {
fullscreenBtn.innerText = "🗗 Çıkış";
}).catch(err => {
alert(`Tam ekrana geçilemedi: ${err.message}`);
});
} else {
document.exitFullscreen().then(() => {
fullscreenBtn.innerText = "⛶ Tam Ekran";
});
}
}
document.addEventListener('fullscreenchange', () => {
if (!document.fullscreenElement) {
fullscreenBtn.innerText = "⛶ Tam Ekran";
} else {
fullscreenBtn.innerText = "🗗 Çıkış";
}
});
</script>
</body>
</html>