Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

demo.js 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /**
  2. * encantar.js pointer demo
  3. * @license LGPL-3.0-or-later
  4. * @author Alexandre Martins <alemartf(at)gmail.com> (https://github.com/alemart/encantar-js)
  5. */
  6. (function() {
  7. let displayMessage = true;
  8. const POINTER_RADIUS = 50;
  9. const POINTER_COLOR = 'red';
  10. const PRIMARY_POINTER_COLOR = 'lime';
  11. const BACKGROUND_COLOR = 'antiquewhite';
  12. const TEXT_COLOR = 'black';
  13. const TEXT_FONT = '36px sans-serif';
  14. const TEXT_LARGE_FONT = '96px sans-serif';
  15. const TEXT_LINE_HEIGHT = 40;
  16. const TWO_PI = 2.0 * Math.PI;
  17. /**
  18. * Render the virtual scene
  19. * @param {TrackablePointer[]} pointers
  20. * @param {Viewport} viewport
  21. * @returns {void}
  22. */
  23. function render(pointers, viewport)
  24. {
  25. /*
  26. Check out the API reference to see the various interesting properties of a
  27. TrackablePointer! They are useful for creating all sorts of interactive
  28. experiences!
  29. */
  30. // get the canvas context
  31. const canvas = viewport.canvas;
  32. const ctx = canvas.getContext('2d');
  33. if(!ctx)
  34. return;
  35. ctx.textAlign = 'center';
  36. // draw the background
  37. ctx.fillStyle = BACKGROUND_COLOR;
  38. ctx.fillRect(0, 0, canvas.width, canvas.height);
  39. // display a message
  40. if(displayMessage) {
  41. ctx.fillStyle = TEXT_COLOR;
  42. ctx.font = TEXT_LARGE_FONT;
  43. ctx.fillText('Tap to begin', canvas.width / 2, canvas.height / 2);
  44. if(pointers.length > 0)
  45. displayMessage = false;
  46. }
  47. // render the pointers
  48. for(const pointer of pointers) {
  49. // pointer.position is given in normalized units [-1,1]x[-1,1]
  50. // we convert it to pixel coordinates (canvas space)
  51. const position = viewport.convertToPixels(pointer.position);
  52. ctx.fillStyle = pointer.isPrimary ? PRIMARY_POINTER_COLOR : POINTER_COLOR;
  53. ctx.beginPath();
  54. ctx.arc(position.x, position.y, POINTER_RADIUS, 0, TWO_PI);
  55. ctx.fill();
  56. }
  57. // render the texts above the pointers
  58. ctx.fillStyle = TEXT_COLOR;
  59. ctx.font = TEXT_FONT;
  60. for(const pointer of pointers) {
  61. const position = viewport.convertToPixels(pointer.position);
  62. position.y -= POINTER_RADIUS + 6 * TEXT_LINE_HEIGHT;
  63. ctx.fillText('id: ' + pointer.id, position.x, position.y + 0 * TEXT_LINE_HEIGHT);
  64. ctx.fillText(pointer.phase, position.x, position.y + 1 * TEXT_LINE_HEIGHT);
  65. ctx.fillText('x: ' + pointer.position.x.toFixed(5), position.x, position.y + 2 * TEXT_LINE_HEIGHT);
  66. ctx.fillText('y: ' + pointer.position.y.toFixed(5), position.x, position.y + 3 * TEXT_LINE_HEIGHT);
  67. ctx.fillText('speed: ' + pointer.velocity.length().toFixed(5), position.x, position.y + 4 * TEXT_LINE_HEIGHT);
  68. ctx.fillText('time: ' + pointer.duration.toFixed(5), position.x, position.y + 5 * TEXT_LINE_HEIGHT);
  69. }
  70. }
  71. /**
  72. * Start the AR session
  73. * @returns {Promise<Session>}
  74. */
  75. async function startARSession()
  76. {
  77. if(!AR.isSupported()) {
  78. throw new Error(
  79. 'This device is not compatible with this AR experience.\n\n' +
  80. 'User agent: ' + navigator.userAgent
  81. );
  82. }
  83. const viewport = AR.Viewport({
  84. resolution: '720p',
  85. container: document.getElementById('ar-viewport'),
  86. hudContainer: document.getElementById('ar-hud')
  87. });
  88. const tracker = AR.Tracker.Pointer();
  89. const source = AR.Source.Pointer();
  90. const session = await AR.startSession({
  91. mode: 'immersive',
  92. viewport: viewport,
  93. trackers: [ tracker ],
  94. sources: [ source ],
  95. stats: true,
  96. });
  97. return session;
  98. }
  99. /**
  100. * Animation loop
  101. * @param {number} time
  102. * @param {Frame} frame
  103. * @returns {void}
  104. */
  105. function animate(time, frame)
  106. {
  107. const session = frame.session;
  108. const pointers = read(frame);
  109. render(pointers, session.viewport);
  110. session.requestAnimationFrame(animate);
  111. }
  112. /**
  113. * Read the results of the tracker
  114. * @param {Frame} frame
  115. * @returns {TrackablePointer[]}
  116. */
  117. function read(frame)
  118. {
  119. for(const result of frame.results) {
  120. if(result.of('pointer-tracker')) {
  121. const pointers = result.trackables;
  122. return pointers;
  123. }
  124. }
  125. return [];
  126. }
  127. /**
  128. * Start the demo
  129. * @returns {void}
  130. */
  131. function main()
  132. {
  133. startARSession().then(session => {
  134. session.requestAnimationFrame(animate); // start the animation loop
  135. }).catch(error => {
  136. alert(error.message);
  137. });
  138. }
  139. document.addEventListener('DOMContentLoaded', main);
  140. })();