Idioma

Entrar em contacto

Aplicação Android · desde 2024

FlashReader

Leitor que mostra um ficheiro de texto uma palavra de cada vez, ao ritmo que definir, e lembra-se de onde parou.

Publicado
Dados recolhidos
Nenhuma
Preço
Grátis
  • HTML
  • CSS
  • JavaScript
  • IndexedDB
  • localStorage
  • FileReader API
  • Fullscreen API
  • Cordova Fullscreen plugin (opcional)
Google Play play.google.com

Sobre

O FlashReader abre um ficheiro .txt local e mostra-o uma palavra de cada vez no meio do ecrã, por omissão a cada 500 ms. O leitor define o intervalo, o tamanho das letras, a cor das letras e a cor do fundo. O texto completo e a posição da palavra ficam no dispositivo, pelo que, após um reinício, o mesmo ficheiro reabre na mesma palavra.

Esta página descreve a versão web em flashreader.fun: uma página HTML com JavaScript embebido. O script não faz pedidos de rede e não tem análise de tráfego. A aplicação Android no Google Play é uma versão separada, cujo código-fonte não é abordado aqui.

A engenharia é pequena e específica: um temporizador que consegue mudar de ritmo sem perder a palavra, um armazenamento que sobrevive a um reinício e definições que são aplicadas e guardadas no momento em que mudam.

FlashReader · leitura focada

o que foi resolvido

ATIVOdesde 2024

Ciclo de palavras

no produto

O que ofereceO utilizador escolhe um ficheiro de texto e lê-o palavra a palavra a um ritmo regular, e pode mudar a velocidade a meio do texto sem perder o sítio onde ia.

Problema
As palavras têm de mudar a um intervalo regular definido pelo utilizador, e o intervalo tem de poder ser alterado a meio de um texto sem perder a palavra atual.
Solução

Um temporizador de intervalo percorre um índice sobre um array de palavras. Uma mudança de velocidade pára esse temporizador e inicia outro a partir do mesmo índice.

Stack
  • JavaScript
  • setInterval
  • FileReader API
Tarefas · 4
Transformar um ficheiro de texto escolhido numa sequência de palavrasLer o ficheiro como UTF-8 com FileReader e dividi-lo por espaços num array

O ficheiro vem de um input de ficheiro padrão limitado a .txt, pelo que a página não precisa de acesso ao sistema de ficheiros. action_load_file() lê-o com readAsText(file, 'UTF-8') e divide o resultado por espaços simples; a pontuação fica com a sua palavra. O texto bruto é também entregue a saveFileContent() para a sessão seguinte.

Mostrar uma palavra por tick e nunca ter dois temporizadores em simultâneoread() termina se já houver um temporizador a correr; cada tick mostra uma palavra e guarda o índice seguinte

read() recusa-se a arrancar sem texto carregado ('Load text file to read!') e termina de imediato quando is_going está definido, pelo que carregar em play duas vezes não pode iniciar um segundo intervalo. Cada tick escreve text[position] em #text-zone e guarda position + 1. togglePlayPause() alterna entre read() e pause() e atualiza o botão de play.

Uma mudança de velocidade a meio da leitura tem de se aplicar de imediatoParar e reiniciar o intervalo com o novo período, mantendo o índice da palavra

setInterval não consegue mudar o seu período. updateReadingSpeed() e o handler de change do campo de velocidade chamam pause() e depois read() quando a leitura está ativa. O índice vive no objeto do leitor, pelo que o temporizador reiniciado continua com a palavra seguinte. Um valor escrito abaixo de 1 é reposto no valor por omissão de 500 ms.

Fim do texto: parar de forma limpa ou recomeçarNo fim, ou parar com 'THE END!' e voltar à palavra 0, ou regressar à palavra 0

O tick verifica se há uma palavra indefinida no índice atual. Com Loop desligado, limpa o temporizador, mostra 'THE END!', guarda a posição 0 e repõe o botão de play. Com Loop ligado, define o índice a 0 e continua. A escolha de Loop é guardada como as restantes definições.

Retomar após reinício

no produto

O que ofereceFeche a aplicação e volte mais tarde: o mesmo texto abre na mesma palavra, com o mesmo tamanho de letra e velocidade, tudo guardado no dispositivo.

Problema
O texto completo, a posição da palavra e as definições de visualização têm de sobreviver ao fecho da página ou da aplicação, sem servidor.
Solução

O texto vai para o IndexedDB, a posição e as definições para o localStorage, e ambos são lidos de novo no arranque.

Stack
  • IndexedDB
  • localStorage
