threejs-offscreencanvas-w-picking.html 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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/r105/three.min.js"></script>
  23. <script src="shared-picking.js"></script>
  24. <script>
  25. 'use strict';
  26. /* global state, init, pickPosition */
  27. let sendMouse;
  28. function startWorker(canvas) {
  29. const offscreen = canvas.transferControlToOffscreen();
  30. const worker = new Worker('offscreencanvas-worker-picking.js');
  31. worker.postMessage({type: 'init', canvas: offscreen}, [offscreen]);
  32. sendMouse = (x, y) => {
  33. worker.postMessage({
  34. type: 'mouse',
  35. x,
  36. y,
  37. });
  38. };
  39. function sendSize() {
  40. worker.postMessage({
  41. type: 'size',
  42. width: canvas.clientWidth,
  43. height: canvas.clientHeight,
  44. });
  45. }
  46. window.addEventListener('resize', sendSize);
  47. sendSize();
  48. console.log('using OffscreenCanvas'); /* eslint-disable-line no-console */
  49. }
  50. function startMainPage(canvas) {
  51. init({canvas});
  52. sendMouse = (x, y) => {
  53. pickPosition.x = x;
  54. pickPosition.y = y;
  55. };
  56. function sendSize() {
  57. state.width = canvas.clientWidth;
  58. state.height = canvas.clientHeight;
  59. }
  60. window.addEventListener('resize', sendSize);
  61. sendSize();
  62. console.log('using regular canvas'); /* eslint-disable-line no-console */
  63. }
  64. function main() { /* eslint consistent-return: 0 */
  65. const canvas = document.querySelector('#c');
  66. if (canvas.transferControlToOffscreen) {
  67. startWorker(canvas);
  68. } else {
  69. startMainPage(canvas);
  70. }
  71. function getCanvasRelativePosition(event) {
  72. const rect = canvas.getBoundingClientRect();
  73. return {
  74. x: event.clientX - rect.left,
  75. y: event.clientY - rect.top,
  76. };
  77. }
  78. function setPickPosition(event) {
  79. const pos = getCanvasRelativePosition(event);
  80. sendMouse(
  81. (pos.x / canvas.clientWidth ) * 2 - 1,
  82. (pos.y / canvas.clientHeight) * -2 + 1); // note we flip Y
  83. }
  84. function clearPickPosition() {
  85. // unlike the mouse which always has a position
  86. // if the user stops touching the screen we want
  87. // to stop picking. For now we just pick a value
  88. // unlikely to pick something
  89. sendMouse(-100000, -100000);
  90. }
  91. window.addEventListener('mousemove', setPickPosition);
  92. window.addEventListener('mouseout', clearPickPosition);
  93. window.addEventListener('mouseleave', clearPickPosition);
  94. window.addEventListener('touchstart', (event) => {
  95. // prevent the window from scrolling
  96. event.preventDefault();
  97. setPickPosition(event.touches[0]);
  98. }, {passive: false});
  99. window.addEventListener('touchmove', (event) => {
  100. setPickPosition(event.touches[0]);
  101. });
  102. window.addEventListener('touchend', clearPickPosition);
  103. }
  104. main();
  105. </script>
  106. </html>