page.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. ( function handleLegacyURLs() {
  2. const hash = window.location.hash;
  3. if ( hash.startsWith( '#api/' ) || hash.startsWith( '#examples/' ) ) {
  4. const mappings = {
  5. '3DMLoader': 'Rhino3dmLoader',
  6. 'BufferGeometryUtils': 'module-BufferGeometryUtils',
  7. 'CameraUtils': 'module-CameraUtils',
  8. 'SceneUtils': 'module-SceneUtils',
  9. 'SkeletonUtils': 'module-SkeletonUtils',
  10. 'UniformsUtils': 'module-UniformsUtils',
  11. 'DefaultLoadingManager': 'LoadingManager',
  12. 'Interpolations': 'module-Interpolations',
  13. 'Animation': 'global',
  14. 'BufferAttributeUsage': 'global',
  15. 'Core': 'global',
  16. 'CustomBlendingEquations': 'global',
  17. 'Materials': 'global',
  18. 'Textures': 'global'
  19. };
  20. const parts = hash.split( '/' );
  21. let className = parts[ parts.length - 1 ];
  22. if ( className ) {
  23. if ( className in mappings ) className = mappings[ className ];
  24. window.location.href = `${className}.html`;
  25. }
  26. }
  27. } )();
  28. ( function loadNavigation() {
  29. const content = document.getElementById( 'content' );
  30. const navContainer = content.querySelector( 'nav' );
  31. fetch( 'nav.html' )
  32. .then( response => response.text() )
  33. .then( html => {
  34. navContainer.innerHTML = html;
  35. const savedScrollTop = sessionStorage.getItem( 'navScrollTop' );
  36. if ( savedScrollTop !== null ) {
  37. content.scrollTop = parseInt( savedScrollTop, 10 );
  38. }
  39. // Save scroll position when clicking nav links
  40. navContainer.addEventListener( 'click', function ( event ) {
  41. const link = event.target.closest( 'a' );
  42. if ( link ) {
  43. sessionStorage.setItem( 'navScrollTop', content.scrollTop );
  44. }
  45. } );
  46. updateNavigation();
  47. sessionStorage.removeItem( 'navScrollTop' );
  48. } )
  49. .catch( err => console.error( 'Failed to load navigation:', err ) );
  50. } )();
  51. //
  52. const panel = document.getElementById( 'panel' );
  53. const panelScrim = document.getElementById( 'panelScrim' );
  54. const expandButton = document.getElementById( 'expandButton' );
  55. const clearSearchButton = document.getElementById( 'clearSearchButton' );
  56. const filterInput = document.getElementById( 'filterInput' );
  57. // code copy buttons
  58. const elements = document.getElementsByTagName( 'pre' );
  59. for ( let i = 0; i < elements.length; i ++ ) {
  60. const element = elements[ i ];
  61. if ( element.classList.contains( 'linenums' ) === false ) {
  62. addCopyButton( element );
  63. }
  64. }
  65. function addCopyButton( element ) {
  66. const copyButton = document.createElement( 'button' );
  67. copyButton.className = 'copy-btn';
  68. element.appendChild( copyButton );
  69. copyButton.addEventListener( 'click', function () {
  70. const codeContent = element.textContent;
  71. navigator.clipboard.writeText( codeContent ).then( () => {
  72. copyButton.classList.add( 'copied' );
  73. setTimeout( () => {
  74. copyButton.classList.remove( 'copied' );
  75. }, 1000 );
  76. } );
  77. } );
  78. }
  79. // Functionality for hamburger button (on small devices)
  80. expandButton.onclick = function ( event ) {
  81. event.preventDefault();
  82. panel.classList.toggle( 'open' );
  83. };
  84. panelScrim.onclick = function ( event ) {
  85. event.preventDefault();
  86. panel.classList.toggle( 'open' );
  87. };
  88. // Functionality for search/filter input field
  89. filterInput.onfocus = function () {
  90. panel.classList.add( 'searchFocused' );
  91. };
  92. filterInput.onblur = function () {
  93. if ( filterInput.value === '' ) {
  94. panel.classList.remove( 'searchFocused' );
  95. }
  96. };
  97. filterInput.oninput = function () {
  98. const term = filterInput.value.trim();
  99. // eslint-disable-next-line no-undef
  100. search( term ); // defined in search.js
  101. };
  102. clearSearchButton.onclick = function () {
  103. filterInput.value = '';
  104. filterInput.focus();
  105. // eslint-disable-next-line no-undef
  106. hideSearch(); // defined in search.js
  107. };
  108. //
  109. window.addEventListener( 'hashchange', updateNavigation );
  110. function updateNavigation() {
  111. // unselected elements
  112. const selected = document.querySelectorAll( 'nav a.selected' );
  113. selected.forEach( link => link.classList.remove( 'selected' ) );
  114. // determine target
  115. const filename = window.location.pathname.split( '/' ).pop();
  116. const pagename = filename.split( '.' )[ 0 ];
  117. let target = pagename.replace( 'module-', '' );
  118. if ( pagename === 'global' ) {
  119. target = window.location.hash.split( '#' ).pop();
  120. }
  121. if ( target === '' ) return;
  122. // select target and move into view
  123. const aElement = document.querySelector( `nav a[href="${filename}"], nav a[href="${filename}#${target}"]` );
  124. if ( aElement !== null ) {
  125. const savedScrollTop = sessionStorage.getItem( 'navScrollTop' );
  126. if ( savedScrollTop === null ) {
  127. aElement.scrollIntoView( { block: 'center' } );
  128. }
  129. aElement.classList.add( 'selected' );
  130. }
  131. }
  132. // eslint-disable-next-line no-undef
  133. prettyPrint();
  134. console.log( [
  135. ' __ __',
  136. ' __/ __\\ / __\\__ ____ _____ _____',
  137. '/ __/ /\\/ / /___\\/ ____\\/ _____\\/ _____\\',
  138. '\\/_ __/ / _ / / __/ / __ / / __ /_ __ _____',
  139. '/ / / / / / / / / / / / ___/ / ___/\\ _\\/ __\\/ _____\\',
  140. '\\/__/ \\/__/\\/__/\\/__/ \\/_____/\\/_____/\\/__/ / / / ___/',
  141. ' / __/ / \\__ \\',
  142. ' \\/____/\\/_____/'
  143. ].join( '\n' ) );
  144. // console sandbox
  145. import( '/build/three.module.js' ).then( THREE => {
  146. window.THREE = THREE;
  147. } );
粤ICP备19079148号