A React component that uses the Speech Synthesis API to read text out loud by sentence or word while the user follows along with their mouse or finger
The easiest way to use Readalong is to install it from NPM and include it in your own React build process (using Browserify, Webpack, etc).
You can also use the standalone build by including dist/react-readalong-component.js in your page. If you use this, make sure you have already included React, and it is available as a global variable.
npm install react-readalong-component --save
The component provides a single React element, Readalong
, that takes three properties and some text
content. The properties of lang
and delimiter
can be provided as attributes. The property
voiceName
should be passed after the browser registers the available Speech Synthesis voices. The
browser will use its default voice until a valid, different voice is passed. The component will attempt to choose a
default voice based on the passed lang
property, but this is hit-or-miss.
The output of the component receives three classes for use with styling. The outer wrapper has the class,
readalong
. Every readable phrase is wrapped in a span with the readalong-phrase
class.
While a phrase is being spoken, the corresponding span also receives a readalong-active
class. This
can be used, as in the examples below, to keep the phrase highlighted after the user moves off or releases her
finger.
It is advisable to make the font size as large as possible for the contents of a Readalong element. This is
especially true if the delimiter is set to word
.
This component depends on two experimental, draft APIs: Pointer Events and Speech Synthesis.
As of July 12, 2015, the Web Speech API is still an unofficial proposal. As such, right out of the box this component will only work in about half of all browsers. Those include recent versions of Chrome, Opera, and Safari. Ostensibly, iOS Safari is supported, but Speech Synthesis seems to work in that browser only sporadically. All other browsers will need a polyfill. There is no polyfill for Speech Synthesis currently installed on this demonstration page.
Again, as of the time of this commit, the Pointer Events API is very poorly supported across all browsers. Only IE and very late version Firefox have implemented it. There's no getting away without a polyfill for Pointer Events. They power the cursor/finger recognition. Fortunately, Google/jQuery have put together a fantastic polyfill called PEP, which is providing cross-browser capability for this page. It does not require jQuery as a dependency.
This component intentionally does not include polyfills. There are many polyfill options, and the one you choose
will depend on the needs of your project. The component also intentionally does check whether the Speech Synthesis
API is available. Readalong assumes that both window.speechSynthesis
and the
SpeechSynthesisUtterance
object are available, and that they are up-to-date with the unofficial
proposal.
The constants, regular expressions, and punctuation encoding used in this project were originally lifted from Blast.js, built by Julian Shapiro. These have been modified to fit the particular requirements of this project, including the addition of the Chinese punctuation.
This delimiter and voice selection form that is shown in some of the following examples is not
included in the Readalong component. Consult the DelimitedParagraph
component in the
examples directory for ideas about implementing something similar in your app.
Hover over or tap any word to hear it read out loud by your browser. The speech will continue even if the user moves away or releases her finger.
<Readalong lang="en-US" delimiter="word">
There once was an old woman who lived in a shoe.
She was underwater on her mortgage. What would she do?
</Readalong>
Readalong will ignore any text wrapped in an element with the silent
attribute.
<Readalong lang="en-US" delimiter="word">
<blockquote>
<p>
This sentence has five words. Here are five more words. Five-
word sentences are fine. But several together become monotonous.
Listen to what is happening. The writing is getting boring. The
sound of it drones. It’s like a stuck record. The ear
demands some variety. Now listen. I vary the sentence length,
and I create music. Music. The writing sings. It has a pleasant
rhythm, a lilt, a harmony. I use short sentences. And I use
sentences of medium length. And sometimes, when I am certain the
reader is rested, I will engage him with a sentence of
considerable length, a sentence that burns with energy and
builds with all the impetus of a crescendo, the roll of the
drums, the crash of the cymbals–sounds that say listen to
this, it is important.
</p>
<footer silent><cite>Gary Provost</cite></footer>
</blockquote>
</Readalong>
Readalong can process multiple blocks of text in the same component. Attributes on those inner elements will be passed through to the final output.
<Readalong lang="en-US" delimiter="word">
<p>
<span data-verse="1">In the beginning was the Word, and the
Word was with God, and the Word was God.</span> <span data-
<verse="2">The same was in the beginning with God.</span>
<span data-verse="3">All things were made through him.
Without him, nothing was made that has been made.</span>
<span data-verse="4">In him was life, and the life was the
light of men.</span> <span data-verse="5">The light shines in
the darkness, and the darkness hasn’t overcome it.</span>
</p>
<p>
<span data-verse="6">There came a man, sent from God, whose
name was John.</span> <span data-verse="7">The same came as
a witness, that he might testify about the light, that all
might believe through him.</span> <span data-verse="8">He was
not the light, but was sent that he might testify about the
light.</span> <span data-verse="9">The true light that
enlightens everyone was coming into the world.</span>
</p>
</Readalong>
Readalong supports any language that uses European or Chinese punctuation marks and is also supported by the browser's Speech Synthesis API.
<Readalong lang="es" delimiter="sentence">
<p>
En un lugar de la Mancha, de cuyo nombre no quiero acordarme,
no ha mucho tiempo que vivía un hidalgo de los de lanza en
astillero, adarga antigua, rocín flaco y galgo corredor. Una
olla de algo más vaca que carnero, salpicón las más noches,
duelos y quebrantos los sábados, lentejas los viernes, algún
palomino de añadidura los domingos, consumían las tres partes
de su hacienda. El resto della concluían sayo de velarte,
calzas de velludo para las fiestas con sus pantuflos de lo
mismo, los días de entre semana se honraba con su vellori de
lo más fino. Tenía en su casa una ama que pasaba de los
cuarenta, y una sobrina que no llegaba a los veinte, y un mozo
de campo y plaza, que así ensillaba el rocín como tomaba la
podadera. Frisaba la edad de nuestro hidalgo con los cincuenta
años, era de complexión recia, seco de carnes, enjuto de
rostro; gran madrugador y amigo de la caza. Quieren decir que
tenía el sobrenombre de Quijada o Quesada (que en esto hay
alguna diferencia en los autores que deste caso escriben),
aunque por conjeturas verosímiles se deja entender que se
llama Quijana; pero esto importa poco a nuestro cuento; basta
que en la narración dél no se salga un punto de la verdad.
</p>
</Readalong>
<Readalong lang="es" delimiter="sentence">
<p>
<i silent>1</i>太 初 有 道 , 道 与 神 同 在 , 道 就 是 神 。
<i silent>2</i>这 道 太 初 与 神 同 在 。 <i silent>3</i>万 物 是
藉 着 他 造 的 ; 凡 被 造 的 , 没 有 一 样 不 是 藉 着 他 造 的 。
<i silent>4</i>生 命 在 他 里 头 , 这 生 命 就 是 人 的 光 。
<i silent>5</i>光 照 在 黑 暗 里 , 黑 暗 却 不 接 受 光 。
<i silent>6</i>有 一 个 人 , 是 从 神 那 里 差 来 的 , 名 叫 约 翰 。
<i silent>7</i>这 人 来 , 为 要 作 见 证 , 就 是 为 光 作 见 证 ,
叫 众 人 因 他 可 以 信 。 <i silent>8</i>他 不 是 那 光 , 乃 是 要
为 光 作 见 证 。 <i silent>9</i>那 光 是 真 光 , 照 亮 一 切 生
在 世 上 的 人 。
</p>
</Readalong>