• 09-11-2025, 17:20:05
    #1
    Selam arkadaşlar,
    ALS hastası ablam için özel bir iletişim arayüzü geliştiriyorum.
    Bu sistemde fiziksel mouse tıklaması yok, sadece “dwell click” dediğimiz bir yöntem var — yani kullanıcı (göz takip cihazı ile) bir butonun üstünde 1–2 saniye gözünü tutunca tıklama olayı simüle ediliyor.

    Sayfa ilk açıldığında dwell click ile (yani fiziksel tıklama olmadan) speechSynthesis.speak() hiçbir ses üretmiyor.
    Ama bir kere fiziksel mouse tıklaması yaptıktan sonra her dwell click düzgün çalışıyor.
    Yani tarayıcı (özellikle Chrome ve Edge) ses sistemini ancak ilk fiziksel etkileşim sonrası aktif ediyor.

    yapay zekaların hiçbiri yapamadı... bu test üzerinde gösterebilecek var mı?



    <!DOCTYPE html>
    <html lang="tr">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TEST 3 - Manuel Event + Focus Hack</title>
    <style>
    body {
    font-family: Arial, sans-serif;
    margin: 40px;
    background: #f0f0f0;
    }

    .container {
    max-width: 600px;
    margin: 0 auto;
    background: white;
    padding: 20px;
    border-radius: 10px;
    box-shadow: 0 2px 10px rgba(0,0,0,0.1);
    }

    .text-area {
    width: 100%;
    height: 100px;
    margin: 20px 0;
    padding: 10px;
    font-size: 16px;
    border: 2px solid #ddd;
    border-radius: 5px;
    resize: vertical;
    }

    .buttons {
    display: flex;
    gap: 20px;
    margin: 20px 0;
    }

    .test-btn {
    flex: 1;
    padding: 15px;
    font-size: 16px;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    background: #4CAF50;
    color: white;
    font-weight: bold;
    }

    .sound-btn {
    flex: 1;
    padding: 15px;
    font-size: 16px;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    background: #2196F3;
    color: white;
    font-weight: bold;
    }

    .dwell-active {
    background: #ff9800 !important;
    }

    .dwell-progress {
    position: absolute;
    bottom: 0;
    left: 0;
    height: 4px;
    background: #ff5722;
    width: 0%;
    transition: width 1s linear;
    }

    .speaking {
    background: #f44336 !important;
    animation: pulse 1.5s infinite;
    }

    @keyframes pulse {
    0% { opacity: 1; }
    50% { opacity: 0.7; }
    100% { opacity: 1; }
    }

    .status {
    margin-top: 20px;
    padding: 10px;
    background: #e0e0e0;
    border-radius: 5px;
    font-family: monospace;
    }

    button {
    position: relative;
    overflow: hidden;
    }
    </style>
    </head>
    <body>
    <div class="container">
    <h1>TEST 3 - Manuel Event + Focus Hack</h1>

    <textarea class="text-area" id="textArea">Test metni buraya yazılacak...</textarea>

    <div class="buttons">
    <button class="test-btn" id="testBtn">TEST BUTONU</button>
    <button class="sound-btn" id="soundBtn">🔊 SES</button>
    </div>

    <div class="status" id="status">
    Durum: Fareyi butonlara getirip dwell ile tıklayın
    </div>

    <div style="margin-top: 20px; padding: 15px; background: #fff3cd; border-radius: 5px;">
    <h3>TEST 3 Talimatları:</h3>
    <ol>
    <li>Fareyi TEST BUTONU üzerine getirip 2.2 saniye bekleyin</li>
    <li>Fareyi SES butonu üzerine getirip 2.2 saniye bekleyin</li>
    <li>Bu test Manuel Event Trigger + Focus Hack kullanıyor</li>
    </ol>
    </div>
    </div>

    <script>
    // ===== DEĞİŞKENLER =====
    const textArea = document.getElementById('textArea');
    const testBtn = document.getElementById('testBtn');
    const soundBtn = document.getElementById('soundBtn');
    const statusDiv = document.getElementById('status');

    let speechState = {
    isSpeaking: false,
    currentUtterance: null
    };

    let dwellState = {
    currentButton: null,
    areaTimer: null,
    dwellTimer: null,
    isInDwell: false
    };

    // ===== MANUEL SES SİSTEMİ =====
    function speakTextManually() {
    updateStatus('MANUEL SES FONKSİYONU ÇAĞRILDI');

    if (speechState.isSpeaking) {
    updateStatus('Zaten konuşuyor');
    return;
    }

    const text = textArea.value;
    if (!text.trim()) {
    updateStatus('Okunacak metin yok');
    return;
    }

    updateStatus('MANUEL seslendirme başlatılıyor...');
    speechState.isSpeaking = true;
    soundBtn.classList.add('speaking');
    soundBtn.disabled = true;

    try {
    // Önce tarayıcıya focus ver
    textArea.focus();

    // Kısa bir timeout ile sesi başlat
    setTimeout(() => {
    speechState.currentUtterance = new SpeechSynthesisUtterance(text);
    speechState.currentUtterance.lang = 'tr-TR';

    speechState.currentUtterance.onstart = function() {
    updateStatus('MANUEL Seslendirme BAŞLADI');
    };

    speechState.currentUtterance.onend = function() {
    updateStatus('MANUEL Seslendirme TAMAMLANDI');
    speechState.isSpeaking = false;
    speechState.currentUtterance = null;
    soundBtn.classList.remove('speaking');
    soundBtn.disabled = false;
    };

    speechState.currentUtterance.onerror = function(event) {
    updateStatus('MANUEL SES HATASI: ' + event.error);
    speechState.isSpeaking = false;
    speechState.currentUtterance = null;
    soundBtn.classList.remove('speaking');
    soundBtn.disabled = false;
    };

    window.speechSynthesis.speak(speechState.currentUt terance);
    }, 100);

    } catch (error) {
    updateStatus('MANUEL SES SİSTEMİ HATASI: ' + error.message);
    speechState.isSpeaking = false;
    soundBtn.classList.remove('speaking');
    soundBtn.disabled = false;
    }
    }

    // ===== DWELL SİSTEMİ =====
    function startDwell(button) {
    if (dwellState.isInDwell && dwellState.currentButton === button) return;

    stopAllTimers();
    dwellState.currentButton = button;

    updateStatus(`Dwell başlatıldı: ${button.textContent}`);

    // AREA DELAY - 1000ms
    dwellState.areaTimer = setTimeout(() => {
    dwellState.isInDwell = true;
    button.classList.add('dwell-active');

    const progress = document.createElement('div');
    progress.className = 'dwell-progress';
    button.appendChild(progress);

    updateStatus(`Dwell aktif: ${button.textContent} - 1.2s sonra tıklanacak`);

    // DWELL SÜRESİ - 1200ms
    dwellState.dwellTimer = setTimeout(() => {
    updateStatus(`DWELL TIKLAMA: ${button.textContent}`);

    // BUTON TİPİNE GÖRE MANUEL FONKSİYON ÇAĞIR
    if (button.id === 'soundBtn') {
    speakTextManually(); // DOĞRUDAN MANUEL FONKSİYON
    } else {
    // Diğer butonlar için normal işlem
    const timestamp = new Date().toLocaleTimeString();
    const newText = `Test tıklandı - ${timestamp}n`;
    textArea.value += newText;
    updateStatus(`Test butonu dwell ile tıklandı: ${timestamp}`);
    }

    button.classList.remove('dwell-active');
    if (progress.parentElement) {
    progress.remove();
    }
    dwellState.isInDwell = false;

    }, 1200);

    // Progress bar animasyonu
    setTimeout(() => {
    if (progress.parentElement) {
    progress.style.width = '100%';
    }
    }, 10);

    }, 1000);
    }

    function stopAllTimers() {
    if (dwellState.areaTimer) {
    clearTimeout(dwellState.areaTimer);
    dwellState.areaTimer = null;
    }
    if (dwellState.dwellTimer) {
    clearTimeout(dwellState.dwellTimer);
    dwellState.dwellTimer = null;
    }

    if (dwellState.currentButton && dwellState.isInDwell) {
    dwellState.currentButton.classList.remove('dwell-active');
    const progress = dwellState.currentButton.querySelector('.dwell-progress');
    if (progress) progress.remove();
    dwellState.isInDwell = false;
    }
    }

    // ===== EVENT LISTENER'LAR =====
    // NORMAL CLICK EVENT'LERİ (karşılaştırma için)
    testBtn.addEventListener('click', function() {
    const timestamp = new Date().toLocaleTimeString();
    const newText = `NORMAL Test tıklandı - ${timestamp}n`;
    textArea.value += newText;
    updateStatus(`NORMAL Test butonu tıklandı: ${timestamp}`);
    });

    soundBtn.addEventListener('click', function() {
    updateStatus('NORMAL SES BUTONU TIKLANDI');
    speakTextManually();
    });

    // Dwell event'leri
    [testBtn, soundBtn].forEach(button => {
    button.addEventListener('mouseenter', () => {
    startDwell(button);
    });

    button.addEventListener('mouseleave', () => {
    if (dwellState.currentButton === button) {
    updateStatus(`Dwell iptal: ${button.textContent}`);
    stopAllTimers();
    dwellState.currentButton = null;
    }
    });
    });

    // ===== YARDIMCI FONKSİYONLAR =====
    function updateStatus(message) {
    statusDiv.textContent = `Durum: ${message}`;
    console.log(`STATUS: ${message}`);
    }

    // Sayfa kaybolduğunda temizle
    document.addEventListener('visibilitychange', stopAllTimers);
    window.addEventListener('blur', stopAllTimers);

    // Sayfa yüklendiğinde
    window.addEventListener('load', () => {
    textArea.focus();
    updateStatus('TEST 3 hazır - Manuel Event + Focus Hack');
    });
    </script>
    </body>
    </html>



    çalıştırmak istediğim asıl arayüz bunun gibi... alterantif olarak ne önerirsiniz.
  • 09-11-2025, 17:40:31
    #2
    Selamlar. Sizi daha önce de görmüştüm forumda, benzer bir kod problemi vardı. konuyu kaybetmiştim arasam da bulamamıştım. Yanlış anlamazsanız istanbuldaysanız sizinle tanışıp yüz yüze görüşüp yardımcı olmak ve bu projenizde elimden geldiğince ücretsiz destek olmak isterim.
    Şu anki kodda tarayıcı güvenlik politikalarından dolayı olduğunu düşünüyorum, farklı alternatiflerle çözülebilir hatta çok gelişmiş bir şey yapılabilir.
    Kod olarak da bunu dener misiniz, sayfa yüklendiğinde otomatik olarak ses sistemini aktif etmeye çalıştım :
    <!DOCTYPE html>
    <html lang="tr">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TEST 3 - Manuel Event + Focus Hack</title>
    <style>
    body {
    font-family: Arial, sans-serif;
    margin: 40px;
    background: #f0f0f0;
    }
    
    .container {
    max-width: 600px;
    margin: 0 auto;
    background: white;
    padding: 20px;
    border-radius: 10px;
    box-shadow: 0 2px 10px rgba(0,0,0,0.1);
    }
    
    .text-area {
    width: 100%;
    height: 100px;
    margin: 20px 0;
    padding: 10px;
    font-size: 16px;
    border: 2px solid #ddd;
    border-radius: 5px;
    resize: vertical;
    }
    
    .buttons {
    display: flex;
    gap: 20px;
    margin: 20px 0;
    }
    
    .test-btn {
    flex: 1;
    padding: 15px;
    font-size: 16px;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    background: #4CAF50;
    color: white;
    font-weight: bold;
    }
    
    .sound-btn {
    flex: 1;
    padding: 15px;
    font-size: 16px;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    background: #2196F3;
    color: white;
    font-weight: bold;
    }
    
    .dwell-active {
    background: #ff9800 !important;
    }
    
    .dwell-progress {
    position: absolute;
    bottom: 0;
    left: 0;
    height: 4px;
    background: #ff5722;
    width: 0%;
    transition: width 1s linear;
    }
    
    .speaking {
    background: #f44336 !important;
    animation: pulse 1.5s infinite;
    }
    
    @keyframes pulse {
    0% { opacity: 1; }
    50% { opacity: 0.7; }
    100% { opacity: 1; }
    }
    
    .status {
    margin-top: 20px;
    padding: 10px;
    background: #e0e0e0;
    border-radius: 5px;
    font-family: monospace;
    }
    
    button {
    position: relative;
    overflow: hidden;
    }
    
    .ses-aktif-btn {
    width: 100%;
    padding: 20px;
    font-size: 18px;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    background: #ff5722;
    color: white;
    font-weight: bold;
    margin-bottom: 20px;
    }
    
    .ses-aktif-btn.aktif {
    background: #4CAF50;
    }
    </style>
    </head>
    <body>
    <div class="container">
    <h1>TEST 3 - Manuel Event + Focus Hack</h1>
    
    <button class="ses-aktif-btn" id="sesAktifBtn">SES SİSTEMİNİ AKTİF ET</button>
    
    <textarea class="text-area" id="textArea">Test metni buraya yazılacak...</textarea>
    
    <div class="buttons">
    <button class="test-btn" id="testBtn">TEST BUTONU</button>
    <button class="sound-btn" id="soundBtn">🔊 SES</button>
    </div>
    
    <div class="status" id="status">
    Durum: Fareyi butonlara getirip dwell ile tıklayın
    </div>
    
    <div style="margin-top: 20px; padding: 15px; background: #fff3cd; border-radius: 5px;">
    <h3>TEST 3 Talimatları:</h3>
    <ol>
    <li>Önce "SES SİSTEMİNİ AKTİF ET" butonuna fareyi 2.2 saniye tutun</li>
    <li>Fareyi TEST BUTONU üzerine getirip 2.2 saniye bekleyin</li>
    <li>Fareyi SES butonu üzerine getirip 2.2 saniye bekleyin</li>
    </ol>
    </div>
    </div>
    
    <script>
    // ===== DEĞİŞKENLER =====
    const textArea = document.getElementById('textArea');
    const testBtn = document.getElementById('testBtn');
    const soundBtn = document.getElementById('soundBtn');
    const statusDiv = document.getElementById('status');
    const sesAktifBtn = document.getElementById('sesAktifBtn');
    
    let speechState = {
    isSpeaking: false,
    currentUtterance: null
    };
    
    let dwellState = {
    currentButton: null,
    areaTimer: null,
    dwellTimer: null,
    isInDwell: false
    };
    
    let sesAktifMi = false;
    let audioContext = null;
    
    // ===== SES SİSTEMİNİ AKTİF ETME =====
    function sesSisteminiAktifEt() {
    if (sesAktifMi) {
    updateStatus('Ses sistemi zaten aktif');
    return;
    }
        
    try {
    // AudioContext oluştur
    if (!audioContext) {
    audioContext = new (window.AudioContext || window.webkitAudioContext)();
    }
            
    // AudioContext'i başlat
    if (audioContext.state === 'suspended') {
    audioContext.resume();
    }
            
    // Sessiz ses çal
    const sessizSes = new SpeechSynthesisUtterance('');
    sessizSes.volume = 0.001;
    sessizSes.rate = 10;
    window.speechSynthesis.speak(sessizSes);
            
    // Kısa bir test sesi çal
    setTimeout(() => {
    const testSes = new SpeechSynthesisUtterance('Ses sistemi aktif');
    testSes.lang = 'tr-TR';
    testSes.volume = 0.1;
    window.speechSynthesis.speak(testSes);
    }, 100);
            
    sesAktifMi = true;
    sesAktifBtn.textContent = 'SES SİSTEMİ AKTİF';
    sesAktifBtn.classList.add('aktif');
    updateStatus('Ses sistemi başarıyla aktif edildi');
            
    } catch (error) {
    updateStatus('Ses sistemi aktif edilemedi: ' + error.message);
    }
    }
    
    // ===== OTOMATİK AKTİVASYON DENEMESİ =====
    function otomatikSesAktivasyon() {
    try {
    // AudioContext oluştur
    if (!audioContext) {
    audioContext = new (window.AudioContext || window.webkitAudioContext)();
    }
            
    // Gizli iframe ile ses başlatma
    const iframe = document.createElement('iframe');
    iframe.style.display = 'none';
    document.body.appendChild(iframe);
            
    const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
    iframeDoc.open();
    iframeDoc.write(`
    <script>
    const sessizSes = new SpeechSynthesisUtterance('');
    sessizSes.volume = 0.001;
    window.speechSynthesis.speak(sessizSes);
    <\/script>
    `);
    iframeDoc.close();
            
    setTimeout(() => {
    document.body.removeChild(iframe);
    }, 100);
            
    } catch (error) {
    console.log('Otomatik aktivasyon başarısız:', error);
    }
    }
    
    // ===== MANUEL SES SİSTEMİ =====
    function speakTextManually() {
    updateStatus('MANUEL SES FONKSİYONU ÇAĞRILDI');
    
    if (speechState.isSpeaking) {
    updateStatus('Zaten konuşuyor');
    return;
    }
    
    const text = textArea.value;
    if (!text.trim()) {
    updateStatus('Okunacak metin yok');
    return;
    }
        
    // Ses sistemi aktif değilse önce aktif et
    if (!sesAktifMi) {
    sesSisteminiAktifEt();
    setTimeout(() => {
    if (sesAktifMi) {
    speakTextManually();
    }
    }, 500);
    return;
    }
    
    updateStatus('MANUEL seslendirme başlatılıyor...');
    speechState.isSpeaking = true;
    soundBtn.classList.add('speaking');
    soundBtn.disabled = true;
    
    try {
    // AudioContext'i kontrol et
    if (audioContext && audioContext.state === 'suspended') {
    audioContext.resume();
    }
            
    // Önce tarayıcıya focus ver
    textArea.focus();
    
    // Kısa bir timeout ile sesi başlat
    setTimeout(() => {
    speechState.currentUtterance = new SpeechSynthesisUtterance(text);
    speechState.currentUtterance.lang = 'tr-TR';
    
    speechState.currentUtterance.onstart = function() {
    updateStatus('MANUEL Seslendirme BAŞLADI');
    };
    
    speechState.currentUtterance.onend = function() {
    updateStatus('MANUEL Seslendirme TAMAMLANDI');
    speechState.isSpeaking = false;
    speechState.currentUtterance = null;
    soundBtn.classList.remove('speaking');
    soundBtn.disabled = false;
    };
    
    speechState.currentUtterance.onerror = function(event) {
    updateStatus('MANUEL SES HATASI: ' + event.error);
    speechState.isSpeaking = false;
    speechState.currentUtterance = null;
    soundBtn.classList.remove('speaking');
    soundBtn.disabled = false;
    };
    
    window.speechSynthesis.speak(speechState.currentUtterance);
    }, 100);
    
    } catch (error) {
    updateStatus('MANUEL SES SİSTEMİ HATASI: ' + error.message);
    speechState.isSpeaking = false;
    soundBtn.classList.remove('speaking');
    soundBtn.disabled = false;
    }
    }
    
    // ===== DWELL SİSTEMİ =====
    function startDwell(button) {
    if (dwellState.isInDwell && dwellState.currentButton === button) return;
    
    stopAllTimers();
    dwellState.currentButton = button;
    
    updateStatus(`Dwell başlatıldı: ${button.textContent}`);
    
    // AREA DELAY - 1000ms
    dwellState.areaTimer = setTimeout(() => {
    dwellState.isInDwell = true;
    button.classList.add('dwell-active');
    
    const progress = document.createElement('div');
    progress.className = 'dwell-progress';
    button.appendChild(progress);
    
    updateStatus(`Dwell aktif: ${button.textContent} - 1.2s sonra tıklanacak`);
    
    // DWELL SÜRESİ - 1200ms
    dwellState.dwellTimer = setTimeout(() => {
    updateStatus(`DWELL TIKLAMA: ${button.textContent}`);
    
    // BUTON TİPİNE GÖRE MANUEL FONKSİYON ÇAĞIR
    if (button.id === 'soundBtn') {
    speakTextManually(); // DOĞRUDAN MANUEL FONKSİYON
    } else if (button.id === 'sesAktifBtn') {
    sesSisteminiAktifEt();
    } else {
    // Diğer butonlar için normal işlem
    const timestamp = new Date().toLocaleTimeString();
    const newText = `Test tıklandı - ${timestamp}\n`;
    textArea.value += newText;
    updateStatus(`Test butonu dwell ile tıklandı: ${timestamp}`);
    }
    
    button.classList.remove('dwell-active');
    if (progress.parentElement) {
    progress.remove();
    }
    dwellState.isInDwell = false;
    
    }, 1200);
    
    // Progress bar animasyonu
    setTimeout(() => {
    if (progress.parentElement) {
    progress.style.width = '100%';
    }
    }, 10);
    
    }, 1000);
    }
    
    function stopAllTimers() {
    if (dwellState.areaTimer) {
    clearTimeout(dwellState.areaTimer);
    dwellState.areaTimer = null;
    }
    if (dwellState.dwellTimer) {
    clearTimeout(dwellState.dwellTimer);
    dwellState.dwellTimer = null;
    }
    
    if (dwellState.currentButton && dwellState.isInDwell) {
    dwellState.currentButton.classList.remove('dwell-active');
    const progress = dwellState.currentButton.querySelector('.dwell-progress');
    if (progress) progress.remove();
    dwellState.isInDwell = false;
    }
    }
    
    // ===== EVENT LISTENER'LAR =====
    // NORMAL CLICK EVENT'LERİ (karşılaştırma için)
    testBtn.addEventListener('click', function() {
    const timestamp = new Date().toLocaleTimeString();
    const newText = `NORMAL Test tıklandı - ${timestamp}\n`;
    textArea.value += newText;
    updateStatus(`NORMAL Test butonu tıklandı: ${timestamp}`);
    });
    
    soundBtn.addEventListener('click', function() {
    updateStatus('NORMAL SES BUTONU TIKLANDI');
    speakTextManually();
    });
    
    sesAktifBtn.addEventListener('click', function() {
    sesSisteminiAktifEt();
    });
    
    // Dwell event'leri
    [testBtn, soundBtn, sesAktifBtn].forEach(button => {
    button.addEventListener('mouseenter', () => {
    startDwell(button);
    });
    
    button.addEventListener('mouseleave', () => {
    if (dwellState.currentButton === button) {
    updateStatus(`Dwell iptal: ${button.textContent}`);
    stopAllTimers();
    dwellState.currentButton = null;
    }
    });
    });
    
    // ===== YARDIMCI FONKSİYONLAR =====
    function updateStatus(message) {
    statusDiv.textContent = `Durum: ${message}`;
    console.log(`STATUS: ${message}`);
    }
    
    // Sayfa kaybolduğunda temizle
    document.addEventListener('visibilitychange', stopAllTimers);
    window.addEventListener('blur', stopAllTimers);
    
    // Sayfa yüklendiğinde
    window.addEventListener('load', () => {
    textArea.focus();
        
    // Otomatik ses aktivasyonu dene
    otomatikSesAktivasyon();
        
    // Mouse hareketi ile aktivasyon dene
    document.addEventListener('mousemove', function etkinlestir() {
    if (!sesAktifMi) {
    try {
    const sessizSes = new SpeechSynthesisUtterance('');
    sessizSes.volume = 0.001;
    window.speechSynthesis.speak(sessizSes);
                    
    if (audioContext && audioContext.state === 'suspended') {
    audioContext.resume();
    }
    } catch (e) {
    console.log('Mouse hareketi ile aktivasyon başarısız');
    }
    }
    }, { once: true });
        
    updateStatus('TEST 3 hazır - Manuel Event + Focus Hack');
    });
    </script>
    </body>
    </html>