onEvent.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. (function (definition) {
  2. "use strict";
  3. if (!THREE) {
  4. throw new Error("This module is dependent from 'three.js,add this file first.");
  5. }
  6. // CommonJS
  7. if (typeof exports === "object" && typeof module === "object") {
  8. module.exports = definition(THREE);
  9. // RequireJS
  10. } else if (typeof define === "function" && define.amd) {
  11. define(definition);
  12. // <script>
  13. } else if (typeof window !== "undefined" || typeof self !== "undefined") {
  14. // Prefer window over self for add-on scripts. Use self for
  15. // non-windowed contexts.
  16. var global = typeof window !== "undefined" ? window : self;
  17. definition(THREE);
  18. } else {
  19. throw new Error("This environment was not anticipated by three-onEvent. Please file a bug.");
  20. }
  21. })(function (THREE) {
  22. var TargetList = {
  23. 'gaze': {},
  24. 'click': {},
  25. 'hover': {}
  26. };
  27. var updateCallbackList = [];
  28. var EventListeners = {},listenerList = {};
  29. Object.keys(TargetList).forEach(function(v,i) {
  30. EventListeners[v] = {
  31. flag: false,
  32. listener: function(targetList) {
  33. listenerList[v](targetList,option.camera);
  34. }
  35. };
  36. });
  37. var option = {};
  38. THREE.onEvent = function(scene,camera) {
  39. option.scene = scene || {};
  40. option.camera = camera || {};
  41. }
  42. THREE.onEvent.prototype.removeAll = function() {
  43. for(var key in TargetList) {
  44. for(var id in TargetList[key]) {
  45. delete TargetList[key][id];
  46. }
  47. }
  48. }
  49. THREE.onEvent.prototype.update = function() {
  50. for(var key in updateCallbackList) {
  51. updateCallbackList[key]();
  52. }
  53. }
  54. Object.assign(THREE.Object3D.prototype,{
  55. on: function(method,callback1,callback2) {
  56. if (EventListeners.hasOwnProperty(method)) {
  57. TargetList[method][this.id] = {
  58. object3d : this,
  59. callback: Array.from(arguments).slice(1)
  60. };
  61. var eventlistener = EventListeners[method];
  62. if(!eventlistener.flag){
  63. eventlistener.flag = true;
  64. eventlistener.listener(TargetList[method]);
  65. }
  66. } else {
  67. console.warn("There is no method called '" + method + "';");
  68. }
  69. },
  70. off: function(method) {
  71. if (!!method) {
  72. if (EventListeners.hasOwnProperty(method)) {
  73. delete TargetList[method][this.id];
  74. } else {
  75. console.warn("There is no method called '" + method + "';");
  76. }
  77. } else {
  78. for(var key in TargetList) {
  79. delete TargetList[key][this.id];
  80. }
  81. }
  82. }
  83. });
  84. function getObjList(targetList) {
  85. var list = [];
  86. for(var key in targetList) {
  87. var target = targetList[key].object3d;
  88. list.push(target);
  89. }
  90. return group2meshlist(list);
  91. }
  92. function group2meshlist(list) {
  93. var l = [];
  94. for (var i in list) {
  95. if (list[i].type === 'Group') {
  96. l = l.concat(group2meshlist(list[i].children));
  97. } else {
  98. l.push(list[i])
  99. }
  100. }
  101. return l;
  102. }
  103. function getEventObj(targetList,object3d) {
  104. return object2group(targetList,object3d);
  105. }
  106. function object2group(targetList,object3d) {
  107. if(targetList[object3d.id]) {
  108. return targetList[object3d.id];
  109. } else {
  110. return object2group(targetList,object3d.parent)
  111. }
  112. }
  113. // WebVR object3d on gazer
  114. listenerList.gaze = function (targetList,camera) {
  115. var Gazing = false,targetObject,obj;
  116. var Eye = new THREE.Raycaster();
  117. var gazeListener = function() {
  118. // create a gazeListener loop
  119. if (!!targetList ) {
  120. var list = [];
  121. Eye.setFromCamera(new THREE.Vector2(),camera);
  122. list = getObjList(targetList);
  123. var intersects = Eye.intersectObjects(list);
  124. if (intersects.length > 0) {
  125. if(!Gazing) { //trigger once when gaze in
  126. Gazing = true;
  127. targetObject = intersects[0].object;
  128. obj = getEventObj(targetList,targetObject);
  129. if(!!obj.callback[0]) obj.callback[0](targetObject);
  130. }
  131. } else{
  132. if(Gazing && !!obj.callback[1]) {
  133. obj.callback[1](targetObject);
  134. }
  135. Gazing = false;
  136. }
  137. }
  138. }
  139. updateCallbackList.push(gazeListener);
  140. }
  141. // object3d on mouse click
  142. listenerList.click = function (targetList,camera) {
  143. var targetObject,obj,Click = false,Down = false;
  144. var Mouse = new THREE.Raycaster();
  145. function down(event) {
  146. event.preventDefault();
  147. if (!targetList) return;
  148. var list = [];
  149. Mouse.setFromCamera(new THREE.Vector2(( event.clientX / window.innerWidth ) * 2 - 1,- ( event.clientY / window.innerHeight ) * 2 + 1), camera);
  150. list = getObjList(targetList);
  151. var intersects = Mouse.intersectObjects(list);
  152. if (intersects.length > 0) { // mouse down trigger
  153. if (Click) return;
  154. Click = true;
  155. targetObject = intersects[0].object;
  156. obj = getEventObj(targetList,targetObject);
  157. } else {
  158. Click = false;
  159. }
  160. }
  161. function move(event) {
  162. event.preventDefault();
  163. // disable click trigger when mouse moving
  164. if (Click) Click = false;
  165. }
  166. function up(event) {
  167. event.preventDefault();
  168. if (Click && !!obj.callback[0]) obj.callback[0](targetObject);
  169. Click = false;
  170. }
  171. window.addEventListener('mousedown',down,false);
  172. window.addEventListener('mousemove',move,false);
  173. window.addEventListener('mouseup',up,false);
  174. }
  175. // object3d on mouse hover
  176. listenerList.hover = function (targetList,camera) {
  177. var targetObject,obj,Hover = false;
  178. var Mouse = new THREE.Raycaster();
  179. window.addEventListener('mousemove',function(event) {
  180. event.preventDefault();
  181. if (!targetList) return;
  182. var list = [];
  183. Mouse.setFromCamera(new THREE.Vector2(( event.clientX / window.innerWidth ) * 2 - 1,- ( event.clientY / window.innerHeight ) * 2 + 1), camera);
  184. list = getObjList(targetList);
  185. var intersects = Mouse.intersectObjects(list);
  186. if (intersects.length > 0) {
  187. if (Hover) return;
  188. Hover = true;
  189. targetObject = intersects[0].object;
  190. obj = getEventObj(targetList,targetObject);
  191. if(!!obj.callback[0]) obj.callback[0](targetObject);
  192. } else {
  193. if(Hover && !!obj.callback[1]) {
  194. obj.callback[1](targetObject);
  195. }
  196. Hover = false;
  197. }
  198. }, false)
  199. }
  200. });