This JavaScript sample has text to speech accessibility feature for the visually impaired
1let voiceIndex = 0;
2let pitch = 1;
3let rate = 1;
4let volume = 1;
5
6window.onbeforeunload = () => {
7  if (speechSynthesis) {
8    speechSynthesis.cancel();
9  }
10};
11
12const readText = documentText => {
13  const utterance = new SpeechSynthesisUtterance(documentText);
14  if (voiceIndex) {
15    utterance.voice = speechSynthesis.getVoices()[voiceIndex];
16  }
17  utterance.pitch = pitch;
18  utterance.rate = rate;
19  utterance.volume = volume;
20  if (speechSynthesis.speaking) {
21    speechSynthesis.resume();
22  } else {
23    speechSynthesis.speak(utterance);
24  }
25};
26
27const pauseText = () => {
28  speechSynthesis.pause();
29};
30
31const addVoices = () => {
32  for (let i = 0; i < speechSynthesis.getVoices().length; i++) {
33    const voice = speechSynthesis.getVoices()[i];
34    const option = document.createElement('option');
35    // eslint-disable-next-line
36    option.textContent = `${voice.voiceURI}-${voice.lang}`;
37    option.value = i;
38    document.getElementById('voice').appendChild(option);
39  }
40};
41
42// Instantiate
43// eslint-disable-next-line no-undef
44const WebViewerConstructor = isWebComponent() ? WebViewer.WebComponent : WebViewer;
45WebViewerConstructor(
46  {
47    path: '../../../lib',
48    initialDoc: '../../../samples/files/cheetahs.pdf',
49    accessibleMode: true,
50  },
51  document.getElementById('viewer')
52).then(instance => {
53  samplesSetup(instance);
54  const documentViewer = instance.Core.documentViewer;
55  // eslint-disable-next-line no-undef
56  const iframeDocument = isWebComponent() ? document.getElementsByTagName('apryse-webviewer')[0].shadowRoot : instance.UI.iframeWindow.document;
57
58  const getPageText = pageNumber => {
59    const pageTextElement = iframeDocument.getElementById(`pageText${pageNumber}`);
60    return pageTextElement ? pageTextElement.innerText : null;
61  };
62
63  let intervalId;
64  const readDocumentText = () => {
65    speechSynthesis.cancel();
66    clearInterval(intervalId);
67    // setInterval used in case text DOM is not ready yet
68    intervalId = setInterval(() => {
69      const text = getPageText(documentViewer.getCurrentPage());
70
71      if (text) {
72        readText(text);
73        clearInterval(intervalId);
74      }
75    }, 200);
76  };
77
78  documentViewer.addEventListener('documentLoaded', () => {
79    const playButton = document.getElementById('play');
80    const pauseButton = document.getElementById('pause');
81
82    iframeDocument.addEventListener('keydown', e => {
83      if (e.key === 'Tab' || e.keycode === 9) {
84        speechSynthesis.cancel();
85      }
86      if (e.key === 'p' || e.keycode === 80) {
87        readDocumentText();
88      }
89    });
90
91    const voiceList = window.speechSynthesis.getVoices();
92    if (voiceList.length) {
93      addVoices();
94    } else {
95      window.speechSynthesis.onvoiceschanged = addVoices;
96    }
97
98    playButton.onclick = readDocumentText;
99    pauseButton.onclick = pauseText;
100  });
101});
102
103const isIE11 = !!window.MSInputMethodContext && !!document.documentMode;
104
105// SpeechSynthesis is not supported in IE11
106if (isIE11) {
107  window.alert('SpeechSynthesis is not supported in IE11.\nPlease try a different browser.');
108  const aside = document.getElementsByTagName('aside')[0];
109  while (aside.firstChild) {
110    aside.removeChild(aside.firstChild);
111  }
112  const warningMessage = document.createTextNode('This demo is not compatible with IE11. Please open the demo in a different browser or ');
113  const returnLink = document.createElement('a');
114  const returnText = document.createTextNode('go back to samples');
115  returnLink.setAttribute('href', '../');
116  returnLink.setAttribute('target', '_self');
117  aside.appendChild(warningMessage);
118  returnLink.appendChild(returnText);
119  aside.appendChild(returnLink);
120}
121
122const voiceDropdown = document.getElementById('voice');
123const pitchSlider = document.getElementById('pitch');
124const rateSlider = document.getElementById('rate');
125const volumeSlider = document.getElementById('volume');
126
127voiceDropdown.onchange = e => {
128  speechSynthesis.cancel();
129  voiceIndex = e.target.value;
130};
131pitchSlider.onchange = e => {
132  speechSynthesis.cancel();
133  pitch = e.target.value / 50;
134};
135rateSlider.onchange = e => {
136  speechSynthesis.cancel();
137  rate = e.target.value / 10;
138};
139volumeSlider.onchange = e => {
140  speechSynthesis.cancel();
141  volume = e.target.value / 100;
142};
Did you find this helpful?
Trial setup questions?
Ask experts on DiscordNeed other help?
Contact SupportPricing or product questions?
Contact Sales