embed-pdf.html 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. <!--
  2. SPDX-License-Identifier: MIT
  3. This shortcut was originally taken from: https://github.com/anvithks/hugo-embed-pdf-shortcode,
  4. where it is available under the MIT License, where it was originally created by https://github.com/anvithks
  5. Since the project seems discontinued, it has been re-created here
  6. -->
  7. <!-- Load the PDF-JS from the local folder (should be updated over time) -->
  8. <script src= '/js/pdf-js/build/pdf.js'></script>
  9. <!-- Set the navigation menu -->
  10. <div id="paginator">
  11. <button id="prev">Previous</button>
  12. <button id="next">Next</button>
  13. &nbsp; &nbsp;
  14. <span>Page: <span id="page_num"></span> / <span id="page_count"></span></span>
  15. </div>
  16. <!-- And the canvas where the PDF will load -->
  17. <div id="embed-pdf-container">
  18. <div id="loadingWrapper">
  19. <div id="loading"></div>
  20. </div>
  21. <canvas id="the-canvas"></canvas>
  22. </div>
  23. <!-- This script gets the PDF, sets it and passes it on to the already-loaded pdf-js -->
  24. <script type="text/javascript">
  25. window.onload = function() {
  26. // If absolute URL from the remote server is provided, configure the CORS
  27. // header on that server.
  28. var url = "{{.Site.BaseURL}}" + '{{ .Get "src" }}';
  29. var hidePaginator = "{{ .Get "hidePaginator" }}" === "true";
  30. var hideLoader = "{{ .Get "hideLoader" }}" === "true";
  31. var selectedPageNum = parseInt("{{ .Get "renderPageNum" }}") || 1;
  32. // Loaded via <script> tag, create shortcut to access PDF.js exports.
  33. var pdfjsLib = window['pdfjs-dist/build/pdf'];
  34. // The workerSrc property shall be specified.
  35. pdfjsLib.GlobalWorkerOptions.workerSrc = "{{.Site.BaseURL}}" + '/js/pdf-js/build/pdf.worker.js';
  36. // Change the Scale value for lower or higher resolution.
  37. var pdfDoc = null,
  38. pageNum = selectedPageNum,
  39. pageRendering = false,
  40. pageNumPending = null,
  41. scale = 3,
  42. canvas = document.getElementById('the-canvas'),
  43. ctx = canvas.getContext('2d'),
  44. paginator = document.getElementById("paginator"),
  45. loadingWrapper = document.getElementById('loadingWrapper');
  46. // Attempt to show paginator and loader if enabled
  47. showPaginator();
  48. showLoader();
  49. /**
  50. * Get page info from document, resize canvas accordingly, and render page.
  51. * @param num Page number.
  52. */
  53. function renderPage(num) {
  54. pageRendering = true;
  55. // Using promise to fetch the page
  56. pdfDoc.getPage(num).then(function(page) {
  57. var viewport = page.getViewport({scale: scale});
  58. canvas.height = viewport.height;
  59. canvas.width = viewport.width;
  60. // Render PDF page into canvas context
  61. var renderContext = {
  62. canvasContext: ctx,
  63. viewport: viewport
  64. };
  65. var renderTask = page.render(renderContext);
  66. // Wait for rendering to finish
  67. renderTask.promise.then(function() {
  68. pageRendering = false;
  69. showContent();
  70. if (pageNumPending !== null) {
  71. // New page rendering is pending
  72. renderPage(pageNumPending);
  73. pageNumPending = null;
  74. }
  75. });
  76. });
  77. // Update page counters
  78. document.getElementById('page_num').textContent = num;
  79. }
  80. /**
  81. * Hides loader and shows canvas
  82. */
  83. function showContent() {
  84. loadingWrapper.style.display = 'none';
  85. canvas.style.display = 'block';
  86. }
  87. /**
  88. * If we haven't disabled the loader, show loader and hide canvas
  89. */
  90. function showLoader() {
  91. if(hideLoader) return
  92. loadingWrapper.style.display = 'flex';
  93. canvas.style.display = 'none';
  94. }
  95. /**
  96. * If we haven't disabled the paginator, show paginator
  97. */
  98. function showPaginator() {
  99. if(hidePaginator) return
  100. paginator.style.display = 'block';
  101. }
  102. /**
  103. * If another page rendering in progress, waits until the rendering is
  104. * finished. Otherwise, executes rendering immediately.
  105. */
  106. function queueRenderPage(num) {
  107. if (pageRendering) {
  108. pageNumPending = num;
  109. } else {
  110. renderPage(num);
  111. }
  112. }
  113. /**
  114. * Displays previous page.
  115. */
  116. function onPrevPage() {
  117. if (pageNum <= 1) {
  118. return;
  119. }
  120. pageNum--;
  121. queueRenderPage(pageNum);
  122. }
  123. document.getElementById('prev').addEventListener('click', onPrevPage);
  124. /**
  125. * Displays next page.
  126. */
  127. function onNextPage() {
  128. if (pageNum >= pdfDoc.numPages) {
  129. return;
  130. }
  131. pageNum++;
  132. queueRenderPage(pageNum);
  133. }
  134. document.getElementById('next').addEventListener('click', onNextPage);
  135. /**
  136. * Asynchronously downloads PDF.
  137. */
  138. pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) {
  139. pdfDoc = pdfDoc_;
  140. var numPages = pdfDoc.numPages;
  141. document.getElementById('page_count').textContent = numPages;
  142. // If the user passed in a number that is out of range, render the last page.
  143. if(pageNum > numPages) {
  144. pageNum = numPages
  145. }
  146. // Initial/first page rendering
  147. renderPage(pageNum);
  148. });
  149. }
  150. </script>
  151. <!-- Finally, make the canvas more beautiful -->
  152. <style>
  153. #the-canvas {
  154. border: 1px solid black;
  155. direction: ltr;
  156. width: 100%;
  157. height: auto;
  158. display: none;
  159. }
  160. #paginator {
  161. display: none;
  162. text-align: center;
  163. margin-bottom: 10px;
  164. }
  165. #loadingWrapper {
  166. display: none;
  167. justify-content: center;
  168. align-items: center;
  169. width: 100%;
  170. height: 350px;
  171. }
  172. #loading {
  173. display: inline-block;
  174. width: 50px;
  175. height: 50px;
  176. border: 3px solid #d2d0d0;;
  177. border-radius: 50%;
  178. border-top-color: #383838;
  179. animation: spin 1s ease-in-out infinite;
  180. -webkit-animation: spin 1s ease-in-out infinite;
  181. }
  182. @keyframes spin {
  183. to { -webkit-transform: rotate(360deg); }
  184. }
  185. @-webkit-keyframes spin {
  186. to { -webkit-transform: rotate(360deg); }
  187. }
  188. </style>