threejs-offscreencanvas-w-picking.html 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. <!-- Licensed under a BSD license. See license.html for license -->
  2. <!DOCTYPE html>
  3. <html>
  4. <head>
  5. <meta charset="utf-8">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
  7. <title>Three.js - OffscreenCanvas Picking</title>
  8. <style>
  9. body {
  10. margin: 0;
  11. }
  12. #c {
  13. width: 100vw;
  14. height: 100vh;
  15. display: block;
  16. }
  17. </style>
  18. </head>
  19. <body>
  20. <canvas id="c"></canvas>
  21. </body>
  22. <script src="resources/threejs/r114/build/three.min.js"></script>
  23. <script src="resources/threejs/r114/examples/js/controls/OrbitControls.js"></script>
  24. <script src="shared-picking.js"></script>
  25. <script>
  26. 'use strict'; // eslint-disable-line
  27. /* global state, init, pickPosition */
  28. let sendMouse;
  29. function startWorker(canvas) {
  30. const offscreen = canvas.transferControlToOffscreen();
  31. const worker = new Worker('offscreencanvas-worker-picking.js');
  32. worker.postMessage({type: 'init', canvas: offscreen}, [offscreen]);
  33. sendMouse = (x, y) => {
  34. worker.postMessage({
  35. type: 'mouse',
  36. x,
  37. y,
  38. });
  39. };
  40. function sendSize() {
  41. worker.postMessage({
  42. type: 'size',
  43. width: canvas.clientWidth,
  44. height: canvas.clientHeight,
  45. });
  46. }
  47. window.addEventListener('resize', sendSize);
  48. sendSize();
  49. console.log('using OffscreenCanvas'); /* eslint-disable-line no-console */
  50. }
  51. function startMainPage(canvas) {
  52. init({canvas});
  53. sendMouse = (x, y) => {
  54. pickPosition.x = x;
  55. pickPosition.y = y;
  56. };
  57. function sendSize() {
  58. state.width = canvas.clientWidth;
  59. state.height = canvas.clientHeight;
  60. }
  61. window.addEventListener('resize', sendSize);
  62. sendSize();
  63. console.log('using regular canvas'); /* eslint-disable-line no-console */
  64. }
  65. function main() { /* eslint consistent-return: 0 */
  66. const canvas = document.querySelector('#c');
  67. if (canvas.transferControlToOffscreen) {
  68. startWorker(canvas);
  69. } else {
  70. startMainPage(canvas);
  71. }
  72. function getCanvasRelativePosition(event) {
  73. const rect = canvas.getBoundingClientRect();
  74. return {
  75. x: (event.clientX - rect.left) * canvas.width / rect.width,
  76. y: (event.clientY - rect.top ) * canvas.height / rect.height,
  77. };
  78. }
  79. function setPickPosition(event) {
  80. const pos = getCanvasRelativePosition(event);
  81. sendMouse(
  82. (pos.x / canvas.width ) * 2 - 1,
  83. (pos.y / canvas.height) * -2 + 1); // note we flip Y
  84. }
  85. function clearPickPosition() {
  86. // unlike the mouse which always has a position
  87. // if the user stops touching the screen we want
  88. // to stop picking. For now we just pick a value
  89. // unlikely to pick something
  90. sendMouse(-100000, -100000);
  91. }
  92. window.addEventListener('mousemove', setPickPosition);
  93. window.addEventListener('mouseout', clearPickPosition);
  94. window.addEventListener('mouseleave', clearPickPosition);
  95. window.addEventListener('touchstart', (event) => {
  96. // prevent the window from scrolling
  97. event.preventDefault();
  98. setPickPosition(event.touches[0]);
  99. }, {passive: false});
  100. window.addEventListener('touchmove', (event) => {
  101. setPickPosition(event.touches[0]);
  102. });
  103. window.addEventListener('touchend', clearPickPosition);
  104. }
  105. main();
  106. </script>
  107. </html>