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