Tarefas · 3
Um livro inteiro não pertence ao localStorageGuardar o texto bruto no IndexedDB sob uma chave fixa; manter os valores pequenos no localStorage

saveFileContent() coloca o texto no store 'files' da base de dados 'flashreader' (versão 2) com o id 'flashreader_last_text', pelo que um ficheiro novo substitui o anterior. onupgradeneeded cria o store apenas se estiver em falta, pelo que abrir sobre uma versão mais antiga não falha.

Posição, cores, tamanho, velocidade, loop e o nome do ficheiro ficam no localStorage, onde as leituras no arranque são síncronas.

Reabrir o último ficheiro na palavra onde a leitura parouGuardar o índice a cada palavra mostrada; no arranque, recarregar o texto e esse índice

set_position() escreve o índice no localStorage (fr_position) a cada tick, pelo que uma aplicação fechada ou terminada perde no máximo uma palavra. O construtor lê primeiro o índice; em DOMContentLoaded, getFileContent() carrega o texto do IndexedDB, divide-o de novo e mostra 'The last file, <name>, has been loaded' com um pedido para carregar em play.

Os valores guardados podem faltar ou estar corrompidosRestaurar cada valor por si, com valores de recurso: posição 0, tamanho 48 px, velocidade 500 ms

Cada chave é lida e aplicada em separado, pelo que um valor mau não bloqueia os restantes. Uma posição não numérica passa a 0, um tamanho de letra que resulta em 0 volta a 48 px, uma velocidade que resulta em 0 volta a 500 ms. As cores são guardadas sem '#' e restauradas com ele, e depois aplicadas ao texto e ao fundo da página.

Visualização e controlos

no produto

O que ofereceO tamanho das letras e as cores mudam durante a leitura, os atalhos de teclado controlam a reprodução num navegador, e o leitor pode recuar dez palavras ou saltar para qualquer palavra.

Problema
O tamanho das letras e as cores têm de mudar durante a leitura e, num navegador de desktop, a reprodução deve poder ser controlada pelo teclado.
Solução

Os campos da barra de ferramentas aplicam e guardam cada alteração de imediato; no navegador, os atalhos de teclado chamam os mesmos métodos do leitor.

Stack
  • JavaScript
  • Keyboard Events
  • Fullscreen API
Tarefas · 4
O tamanho das letras e as cores têm de se aplicar de imediato e persistirOs handlers de change definem o estilo diretamente e guardam o valor; um tamanho abaixo de 8 px passa a 8

O handler da cor da letra define a cor do texto de #text-zone, o handler do fundo define o fundo do body, e o handler do tamanho define font-size em px com um mínimo de 8. Cada handler escreve o seu valor no localStorage no mesmo passo, pelo que não existe uma ação de gravação separada.

No navegador, o controlo por teclado não pode deslocar a página durante a leituraEspaço, F, Cima e Baixo chamam ações do leitor e cancelam o comportamento por omissão do navegador

Na versão para navegador, Espaço alterna entre play e pausa, F alterna o ecrã completo, Cima torna as palavras mais rápidas em 10 ms com um mínimo de 50 ms, Baixo mais lentas em 10 ms. preventDefault() impede o navegador de deslocar a página ou de acionar um controlo com foco. As mudanças de velocidade passam por updateReadingSpeed(), pelo que um temporizador em execução reinicia ao novo ritmo.

O leitor perdeu algumas palavras e quer voltar atrásA seta para a esquerda (navegador) recua 10 palavras, limitado a 0; o campo de posição salta para qualquer palavra

skipBackwards() recua o índice 10 posições, nunca abaixo de 0, mostra essa palavra de imediato e guarda a posição. O campo de posição na barra de ferramentas aceita qualquer número de palavra; os valores negativos passam a 0.

O ecrã completo funciona de forma diferente entre navegadores e invólucros de aplicaçãoTentar as Fullscreen APIs padrão e com prefixo, e depois um plugin Cordova Fullscreen se a página encontrar um

enterFullscreen() e exitFullscreen() percorrem as variantes standard, moz, webkit e ms. Quando existe um objeto global Fullscreen, como com um plugin Cordova de ecrã completo, Fullscreen.show() também é chamado. O botão e a tecla F partilham a mesma verificação das quatro variantes de fullscreenElement.

Números

do produto
  • Ritmo por omissão 500 ms por palavra 120 palavras por minuto.
  • Ritmo mais rápido 50 ms por palavra Até 1,200 palavras por minuto a partir do teclado.
  • Passo de velocidade 10 ms Teclas de seta para cima e para baixo.