babylon.pointerInput.tests.ts 66 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959
  1. /**
  2. * Mock event interface used in place of real events when testing BaseCameraPointersInput
  3. * and derived classes.
  4. * Many PointerEvent properties are read-only so using real "new PointerEvent()"
  5. * is unpractical.
  6. */
  7. interface MockPointerEvent {
  8. target?: HTMLElement;
  9. type?: string;
  10. button?: number;
  11. pointerId?: number;
  12. pointerType?: string;
  13. clientX?: number;
  14. clientY?: number;
  15. movementX?: number;
  16. movementY?: number;
  17. altKey?: boolean;
  18. ctrlKey?: boolean;
  19. metaKey?: boolean;
  20. shiftKey?: boolean;
  21. buttons?: number[];
  22. [propName: string]: any;
  23. }
  24. /**
  25. * Make a mock PointerEvent.
  26. * Many PointerEvent properties are read-only so using real "new PointerEvent()"
  27. * is unpractical.
  28. */
  29. function eventTemplate(target: HTMLElement): MockPointerEvent {
  30. let returnVal = {
  31. target,
  32. button: 0,
  33. preventDefault: () => {},
  34. };
  35. return returnVal;
  36. }
  37. /**
  38. * Simulate PointerEvent in CameraPointersInput instance.
  39. */
  40. function simulateEvent(cameraInput: BABYLON.ICameraInput<BABYLON.Camera>,
  41. event: MockPointerEvent) {
  42. let pointerInfo = {};
  43. switch (event.type) {
  44. case "pointerdown":
  45. pointerInfo = {type: BABYLON.PointerEventTypes.POINTERDOWN, event};
  46. // Cast "camera" to <any> to relax "private" classification.
  47. (<any>cameraInput)._pointerInput(pointerInfo, undefined);
  48. break;
  49. case "pointerup":
  50. pointerInfo = {type: BABYLON.PointerEventTypes.POINTERUP, event};
  51. // Cast "camera" to <any> to relax "private" classification.
  52. (<any>cameraInput)._pointerInput(pointerInfo, undefined);
  53. break;
  54. case "pointermove":
  55. pointerInfo = {type: BABYLON.PointerEventTypes.POINTERMOVE, event};
  56. // Cast "camera" to <any> to relax "private" classification.
  57. (<any>cameraInput)._pointerInput(pointerInfo, undefined);
  58. break;
  59. case "blur":
  60. // Cast "camera" to <any> to relax "private" classification.
  61. (<any>cameraInput)._onLostFocus();
  62. break;
  63. case "POINTERDOUBLETAP":
  64. // Not a real DOM event. Just a shortcut to trigger
  65. // PointerEventTypes.POINTERMOVE on the Input class.
  66. pointerInfo = {type: BABYLON.PointerEventTypes.POINTERDOUBLETAP, event};
  67. // Cast "camera" to <any> to relax "private" classification.
  68. (<any>cameraInput)._pointerInput(pointerInfo, undefined);
  69. break;
  70. default:
  71. console.error("Invalid pointer event: " + event.type);
  72. }
  73. }
  74. /**
  75. * Override the methods of an existing camera to create a stub for testing
  76. * BaseCameraPointersInput.
  77. * @returns An instance of ArcRotateCameraPointersInput with the interesting
  78. * methods stubbed out.
  79. */
  80. function StubCameraInput() {
  81. // Force our CameraPointersInput instance to type "any" so we can access
  82. // protected methods from within this function.
  83. let cameraInput: any = (<any>new BABYLON.ArcRotateCameraPointersInput());
  84. /**
  85. * Reset all counters.
  86. */
  87. cameraInput.reset = ((): void => {
  88. cameraInput.countOnDoubleTap = 0;
  89. cameraInput.countOnTouch = 0;
  90. cameraInput.countOnMultiTouch = 0;
  91. cameraInput.countOnContextMenu = 0;
  92. cameraInput.countOnButtonDown = 0;
  93. cameraInput.countOnButtonUp = 0;
  94. cameraInput.countOnLostFocus = 0;
  95. cameraInput.lastOnDoubleTap = undefined;
  96. cameraInput.lastOnTouch = undefined;
  97. cameraInput.lastOnMultiTouch = undefined;
  98. cameraInput.lastOnContextMenu = undefined;
  99. cameraInput.lastOnButtonDown = undefined;
  100. cameraInput.lastOnButtonUp = undefined;
  101. });
  102. cameraInput.reset();
  103. /**
  104. * Stub out all mothods we want to test as part of the BaseCameraPointersInput testing.
  105. * These stubs keep track of how many times they were called and
  106. */
  107. cameraInput.onTouch =
  108. ((point: BABYLON.Nullable<BABYLON.PointerTouch>, offsetX: number, offsetY: number) => {
  109. cameraInput.countOnTouch++;
  110. cameraInput.lastOnTouch = {point, offsetX, offsetY};
  111. });
  112. cameraInput.onDoubleTap = ((type: string) => {
  113. cameraInput.countOnDoubleTap++;
  114. cameraInput.lastOnDoubleTap = type;
  115. });
  116. cameraInput.onMultiTouch = (
  117. (pointA: BABYLON.Nullable<BABYLON.PointerTouch>,
  118. pointB: BABYLON.Nullable<BABYLON.PointerTouch>,
  119. previousPinchSquaredDistance: number,
  120. pinchSquaredDistance: number,
  121. previousMultiTouchPanPosition: BABYLON.Nullable<BABYLON.PointerTouch>,
  122. multiTouchPanPosition: BABYLON.Nullable<BABYLON.PointerTouch>) =>
  123. {
  124. cameraInput.countOnMultiTouch++;
  125. cameraInput.lastOnMultiTouch = {
  126. pointA,
  127. pointB,
  128. previousPinchSquaredDistance,
  129. pinchSquaredDistance,
  130. previousMultiTouchPanPosition,
  131. multiTouchPanPosition,
  132. };
  133. });
  134. cameraInput.onButtonDown = ((evt: PointerEvent) => {
  135. cameraInput.countOnButtonDown++;
  136. let buttonCount = cameraInput.pointB !== null ? 2 : 1;
  137. cameraInput.lastOnButtonDown = {evt, buttonCount};
  138. });
  139. cameraInput.onButtonUp = ((evt: PointerEvent) => {
  140. cameraInput.countOnButtonUp++;
  141. let buttonCount = cameraInput.pointA !== null ? 1 : 0;
  142. cameraInput.lastOnButtonUp = {evt, buttonCount};
  143. });
  144. cameraInput.onContextMenu = ((evt: PointerEvent) => {
  145. cameraInput.countOnContextMenu++;
  146. cameraInput.lastOnContextMenu = evt;
  147. });
  148. cameraInput.onLostFocus = (() => {
  149. cameraInput.countOnLostFocus++;
  150. });
  151. return cameraInput;
  152. }
  153. /**
  154. * Test the things.
  155. * The BaseCameraPointersInput class first.
  156. */
  157. describe('BaseCameraPointersInput', function() {
  158. /**
  159. * Sets the timeout of all the tests to 10 seconds.
  160. */
  161. this.timeout(10000);
  162. before(function(done) {
  163. // runs before all tests in this block
  164. this.timeout(180000);
  165. (BABYLONDEVTOOLS).Loader
  166. .useDist()
  167. .testMode()
  168. .load(function() {
  169. // Force apply promise polyfill for consistent behavior between
  170. // PhantomJS, IE11, and other browsers.
  171. BABYLON.PromisePolyfill.Apply(true);
  172. done();
  173. });
  174. this._canvas = document.createElement("canvas");
  175. this._engine = new BABYLON.NullEngine();
  176. this._scene = new BABYLON.Scene(this._engine);
  177. // Set up an instance of a Camera with the ArcRotateCameraPointersInput.
  178. this.camera = new BABYLON.ArcRotateCamera(
  179. "StubCamera", 0, 0, 0, new BABYLON.Vector3(0, 0, 0), this._scene);
  180. this.cameraInput = StubCameraInput();
  181. this.cameraInput.camera = this.camera;
  182. this.cameraInput.attachControl(this._canvas);
  183. });
  184. beforeEach(function() {
  185. // runs before each test in this block
  186. this.cameraInput.reset();
  187. });
  188. describe('one button drag', function() {
  189. it('calls "onTouch" method', function() {
  190. var event: MockPointerEvent = eventTemplate(<HTMLElement>this._canvas);
  191. // Button down.
  192. event.type = "pointerdown";
  193. event.clientX = 100;
  194. event.clientY = 200;
  195. event.button = 0;
  196. simulateEvent(this.cameraInput, event);
  197. // Button down but no movement events have fired yet.
  198. expect(this.cameraInput.countOnTouch).to.equal(0);
  199. expect(this.cameraInput.countOnButtonDown).to.equal(1);
  200. expect(this.cameraInput.countOnButtonUp).to.equal(0);
  201. // Start moving.
  202. event.type = "pointermove";
  203. event.button = 0;
  204. simulateEvent(this.cameraInput, event);
  205. expect(this.cameraInput.countOnTouch).to.equal(1);
  206. expect(this.cameraInput.countOnButtonDown).to.equal(1);
  207. expect(this.cameraInput.countOnButtonUp).to.equal(0);
  208. // Move just started; No value yet.
  209. expect(this.cameraInput.lastOnTouch.offsetX).to.equal(0);
  210. expect(this.cameraInput.lastOnTouch.offsetY).to.equal(0);
  211. // Drag.
  212. event.type = "pointermove";
  213. event.clientX = 1000;
  214. event.button = 0;
  215. simulateEvent(this.cameraInput, event);
  216. expect(this.cameraInput.countOnTouch).to.equal(2);
  217. expect(this.cameraInput.countOnButtonDown).to.equal(1);
  218. expect(this.cameraInput.countOnButtonUp).to.equal(0);
  219. // Pointer dragged in X direction.
  220. expect(this.cameraInput.lastOnTouch.offsetX).to.above(0);
  221. expect(this.cameraInput.lastOnTouch.offsetY).to.equal(0);
  222. // Button up.
  223. event.type = "pointerup";
  224. event.button = 0;
  225. simulateEvent(this.cameraInput, event);
  226. expect(this.cameraInput.countOnTouch).to.equal(2);
  227. expect(this.cameraInput.countOnButtonDown).to.equal(1);
  228. expect(this.cameraInput.countOnButtonUp).to.equal(1);
  229. // These callbacks were never called.
  230. expect(this.cameraInput.countOnDoubleTap).to.equal(0);
  231. expect(this.cameraInput.countOnMultiTouch).to.equal(0);
  232. expect(this.cameraInput.countOnContextMenu).to.equal(0);
  233. expect(this.cameraInput.countOnLostFocus).to.equal(0);
  234. });
  235. it('leaves a clean state allowing repeat calls', function() {
  236. var event: MockPointerEvent = eventTemplate(<HTMLElement>this._canvas);
  237. // Button down.
  238. event.type = "pointerdown";
  239. event.clientX = 100;
  240. event.clientY = 200;
  241. event.button = 0;
  242. simulateEvent(this.cameraInput, event);
  243. // Button down but no movement events have fired yet.
  244. expect(this.cameraInput.countOnTouch).to.equal(0);
  245. expect(this.cameraInput.countOnButtonDown).to.equal(1);
  246. expect(this.cameraInput.countOnButtonUp).to.equal(0);
  247. // Start moving.
  248. event.type = "pointermove";
  249. event.button = 0;
  250. simulateEvent(this.cameraInput, event);
  251. expect(this.cameraInput.countOnTouch).to.equal(1);
  252. expect(this.cameraInput.countOnButtonDown).to.equal(1);
  253. expect(this.cameraInput.countOnButtonUp).to.equal(0);
  254. // Move just started; No value yet.
  255. expect(this.cameraInput.lastOnTouch.offsetX).to.equal(0);
  256. expect(this.cameraInput.lastOnTouch.offsetY).to.equal(0);
  257. // Drag.
  258. event.type = "pointermove";
  259. event.clientX = 1000;
  260. event.button = 0;
  261. simulateEvent(this.cameraInput, event);
  262. expect(this.cameraInput.countOnTouch).to.equal(2);
  263. expect(this.cameraInput.countOnButtonDown).to.equal(1);
  264. expect(this.cameraInput.countOnButtonUp).to.equal(0);
  265. // Pointer dragged in X direction.
  266. expect(this.cameraInput.lastOnTouch.offsetX).to.above(0);
  267. expect(this.cameraInput.lastOnTouch.offsetY).to.equal(0);
  268. // Button up.
  269. event.type = "pointerup";
  270. event.button = 0;
  271. simulateEvent(this.cameraInput, event);
  272. expect(this.cameraInput.countOnTouch).to.equal(2);
  273. expect(this.cameraInput.countOnButtonDown).to.equal(1);
  274. expect(this.cameraInput.countOnButtonUp).to.equal(1);
  275. // Button down for 2nd time.
  276. event.type = "pointerdown";
  277. event.clientX = 100;
  278. event.clientY = 200;
  279. event.button = 0;
  280. simulateEvent(this.cameraInput, event);
  281. // Button down but no movement events have fired yet.
  282. expect(this.cameraInput.countOnTouch).to.equal(2);
  283. expect(this.cameraInput.countOnButtonDown).to.equal(2);
  284. expect(this.cameraInput.countOnButtonUp).to.equal(1);
  285. // Start moving.
  286. event.type = "pointermove";
  287. event.button = 0;
  288. simulateEvent(this.cameraInput, event);
  289. expect(this.cameraInput.countOnTouch).to.equal(3);
  290. expect(this.cameraInput.countOnButtonDown).to.equal(2);
  291. expect(this.cameraInput.countOnButtonUp).to.equal(1);
  292. // Move just started; No value yet.
  293. expect(this.cameraInput.lastOnTouch.offsetX).to.equal(0);
  294. expect(this.cameraInput.lastOnTouch.offsetY).to.equal(0);
  295. // Drag again.
  296. event.type = "pointermove";
  297. event.clientY = 2000;
  298. event.button = 0;
  299. simulateEvent(this.cameraInput, event);
  300. expect(this.cameraInput.countOnTouch).to.equal(4);
  301. expect(this.cameraInput.countOnButtonDown).to.equal(2);
  302. expect(this.cameraInput.countOnButtonUp).to.equal(1);
  303. // Pointer dragged in Y direction.
  304. expect(this.cameraInput.lastOnTouch.offsetX).to.equal(0);
  305. expect(this.cameraInput.lastOnTouch.offsetY).to.above(0);
  306. // Button up.
  307. event.type = "pointerup";
  308. event.button = 0;
  309. simulateEvent(this.cameraInput, event);
  310. expect(this.cameraInput.countOnTouch).to.equal(4);
  311. expect(this.cameraInput.countOnButtonDown).to.equal(2);
  312. expect(this.cameraInput.countOnButtonUp).to.equal(2);
  313. // These callbacks were never called.
  314. expect(this.cameraInput.countOnDoubleTap).to.equal(0);
  315. expect(this.cameraInput.countOnMultiTouch).to.equal(0);
  316. expect(this.cameraInput.countOnContextMenu).to.equal(0);
  317. expect(this.cameraInput.countOnLostFocus).to.equal(0);
  318. });
  319. });
  320. describe('two button drag', function() {
  321. it('calls "onMultiTouch" method', function() {
  322. var event: MockPointerEvent = eventTemplate(<HTMLElement>this._canvas);
  323. // 1st button down.
  324. event.type = "pointerdown";
  325. event.pointerType = "touch";
  326. event.clientX = 1000;
  327. event.clientY = 200;
  328. event.button = 0;
  329. event.pointerId = 1;
  330. simulateEvent(this.cameraInput, event);
  331. // Button down but no movement events have fired yet.
  332. expect(this.cameraInput.countOnButtonDown).to.equal(1);
  333. expect(this.cameraInput.countOnButtonUp).to.equal(0);
  334. expect(this.cameraInput.countOnTouch).to.equal(0);
  335. expect(this.cameraInput.countOnMultiTouch).to.equal(0);
  336. // Start moving before 2nd button has been pressed.
  337. event.type = "pointermove";
  338. event.button = -1;
  339. event.pointerId = 1;
  340. simulateEvent(this.cameraInput, event);
  341. // Moving with one button down will start a drag.
  342. expect(this.cameraInput.countOnButtonDown).to.equal(1);
  343. expect(this.cameraInput.countOnButtonUp).to.equal(0);
  344. expect(this.cameraInput.countOnTouch).to.equal(1);
  345. expect(this.cameraInput.countOnMultiTouch).to.equal(0);
  346. // Move X coordinate.
  347. event.type = "pointermove";
  348. event.clientX = 1500;
  349. event.clientY = 200;
  350. event.button = -1;
  351. event.pointerId = 1;
  352. simulateEvent(this.cameraInput, event);
  353. // One button drag.
  354. expect(this.cameraInput.countOnButtonDown).to.equal(1);
  355. expect(this.cameraInput.countOnButtonUp).to.equal(0);
  356. expect(this.cameraInput.countOnTouch).to.equal(2);
  357. expect(this.cameraInput.countOnMultiTouch).to.equal(0);
  358. // 2nd button down. (Enter zoom mode.)
  359. event.type = "pointerdown";
  360. event.pointerType = "touch";
  361. event.button = 1;
  362. event.pointerId = 2;
  363. simulateEvent(this.cameraInput, event);
  364. // 2nd button down but hasn't moved yet.
  365. expect(this.cameraInput.countOnButtonDown).to.equal(2);
  366. expect(this.cameraInput.countOnButtonUp).to.equal(0);
  367. expect(this.cameraInput.countOnTouch).to.equal(2);
  368. expect(this.cameraInput.countOnMultiTouch).to.equal(0);
  369. // Start move of 2nd pointer.
  370. event.type = "pointermove";
  371. event.clientX = 2000;
  372. event.clientY = 2000;
  373. event.button = -1;
  374. event.pointerId = 2;
  375. simulateEvent(this.cameraInput, event);
  376. // Start of drag with 2 buttons down.
  377. expect(this.cameraInput.countOnButtonDown).to.equal(2);
  378. expect(this.cameraInput.countOnButtonUp).to.equal(0);
  379. expect(this.cameraInput.countOnTouch).to.equal(2);
  380. expect(this.cameraInput.countOnMultiTouch).to.equal(1);
  381. // First time onMultiTouch() is called for a new drag.
  382. expect(this.cameraInput.lastOnMultiTouch.pinchSquaredDistance).to.be.above(0);
  383. expect(this.cameraInput.lastOnMultiTouch.multiTouchPanPosition).to.not.be.null;
  384. // previousPinchSquaredDistance will be null.
  385. expect(this.cameraInput.lastOnMultiTouch.previousPinchSquaredDistance).to.be.equal(0);
  386. expect(this.cameraInput.lastOnMultiTouch.previousMultiTouchPanPosition).to.be.null;
  387. // Move Y coordinate. 2nd point is the one moving.
  388. event.type = "pointermove";
  389. event.clientX = 2000;
  390. event.clientY = 2500;
  391. event.button = -1;
  392. event.pointerId = 2;
  393. simulateEvent(this.cameraInput, event);
  394. // Moving two button drag.
  395. expect(this.cameraInput.countOnButtonDown).to.equal(2);
  396. expect(this.cameraInput.countOnButtonUp).to.equal(0);
  397. expect(this.cameraInput.countOnTouch).to.equal(2);
  398. expect(this.cameraInput.countOnMultiTouch).to.equal(2);
  399. // Neither first nor last event in a drag so everything populated.
  400. expect(this.cameraInput.lastOnMultiTouch.pinchSquaredDistance).to.be.above(0);
  401. expect(this.cameraInput.lastOnMultiTouch.multiTouchPanPosition).to.not.be.null;
  402. expect(this.cameraInput.lastOnMultiTouch.previousPinchSquaredDistance).to.be.above(0);
  403. expect(this.cameraInput.lastOnMultiTouch.previousMultiTouchPanPosition).to.not.be.null;
  404. // Move X and Y coordinate. 1st point is the one moving.
  405. event.type = "pointermove";
  406. event.clientX = 1700;
  407. event.clientY = 1700;
  408. event.button = -1;
  409. event.pointerId = 1;
  410. simulateEvent(this.cameraInput, event);
  411. // Moving two button drag.
  412. expect(this.cameraInput.countOnButtonDown).to.equal(2);
  413. expect(this.cameraInput.countOnButtonUp).to.equal(0);
  414. expect(this.cameraInput.countOnTouch).to.equal(2);
  415. expect(this.cameraInput.countOnMultiTouch).to.equal(3);
  416. // One of the buttons button up.
  417. event.type = "pointerup";
  418. event.pointerType = "touch";
  419. event.button = 0;
  420. event.pointerId = 1;
  421. simulateEvent(this.cameraInput, event);
  422. // Button up.
  423. expect(this.cameraInput.countOnButtonDown).to.equal(2);
  424. expect(this.cameraInput.countOnButtonUp).to.equal(1);
  425. expect(this.cameraInput.countOnTouch).to.equal(2);
  426. expect(this.cameraInput.countOnMultiTouch).to.equal(4);
  427. // onMultiTouch() is called one last time when drag ends with null value for
  428. // multiTouchPanPosition.
  429. expect(this.cameraInput.lastOnMultiTouch.pinchSquaredDistance).to.equal(0);
  430. expect(this.cameraInput.lastOnMultiTouch.multiTouchPanPosition).to.be.null;
  431. // previousPinchSquaredDistance and previousMultiTouchPanPosition are
  432. // populated though.
  433. expect(this.cameraInput.lastOnMultiTouch.previousPinchSquaredDistance).to.be.above(0);
  434. expect(this.cameraInput.lastOnMultiTouch.previousMultiTouchPanPosition).to.not.be.null;
  435. // Move X and Y coordinate of remaining pressed point.
  436. event.type = "pointermove";
  437. event.clientX = 2000;
  438. event.clientY = 2700;
  439. event.button = -1;
  440. event.pointerId = 2;
  441. simulateEvent(this.cameraInput, event);
  442. // Back to one button drag.
  443. expect(this.cameraInput.countOnButtonDown).to.equal(2);
  444. expect(this.cameraInput.countOnButtonUp).to.equal(1);
  445. expect(this.cameraInput.countOnTouch).to.equal(3);
  446. expect(this.cameraInput.countOnMultiTouch).to.equal(4);
  447. // Other button button up. (Now moves should have no affect.)
  448. event.type = "pointerup";
  449. event.pointerType = "touch";
  450. event.button = 1;
  451. event.pointerId = 2;
  452. simulateEvent(this.cameraInput, event);
  453. // Button up.
  454. expect(this.cameraInput.countOnButtonDown).to.equal(2);
  455. expect(this.cameraInput.countOnButtonUp).to.equal(2);
  456. expect(this.cameraInput.countOnTouch).to.equal(3);
  457. expect(this.cameraInput.countOnMultiTouch).to.equal(4);
  458. // Move X and Y coordinate.
  459. event.type = "pointermove";
  460. event.clientX = 3000;
  461. event.clientY = 4000;
  462. event.button = -1;
  463. event.pointerId = 1;
  464. simulateEvent(this.cameraInput, event);
  465. // Not dragging anymore so no change in callbacks.
  466. expect(this.cameraInput.countOnButtonDown).to.equal(2);
  467. expect(this.cameraInput.countOnButtonUp).to.equal(2);
  468. expect(this.cameraInput.countOnTouch).to.equal(3);
  469. expect(this.cameraInput.countOnMultiTouch).to.equal(4);
  470. // These callbacks were never called.
  471. expect(this.cameraInput.countOnDoubleTap).to.equal(0);
  472. expect(this.cameraInput.countOnContextMenu).to.equal(0);
  473. expect(this.cameraInput.countOnLostFocus).to.equal(0);
  474. });
  475. });
  476. describe('button down then up', function() {
  477. it('calls "onButtonDown" and "onButtonUp"', function() {
  478. var event: MockPointerEvent = eventTemplate(<HTMLElement>this._canvas);
  479. // 1st button down.
  480. event.type = "pointerdown";
  481. event.pointerType = "touch";
  482. event.button = 0;
  483. event.pointerId = 1;
  484. simulateEvent(this.cameraInput, event);
  485. expect(this.cameraInput.countOnButtonDown).to.equal(1);
  486. expect(this.cameraInput.countOnButtonUp).to.equal(0);
  487. expect(this.cameraInput.lastOnButtonDown.buttonCount).to.be.equal(1);
  488. // 2nd button down.
  489. event.type = "pointerdown";
  490. event.pointerType = "touch";
  491. event.button = 1;
  492. event.pointerId = 2;
  493. simulateEvent(this.cameraInput, event);
  494. expect(this.cameraInput.countOnButtonDown).to.equal(2);
  495. expect(this.cameraInput.countOnButtonUp).to.equal(0);
  496. expect(this.cameraInput.lastOnButtonDown.buttonCount).to.be.equal(2);
  497. // One button up.
  498. event.type = "pointerup";
  499. event.pointerType = "touch";
  500. event.button = 1;
  501. event.pointerId = 2;
  502. simulateEvent(this.cameraInput, event);
  503. expect(this.cameraInput.countOnButtonDown).to.equal(2);
  504. expect(this.cameraInput.countOnButtonUp).to.equal(1);
  505. expect(this.cameraInput.lastOnButtonUp.buttonCount).to.be.equal(1);
  506. // Other button up.
  507. event.type = "pointerup";
  508. event.pointerType = "touch";
  509. event.button = 0;
  510. event.pointerId = 1;
  511. simulateEvent(this.cameraInput, event);
  512. expect(this.cameraInput.countOnButtonDown).to.equal(2);
  513. expect(this.cameraInput.countOnButtonUp).to.equal(2);
  514. expect(this.cameraInput.lastOnButtonUp.buttonCount).to.be.equal(0);
  515. // These callbacks were never called.
  516. expect(this.cameraInput.countOnTouch).to.equal(0);
  517. expect(this.cameraInput.countOnMultiTouch).to.equal(0);
  518. expect(this.cameraInput.countOnDoubleTap).to.equal(0);
  519. expect(this.cameraInput.countOnContextMenu).to.equal(0);
  520. expect(this.cameraInput.countOnLostFocus).to.equal(0);
  521. });
  522. it('pointerId of pointerup doesnt match', function() {
  523. var event: MockPointerEvent = eventTemplate(<HTMLElement>this._canvas);
  524. // 1st button down.
  525. event.type = "pointerdown";
  526. event.pointerType = "touch";
  527. event.button = 0;
  528. event.pointerId = 1;
  529. simulateEvent(this.cameraInput, event);
  530. expect(this.cameraInput.countOnButtonDown).to.equal(1);
  531. expect(this.cameraInput.countOnButtonUp).to.equal(0);
  532. expect(this.cameraInput.lastOnButtonDown.buttonCount).to.be.equal(1);
  533. // 2nd button down.
  534. event.type = "pointerdown";
  535. event.pointerType = "touch";
  536. event.button = 1;
  537. event.pointerId = 2;
  538. simulateEvent(this.cameraInput, event);
  539. expect(this.cameraInput.countOnButtonDown).to.equal(2);
  540. expect(this.cameraInput.countOnButtonUp).to.equal(0);
  541. expect(this.cameraInput.lastOnButtonDown.buttonCount).to.be.equal(2);
  542. // 3rd button down.
  543. event.type = "pointerdown";
  544. event.pointerType = "touch";
  545. event.button = 2;
  546. event.pointerId = 3;
  547. simulateEvent(this.cameraInput, event);
  548. // Only 2 buttons are tracked.
  549. // onButtonDown() gets called but nothing else changes.
  550. expect(this.cameraInput.countOnButtonDown).to.equal(3);
  551. expect(this.cameraInput.countOnButtonUp).to.equal(0);
  552. expect(this.cameraInput.lastOnButtonDown.buttonCount).to.be.equal(2);
  553. // One button up.
  554. event.type = "pointerup";
  555. event.pointerType = "touch";
  556. event.button = 1;
  557. event.pointerId = 99;
  558. simulateEvent(this.cameraInput, event);
  559. expect(this.cameraInput.countOnButtonDown).to.equal(3);
  560. expect(this.cameraInput.countOnButtonUp).to.equal(1);
  561. // Button state gets cleared. No buttons registered as being down.
  562. expect(this.cameraInput.lastOnButtonUp.buttonCount).to.be.equal(0);
  563. // These callbacks were never called.
  564. expect(this.cameraInput.countOnTouch).to.equal(0);
  565. expect(this.cameraInput.countOnMultiTouch).to.equal(0);
  566. expect(this.cameraInput.countOnDoubleTap).to.equal(0);
  567. expect(this.cameraInput.countOnContextMenu).to.equal(0);
  568. expect(this.cameraInput.countOnLostFocus).to.equal(0);
  569. });
  570. });
  571. });
  572. /**
  573. * Test the things.
  574. * The ArcRotateCameraInput class.
  575. */
  576. describe('ArcRotateCameraInput', function() {
  577. /**
  578. * Sets the timeout of all the tests to 10 seconds.
  579. */
  580. this.timeout(10000);
  581. enum ValChange {
  582. Increase,
  583. Same,
  584. Decrease,
  585. DontCare,
  586. }
  587. const interestingValues = [
  588. "inertialPanningX",
  589. "inertialPanningY",
  590. "inertialAlphaOffset",
  591. "inertialBetaOffset",
  592. "inertialRadiusOffset",
  593. ];
  594. function resetCameraPos(camera: BABYLON.ArcRotateCamera, cameraCachePos: {}) {
  595. camera.alpha = 10;
  596. camera.beta = 20;
  597. camera.radius = 30;
  598. camera.inertialPanningX = 0;
  599. camera.inertialPanningY = 0;
  600. camera.inertialAlphaOffset = 0;
  601. camera.inertialBetaOffset = 0;
  602. camera.inertialRadiusOffset = 0;
  603. camera._panningMouseButton = 2;
  604. camera.useInputToRestoreState = true;
  605. camera._useCtrlForPanning = true;
  606. interestingValues.forEach((key) => {
  607. cameraCachePos[key] = camera[key];
  608. });
  609. }
  610. function verifyChanges(
  611. camera: BABYLON.ArcRotateCamera,
  612. cameraCachePos: {},
  613. toCheck: {[key: string]: ValChange}): boolean {
  614. let result = true;
  615. interestingValues.forEach((key) => {
  616. if (toCheck[key] === undefined) {
  617. toCheck[key] = ValChange.Same;
  618. }
  619. let r = (
  620. toCheck[key] === ValChange.DontCare ||
  621. (toCheck[key] === ValChange.Decrease && camera[key] < cameraCachePos[key]) ||
  622. (toCheck[key] === ValChange.Same && camera[key] === cameraCachePos[key]) ||
  623. (toCheck[key] === ValChange.Increase && camera[key] > cameraCachePos[key])
  624. );
  625. if (!r) {
  626. console.log(
  627. `Incorrect value for ${key}, previous: ${cameraCachePos[key]}, current: ${camera[key]}`
  628. );
  629. }
  630. result = result && r;
  631. cameraCachePos[key] = camera[key];
  632. });
  633. if (!result) {
  634. displayCamera(camera);
  635. }
  636. return result;
  637. }
  638. function displayCamera(camera: BABYLON.ArcRotateCamera): void {
  639. let info = {
  640. inertialPanningX: camera.inertialPanningX,
  641. inertialPanningY: camera.inertialPanningY,
  642. inertialAlphaOffset: camera.inertialAlphaOffset,
  643. inertialBetaOffset: camera.inertialBetaOffset,
  644. inertialRadiusOffset: camera.inertialRadiusOffset
  645. };
  646. console.log(info);
  647. };
  648. before(function(done) {
  649. // runs before all tests in this block
  650. this.timeout(180000);
  651. (BABYLONDEVTOOLS).Loader
  652. .useDist()
  653. .testMode()
  654. .load(function() {
  655. // Force apply promise polyfill for consistent behavior between
  656. // PhantomJS, IE11, and other browsers.
  657. BABYLON.PromisePolyfill.Apply(true);
  658. done();
  659. });
  660. this._canvas = document.createElement("canvas");
  661. this._scene = new BABYLON.Scene(new BABYLON.NullEngine());
  662. // Set up an instance of a Camera with the ArcRotateCameraPointersInput.
  663. this.camera = new BABYLON.ArcRotateCamera(
  664. "Camera", 0, 0, 0, new BABYLON.Vector3(0, 0, 0), this._scene);
  665. this.cameraInput = new BABYLON.ArcRotateCameraPointersInput();
  666. this.cameraInput.camera = this.camera;
  667. this.cameraInput.attachControl(this._canvas);
  668. this.cameraCachePos = {};
  669. });
  670. beforeEach(function() {
  671. // runs before each test in this block
  672. resetCameraPos(this.camera, this.cameraCachePos);
  673. });
  674. describe('Test infrastructure', function() {
  675. it('verifyChanges checks Decrease', function() {
  676. this.camera.inertialAlphaOffset = 10;
  677. this.cameraCachePos.inertialAlphaOffset = 10.001;
  678. expect(
  679. verifyChanges(
  680. this.camera,
  681. this.cameraCachePos,
  682. {inertialAlphaOffset: ValChange.Decrease})
  683. ).to.be.true;
  684. this.camera.inertialAlphaOffset = 10;
  685. this.cameraCachePos.inertialAlphaOffset = 9.999;
  686. expect(
  687. verifyChanges(
  688. this.camera,
  689. this.cameraCachePos,
  690. {inertialAlphaOffset: ValChange.Decrease})
  691. ).to.be.false;
  692. });
  693. it('verifyChanges checks Same', function() {
  694. this.camera.inertialAlphaOffset = 10;
  695. this.cameraCachePos.inertialAlphaOffset = 10;
  696. expect(
  697. verifyChanges(
  698. this.camera,
  699. this.cameraCachePos,
  700. {inertialAlphaOffset: ValChange.Same})
  701. ).to.be.true;
  702. this.camera.inertialAlphaOffset = 10;
  703. this.cameraCachePos.inertialAlphaOffset = 10.001;
  704. expect(
  705. verifyChanges(
  706. this.camera,
  707. this.cameraCachePos,
  708. {inertialAlphaOffset: ValChange.Same})
  709. ).to.be.false;
  710. });
  711. it('verifyChanges checks undefined', function() {
  712. // If the 'toCheck' field is undefined, treat is as ValChange.Same.
  713. this.camera.inertialAlphaOffset = 10;
  714. this.cameraCachePos.inertialAlphaOffset = 10;
  715. expect(
  716. verifyChanges(
  717. this.camera,
  718. this.cameraCachePos,
  719. {})
  720. ).to.be.true;
  721. this.camera.inertialAlphaOffset = 10;
  722. this.cameraCachePos.inertialAlphaOffset = 10.001;
  723. expect(
  724. verifyChanges(
  725. this.camera,
  726. this.cameraCachePos,
  727. {})
  728. ).to.be.false;
  729. });
  730. it('verifyChanges checks DontCare', function() {
  731. this.camera.inertialAlphaOffset = 10;
  732. this.cameraCachePos.inertialAlphaOffset = 10;
  733. expect(
  734. verifyChanges(
  735. this.camera,
  736. this.cameraCachePos,
  737. {inertialAlphaOffset: ValChange.DontCare})
  738. ).to.be.true;
  739. this.camera.inertialAlphaOffset = 10;
  740. this.cameraCachePos.inertialAlphaOffset = 1001;
  741. expect(
  742. verifyChanges(
  743. this.camera,
  744. this.cameraCachePos,
  745. {inertialAlphaOffset: ValChange.DontCare})
  746. ).to.be.true;
  747. });
  748. it('verifyChanges checks Increase', function() {
  749. this.camera.inertialAlphaOffset = 10;
  750. this.cameraCachePos.inertialAlphaOffset = 9.999;
  751. expect(
  752. verifyChanges(
  753. this.camera,
  754. this.cameraCachePos,
  755. {inertialAlphaOffset: ValChange.Increase})
  756. ).to.be.true;
  757. this.camera.inertialAlphaOffset = 10;
  758. this.cameraCachePos.inertialAlphaOffset = 10.001;
  759. expect(
  760. verifyChanges(
  761. this.camera,
  762. this.cameraCachePos,
  763. {inertialAlphaOffset: ValChange.Increase})
  764. ).to.be.false;
  765. });
  766. });
  767. describe('one button drag', function() {
  768. it('changes inertialAlphaOffset', function() {
  769. var event: MockPointerEvent = eventTemplate(<HTMLElement>this._canvas);
  770. // Button down.
  771. event.type = "pointerdown";
  772. event.clientX = 100;
  773. event.clientY = 200;
  774. event.button = 0;
  775. simulateEvent(this.cameraInput, event);
  776. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  777. // Start moving.
  778. event.type = "pointermove";
  779. event.button = 0;
  780. simulateEvent(this.cameraInput, event);
  781. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  782. // Move X coordinate. Drag camera.
  783. event.type = "pointermove";
  784. event.clientX = 1000;
  785. event.button = 0;
  786. simulateEvent(this.cameraInput, event);
  787. expect(verifyChanges(
  788. this.camera,
  789. this.cameraCachePos,
  790. {inertialAlphaOffset: ValChange.Decrease})
  791. ).to.be.true;
  792. // Button up. Primary button.
  793. event.type = "pointerup";
  794. event.button = 0;
  795. simulateEvent(this.cameraInput, event);
  796. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  797. });
  798. it('followed by another one button drag', function() {
  799. var event: MockPointerEvent = eventTemplate(<HTMLElement>this._canvas);
  800. // Button down.
  801. event.type = "pointerdown";
  802. event.clientX = 100;
  803. event.clientY = 200;
  804. event.button = 0;
  805. simulateEvent(this.cameraInput, event);
  806. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  807. // Start moving.
  808. event.type = "pointermove";
  809. event.button = 0;
  810. simulateEvent(this.cameraInput, event);
  811. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  812. // Move X coordinate. Drag camera.
  813. event.type = "pointermove";
  814. event.clientX = 1000;
  815. event.button = 0;
  816. simulateEvent(this.cameraInput, event);
  817. expect(verifyChanges(
  818. this.camera,
  819. this.cameraCachePos,
  820. {inertialAlphaOffset: ValChange.Decrease})
  821. ).to.be.true;
  822. // Button up. Primary button.
  823. event.type = "pointerup";
  824. event.button = 0;
  825. simulateEvent(this.cameraInput, event);
  826. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  827. // 2nd drag.
  828. // Button down.
  829. event.type = "pointerdown";
  830. event.clientX = 100;
  831. event.clientY = 200;
  832. event.button = 0;
  833. simulateEvent(this.cameraInput, event);
  834. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  835. // Start moving.
  836. event.type = "pointermove";
  837. event.button = 0;
  838. simulateEvent(this.cameraInput, event);
  839. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  840. // Move Y coordinate. Drag camera.
  841. event.type = "pointermove";
  842. event.clientY = 1000;
  843. event.button = 0;
  844. simulateEvent(this.cameraInput, event);
  845. expect(verifyChanges(
  846. this.camera,
  847. this.cameraCachePos,
  848. {inertialBetaOffset: ValChange.Decrease})
  849. ).to.be.true;
  850. // Button up. Primary button.
  851. event.type = "pointerup";
  852. event.button = 0;
  853. simulateEvent(this.cameraInput, event);
  854. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  855. });
  856. it('with Ctrl key changes inertialPanningY', function() {
  857. this.cameraInput.panningSensibility = 3;
  858. this.cameraInput._useCtrlForPanning = true;
  859. var event: MockPointerEvent = eventTemplate(<HTMLElement>this._canvas);
  860. // Button down.
  861. event.type = "pointerdown";
  862. event.clientX = 100;
  863. event.clientY = 200;
  864. event.button = 0;
  865. simulateEvent(this.cameraInput, event);
  866. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  867. // Start moving.
  868. event.type = "pointermove";
  869. event.button = 0;
  870. simulateEvent(this.cameraInput, event);
  871. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  872. // Move Y coordinate. Drag camera. (Not panning yet.)
  873. event.type = "pointermove";
  874. event.clientY = 1000;
  875. event.button = 0;
  876. simulateEvent(this.cameraInput, event);
  877. expect(verifyChanges(
  878. this.camera,
  879. this.cameraCachePos,
  880. {inertialBetaOffset: ValChange.Decrease})
  881. ).to.be.true;
  882. // Move X coordinate with Ctrl key depressed. Panning now.
  883. event.type = "pointermove";
  884. event.clientY = 2000;
  885. event.button = 0;
  886. event.ctrlKey = true; // Will cause pan motion.
  887. simulateEvent(this.cameraInput, event);
  888. expect(verifyChanges(
  889. this.camera,
  890. this.cameraCachePos,
  891. {inertialPanningY: ValChange.Increase})
  892. ).to.be.true;
  893. // Move X coordinate having released Ctrl.
  894. event.type = "pointermove";
  895. event.clientY = 3000;
  896. event.button = 0;
  897. event.ctrlKey = false; // Will cancel pan motion.
  898. simulateEvent(this.cameraInput, event);
  899. expect(verifyChanges(
  900. this.camera,
  901. this.cameraCachePos,
  902. {inertialBetaOffset: ValChange.Decrease})
  903. ).to.be.true;
  904. // Button up. Primary button.
  905. event.type = "pointerup";
  906. event.button = 0;
  907. simulateEvent(this.cameraInput, event);
  908. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  909. });
  910. it('with panningSensibility disabled', function() {
  911. this.cameraInput.panningSensibility = 0;
  912. var event: MockPointerEvent = eventTemplate(<HTMLElement>this._canvas);
  913. // Button down.
  914. event.type = "pointerdown";
  915. event.clientX = 100;
  916. event.clientY = 200;
  917. event.button = 0;
  918. simulateEvent(this.cameraInput, event);
  919. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  920. // Start moving.
  921. event.type = "pointermove";
  922. event.button = 0;
  923. simulateEvent(this.cameraInput, event);
  924. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  925. // Move Y coordinate. Drag camera.
  926. event.type = "pointermove";
  927. event.clientY = 1000;
  928. event.button = 0;
  929. simulateEvent(this.cameraInput, event);
  930. expect(verifyChanges(
  931. this.camera,
  932. this.cameraCachePos,
  933. {inertialBetaOffset: ValChange.Decrease})
  934. ).to.be.true;
  935. // Move X coordinate with Ctrl key depressed.
  936. // Panning disabled so continue regular drag..
  937. event.type = "pointermove";
  938. event.clientY = 1500;
  939. event.button = 0;
  940. event.ctrlKey = true; // Will cause pan motion.
  941. simulateEvent(this.cameraInput, event);
  942. expect(verifyChanges(
  943. this.camera,
  944. this.cameraCachePos,
  945. {inertialBetaOffset: ValChange.Decrease})
  946. ).to.be.true;
  947. // Move X coordinate having released Ctrl.
  948. event.type = "pointermove";
  949. event.clientY = 3000;
  950. event.button = 0;
  951. event.ctrlKey = false;
  952. simulateEvent(this.cameraInput, event);
  953. expect(verifyChanges(
  954. this.camera,
  955. this.cameraCachePos,
  956. {inertialBetaOffset: ValChange.Decrease})
  957. ).to.be.true;
  958. // Button up. Primary button.
  959. event.type = "pointerup";
  960. event.button = 0;
  961. simulateEvent(this.cameraInput, event);
  962. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  963. });
  964. });
  965. describe('two button drag', function() {
  966. describe('multiTouchPanAndZoom enabled', function() {
  967. it('pinchDeltaPercentage enabled', function() {
  968. // Multiple button presses interpreted as "pinch" and "swipe".
  969. this.cameraInput.multiTouchPanAndZoom = true;
  970. // Zoom changes are a percentage of current value.
  971. this.cameraInput.pinchDeltaPercentage = 10;
  972. // Panning not enabled.
  973. this.cameraInput.panningSensibility = 0;
  974. var event: MockPointerEvent = eventTemplate(<HTMLElement>this._canvas);
  975. // 1st button down.
  976. event.type = "pointerdown";
  977. event.pointerType = "touch";
  978. event.clientX = 1000;
  979. event.clientY = 200;
  980. event.button = 0;
  981. event.pointerId = 1;
  982. simulateEvent(this.cameraInput, event);
  983. // Start moving before 2nd button has been pressed.
  984. event.type = "pointermove";
  985. event.button = -1;
  986. event.pointerId = 1;
  987. simulateEvent(this.cameraInput, event);
  988. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  989. // Move X coordinate.
  990. event.type = "pointermove";
  991. event.clientX = 1500;
  992. event.clientY = 200;
  993. event.button = -1;
  994. event.pointerId = 1;
  995. simulateEvent(this.cameraInput, event);
  996. expect(verifyChanges(
  997. this.camera,
  998. this.cameraCachePos,
  999. {inertialAlphaOffset: ValChange.Decrease})
  1000. ).to.be.true;
  1001. // 2nd button down. (Enter zoom mode.)
  1002. event.type = "pointerdown";
  1003. event.pointerType = "touch";
  1004. event.button = 1;
  1005. event.pointerId = 2;
  1006. simulateEvent(this.cameraInput, event);
  1007. // Start move of 2nd pointer.
  1008. event.type = "pointermove";
  1009. event.clientX = 2000;
  1010. event.clientY = 2000;
  1011. event.button = -1;
  1012. event.pointerId = 2;
  1013. simulateEvent(this.cameraInput, event);
  1014. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  1015. // Move Y coordinate. 2nd point is the one moving.
  1016. event.type = "pointermove";
  1017. event.clientX = 2000;
  1018. event.clientY = 2500;
  1019. event.button = -1;
  1020. event.pointerId = 2;
  1021. simulateEvent(this.cameraInput, event);
  1022. expect(verifyChanges(
  1023. this.camera,
  1024. this.cameraCachePos,
  1025. {inertialRadiusOffset: ValChange.Increase})
  1026. ).to.be.true;
  1027. // Move X + Y coordinate. 1st point is the one moving.
  1028. event.type = "pointermove";
  1029. event.clientX = 1700;
  1030. event.clientY = 1700;
  1031. event.button = -1;
  1032. event.pointerId = 1;
  1033. simulateEvent(this.cameraInput, event);
  1034. expect(verifyChanges(
  1035. this.camera,
  1036. this.cameraCachePos,
  1037. {inertialRadiusOffset: ValChange.Decrease})
  1038. ).to.be.true;
  1039. // One of the buttons button up. (Leave zoom mode.)
  1040. event.type = "pointerup";
  1041. event.pointerType = "touch";
  1042. event.button = 0;
  1043. event.pointerId = 1;
  1044. simulateEvent(this.cameraInput, event);
  1045. // Move X and Y coordinate of remaining pressed point.
  1046. event.type = "pointermove";
  1047. event.clientX = 2000;
  1048. event.clientY = 2700;
  1049. event.button = -1;
  1050. event.pointerId = 2;
  1051. simulateEvent(this.cameraInput, event);
  1052. expect(verifyChanges(
  1053. this.camera,
  1054. this.cameraCachePos,
  1055. {inertialBetaOffset: ValChange.Decrease})
  1056. ).to.be.true;
  1057. // Other button button up. (Now moves should have no affect.)
  1058. event.type = "pointerup";
  1059. event.pointerType = "touch";
  1060. event.button = 1;
  1061. event.pointerId = 2;
  1062. simulateEvent(this.cameraInput, event);
  1063. // Move X and Y coordinate.
  1064. event.type = "pointermove";
  1065. event.clientX = 3000;
  1066. event.clientY = 4000;
  1067. event.button = -1;
  1068. event.pointerId = 1;
  1069. simulateEvent(this.cameraInput, event);
  1070. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  1071. });
  1072. it('pinchDeltaPercentage disabled', function() {
  1073. // Multiple button presses interpreted as "pinch" and "swipe".
  1074. this.cameraInput.multiTouchPanAndZoom = true;
  1075. // Zoom changes are not a percentage of current value.
  1076. this.cameraInput.pinchDeltaPercentage = 0;
  1077. // Panning not enabled.
  1078. this.cameraInput.panningSensibility = 0;
  1079. var event: MockPointerEvent = eventTemplate(<HTMLElement>this._canvas);
  1080. // 1st button down.
  1081. event.type = "pointerdown";
  1082. event.pointerType = "touch";
  1083. event.clientX = 1000;
  1084. event.clientY = 200;
  1085. event.button = 0;
  1086. event.pointerId = 1;
  1087. simulateEvent(this.cameraInput, event);
  1088. // Start moving before 2nd button has been pressed.
  1089. event.type = "pointermove";
  1090. event.button = -1;
  1091. event.pointerId = 1;
  1092. simulateEvent(this.cameraInput, event);
  1093. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  1094. // Move X coordinate.
  1095. event.type = "pointermove";
  1096. event.clientX = 1500;
  1097. event.clientY = 200;
  1098. event.button = -1;
  1099. event.pointerId = 1;
  1100. simulateEvent(this.cameraInput, event);
  1101. expect(verifyChanges(
  1102. this.camera,
  1103. this.cameraCachePos,
  1104. {inertialAlphaOffset: ValChange.Decrease})
  1105. ).to.be.true;
  1106. // 2nd button down. (Enter zoom mode.)
  1107. event.type = "pointerdown";
  1108. event.pointerType = "touch";
  1109. event.button = 1;
  1110. event.pointerId = 2;
  1111. simulateEvent(this.cameraInput, event);
  1112. // Start move of 2nd pointer.
  1113. event.type = "pointermove";
  1114. event.clientX = 2000;
  1115. event.clientY = 2000;
  1116. event.button = -1;
  1117. event.pointerId = 2;
  1118. simulateEvent(this.cameraInput, event);
  1119. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  1120. // Move Y coordinate. 2nd point is the one moving.
  1121. event.type = "pointermove";
  1122. event.clientX = 2000;
  1123. event.clientY = 2500;
  1124. event.button = -1;
  1125. event.pointerId = 2;
  1126. simulateEvent(this.cameraInput, event);
  1127. expect(verifyChanges(
  1128. this.camera,
  1129. this.cameraCachePos,
  1130. {inertialRadiusOffset: ValChange.Increase})
  1131. ).to.be.true;
  1132. // Move X + Y coordinate. 1st point is the one moving.
  1133. event.type = "pointermove";
  1134. event.clientX = 1700;
  1135. event.clientY = 1700;
  1136. event.button = -1;
  1137. event.pointerId = 1;
  1138. simulateEvent(this.cameraInput, event);
  1139. expect(verifyChanges(
  1140. this.camera,
  1141. this.cameraCachePos,
  1142. {inertialRadiusOffset: ValChange.Decrease})
  1143. ).to.be.true;
  1144. // One of the buttons button up. (Leave zoom mode.)
  1145. event.type = "pointerup";
  1146. event.pointerType = "touch";
  1147. event.button = 0;
  1148. event.pointerId = 1;
  1149. simulateEvent(this.cameraInput, event);
  1150. // Move X and Y coordinate of remaining pressed point.
  1151. event.type = "pointermove";
  1152. event.clientX = 2000;
  1153. event.clientY = 2700;
  1154. event.button = -1;
  1155. event.pointerId = 2;
  1156. simulateEvent(this.cameraInput, event);
  1157. expect(verifyChanges(
  1158. this.camera,
  1159. this.cameraCachePos,
  1160. {inertialBetaOffset: ValChange.Decrease})
  1161. ).to.be.true;
  1162. // Other button button up. (Now moves should have no affect.)
  1163. event.type = "pointerup";
  1164. event.pointerType = "touch";
  1165. event.button = 1;
  1166. event.pointerId = 2;
  1167. simulateEvent(this.cameraInput, event);
  1168. // Move X and Y coordinate.
  1169. event.type = "pointermove";
  1170. event.clientX = 3000;
  1171. event.clientY = 4000;
  1172. event.button = -1;
  1173. event.pointerId = 1;
  1174. simulateEvent(this.cameraInput, event);
  1175. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  1176. });
  1177. it('pan on drag', function() {
  1178. // Multiple button presses interpreted as "pinch" and "swipe".
  1179. this.cameraInput.multiTouchPanAndZoom = true;
  1180. // Zoom changes are not a percentage of current value.
  1181. this.cameraInput.pinchDeltaPercentage = 0;
  1182. // Panning not enabled.
  1183. this.cameraInput.panningSensibility = 3;
  1184. var event: MockPointerEvent = eventTemplate(<HTMLElement>this._canvas);
  1185. // 1st button down.
  1186. event.type = "pointerdown";
  1187. event.pointerType = "touch";
  1188. event.clientX = 1000;
  1189. event.clientY = 200;
  1190. event.button = 0;
  1191. event.pointerId = 1;
  1192. simulateEvent(this.cameraInput, event);
  1193. // Start moving before 2nd button has been pressed.
  1194. event.type = "pointermove";
  1195. event.button = -1;
  1196. event.pointerId = 1;
  1197. simulateEvent(this.cameraInput, event);
  1198. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  1199. // Move X coordinate.
  1200. event.type = "pointermove";
  1201. event.clientX = 1500;
  1202. event.clientY = 200;
  1203. event.button = -1;
  1204. event.pointerId = 1;
  1205. simulateEvent(this.cameraInput, event);
  1206. expect(verifyChanges(
  1207. this.camera,
  1208. this.cameraCachePos,
  1209. {inertialAlphaOffset: ValChange.Decrease})
  1210. ).to.be.true;
  1211. // 2nd button down. (Enter zoom mode.)
  1212. event.type = "pointerdown";
  1213. event.pointerType = "touch";
  1214. event.button = 1;
  1215. event.pointerId = 2;
  1216. simulateEvent(this.cameraInput, event);
  1217. // Start move of 2nd pointer.
  1218. event.type = "pointermove";
  1219. event.clientX = 2000;
  1220. event.clientY = 2000;
  1221. event.button = -1;
  1222. event.pointerId = 2;
  1223. simulateEvent(this.cameraInput, event);
  1224. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  1225. // Move Y coordinate. 2nd point is the one moving.
  1226. event.type = "pointermove";
  1227. event.clientX = 2000;
  1228. event.clientY = 2500;
  1229. event.button = -1;
  1230. event.pointerId = 2;
  1231. simulateEvent(this.cameraInput, event);
  1232. expect(verifyChanges(
  1233. this.camera,
  1234. this.cameraCachePos,
  1235. {inertialRadiusOffset: ValChange.Increase,
  1236. inertialPanningY: ValChange.Increase})
  1237. ).to.be.true;
  1238. // Move X + Y coordinate. 1st point is the one moving.
  1239. event.type = "pointermove";
  1240. event.clientX = 1700;
  1241. event.clientY = 1700;
  1242. event.button = -1;
  1243. event.pointerId = 1;
  1244. simulateEvent(this.cameraInput, event);
  1245. expect(verifyChanges(
  1246. this.camera,
  1247. this.cameraCachePos,
  1248. {inertialRadiusOffset: ValChange.Decrease,
  1249. inertialPanningX: ValChange.Decrease,
  1250. inertialPanningY: ValChange.Increase})
  1251. ).to.be.true;
  1252. // One of the buttons button up. (Leave zoom mode.)
  1253. event.type = "pointerup";
  1254. event.pointerType = "touch";
  1255. event.button = 0;
  1256. event.pointerId = 1;
  1257. simulateEvent(this.cameraInput, event);
  1258. // Move X and Y coordinate of remaining pressed point.
  1259. event.type = "pointermove";
  1260. event.clientX = 2000;
  1261. event.clientY = 2700;
  1262. event.button = -1;
  1263. event.pointerId = 2;
  1264. simulateEvent(this.cameraInput, event);
  1265. expect(verifyChanges(
  1266. this.camera,
  1267. this.cameraCachePos,
  1268. {inertialBetaOffset: ValChange.Decrease})
  1269. ).to.be.true;
  1270. // Other button button up. (Now moves should have no affect.)
  1271. event.type = "pointerup";
  1272. event.pointerType = "touch";
  1273. event.button = 1;
  1274. event.pointerId = 2;
  1275. simulateEvent(this.cameraInput, event);
  1276. // Move X and Y coordinate.
  1277. event.type = "pointermove";
  1278. event.clientX = 3000;
  1279. event.clientY = 4000;
  1280. event.button = -1;
  1281. event.pointerId = 1;
  1282. simulateEvent(this.cameraInput, event);
  1283. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  1284. });
  1285. });
  1286. describe('multiTouchPanAndZoom disabled', function() {
  1287. it('pinchDeltaPercentage enabled', function() {
  1288. // Multiple button presses not interpreted as multitouch.
  1289. this.cameraInput.multiTouchPanAndZoom = false;
  1290. // Zoom changes are a percentage of current value.
  1291. this.cameraInput.pinchDeltaPercentage = 10;
  1292. // Panning not enabled.
  1293. this.cameraInput.panningSensibility = 3;
  1294. var event: MockPointerEvent = eventTemplate(<HTMLElement>this._canvas);
  1295. // 1st button down.
  1296. event.type = "pointerdown";
  1297. event.pointerType = "touch";
  1298. event.clientX = 1000;
  1299. event.clientY = 200;
  1300. event.button = 0;
  1301. event.pointerId = 1;
  1302. simulateEvent(this.cameraInput, event);
  1303. // Start moving before 2nd button has been pressed.
  1304. event.type = "pointermove";
  1305. event.button = -1;
  1306. event.pointerId = 1;
  1307. simulateEvent(this.cameraInput, event);
  1308. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  1309. // Move X coordinate.
  1310. event.type = "pointermove";
  1311. event.clientX = 1500;
  1312. event.clientY = 200;
  1313. event.button = -1;
  1314. event.pointerId = 1;
  1315. simulateEvent(this.cameraInput, event);
  1316. expect(verifyChanges(
  1317. this.camera,
  1318. this.cameraCachePos,
  1319. {inertialAlphaOffset: ValChange.Decrease})
  1320. ).to.be.true;
  1321. // 2nd button down. (Enter zoom mode.)
  1322. event.type = "pointerdown";
  1323. event.pointerType = "touch";
  1324. event.button = 1;
  1325. event.pointerId = 2;
  1326. simulateEvent(this.cameraInput, event);
  1327. // Start move of 2nd pointer.
  1328. event.type = "pointermove";
  1329. event.clientX = 2000;
  1330. event.clientY = 2000;
  1331. event.button = -1;
  1332. event.pointerId = 2;
  1333. simulateEvent(this.cameraInput, event);
  1334. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  1335. // Move Y coordinate. 2nd point is the one moving.
  1336. event.type = "pointermove";
  1337. event.clientX = 2000;
  1338. event.clientY = 2500;
  1339. event.button = -1;
  1340. event.pointerId = 2;
  1341. simulateEvent(this.cameraInput, event);
  1342. expect(verifyChanges(
  1343. this.camera,
  1344. this.cameraCachePos,
  1345. {inertialRadiusOffset: ValChange.Increase})
  1346. ).to.be.true;
  1347. // Move X + Y coordinate. 1st point is the one moving.
  1348. event.type = "pointermove";
  1349. event.clientX = 1700;
  1350. event.clientY = 1700;
  1351. event.button = -1;
  1352. event.pointerId = 1;
  1353. simulateEvent(this.cameraInput, event);
  1354. expect(verifyChanges(
  1355. this.camera,
  1356. this.cameraCachePos,
  1357. {inertialRadiusOffset: ValChange.Decrease})
  1358. ).to.be.true;
  1359. // One of the buttons button up. (Leave zoom mode.)
  1360. event.type = "pointerup";
  1361. event.pointerType = "touch";
  1362. event.button = 0;
  1363. event.pointerId = 1;
  1364. simulateEvent(this.cameraInput, event);
  1365. // Move X and Y coordinate of remaining pressed point.
  1366. event.type = "pointermove";
  1367. event.clientX = 2000;
  1368. event.clientY = 2700;
  1369. event.button = -1;
  1370. event.pointerId = 2;
  1371. simulateEvent(this.cameraInput, event);
  1372. expect(verifyChanges(
  1373. this.camera,
  1374. this.cameraCachePos,
  1375. {inertialBetaOffset: ValChange.Decrease})
  1376. ).to.be.true;
  1377. // 1st button down again
  1378. event.type = "pointerdown";
  1379. event.pointerType = "touch";
  1380. event.button = 0;
  1381. event.pointerId = 1;
  1382. simulateEvent(this.cameraInput, event);
  1383. // Start move of 1st button.
  1384. // This time trigger more than 20 pointermove events without moving more
  1385. // than pinchToPanMaxDistance to lock into "pan" mode.
  1386. event.type = "pointermove";
  1387. event.clientX = 1000;
  1388. event.clientY = 1000;
  1389. event.button = -1;
  1390. event.pointerId = 1;
  1391. for (let i = 0; i < 21; i++) {
  1392. event.clientX++;
  1393. simulateEvent(this.cameraInput, event);
  1394. }
  1395. expect(verifyChanges(
  1396. this.camera,
  1397. this.cameraCachePos,
  1398. {inertialPanningX: ValChange.Decrease})
  1399. ).to.be.true;
  1400. // Now we are in "pan" mode, we can move 1st pointer larger distances.
  1401. event.type = "pointermove";
  1402. event.clientX = 5000;
  1403. event.clientY = 5000;
  1404. event.button = -1;
  1405. event.pointerId = 2;
  1406. simulateEvent(this.cameraInput, event);
  1407. expect(verifyChanges(
  1408. this.camera,
  1409. this.cameraCachePos,
  1410. {inertialPanningX: ValChange.Decrease,
  1411. inertialPanningY: ValChange.Increase})
  1412. ).to.be.true;
  1413. // One of the buttons button up. (Leave pan mode.)
  1414. event.type = "pointerup";
  1415. event.pointerType = "touch";
  1416. event.button = 0;
  1417. event.pointerId = 1;
  1418. simulateEvent(this.cameraInput, event);
  1419. // Other button button up. (Now moves should have no affect.)
  1420. event.type = "pointerup";
  1421. event.pointerType = "touch";
  1422. event.button = 1;
  1423. event.pointerId = 2;
  1424. simulateEvent(this.cameraInput, event);
  1425. // Move X and Y coordinate.
  1426. event.type = "pointermove";
  1427. event.clientX = 3000;
  1428. event.clientY = 4000;
  1429. event.button = -1;
  1430. event.pointerId = 1;
  1431. simulateEvent(this.cameraInput, event);
  1432. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  1433. });
  1434. it('pinchDeltaPercentage disabled', function() {
  1435. // Multiple button presses not interpreted as multitouch.
  1436. this.cameraInput.multiTouchPanAndZoom = false;
  1437. // Zoom changes are not a percentage of current value.
  1438. this.cameraInput.pinchDeltaPercentage = 0;
  1439. // Panning not enabled.
  1440. this.cameraInput.panningSensibility = 3;
  1441. var event: MockPointerEvent = eventTemplate(<HTMLElement>this._canvas);
  1442. // 1st button down.
  1443. event.type = "pointerdown";
  1444. event.pointerType = "touch";
  1445. event.clientX = 1000;
  1446. event.clientY = 200;
  1447. event.button = 0;
  1448. event.pointerId = 1;
  1449. simulateEvent(this.cameraInput, event);
  1450. // Start moving before 2nd button has been pressed.
  1451. event.type = "pointermove";
  1452. event.button = -1;
  1453. event.pointerId = 1;
  1454. simulateEvent(this.cameraInput, event);
  1455. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  1456. // Move X coordinate.
  1457. event.type = "pointermove";
  1458. event.clientX = 1500;
  1459. event.clientY = 200;
  1460. event.button = -1;
  1461. event.pointerId = 1;
  1462. simulateEvent(this.cameraInput, event);
  1463. expect(verifyChanges(
  1464. this.camera,
  1465. this.cameraCachePos,
  1466. {inertialAlphaOffset: ValChange.Decrease})
  1467. ).to.be.true;
  1468. // 2nd button down. (Enter zoom mode.)
  1469. event.type = "pointerdown";
  1470. event.pointerType = "touch";
  1471. event.button = 1;
  1472. event.pointerId = 2;
  1473. simulateEvent(this.cameraInput, event);
  1474. // Start move of 2nd pointer.
  1475. event.type = "pointermove";
  1476. event.clientX = 2000;
  1477. event.clientY = 2000;
  1478. event.button = -1;
  1479. event.pointerId = 2;
  1480. simulateEvent(this.cameraInput, event);
  1481. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  1482. // Move Y coordinate. 2nd point is the one moving.
  1483. event.type = "pointermove";
  1484. event.clientX = 2000;
  1485. event.clientY = 2500;
  1486. event.button = -1;
  1487. event.pointerId = 2;
  1488. simulateEvent(this.cameraInput, event);
  1489. expect(verifyChanges(
  1490. this.camera,
  1491. this.cameraCachePos,
  1492. {inertialRadiusOffset: ValChange.Increase})
  1493. ).to.be.true;
  1494. // Move X + Y coordinate. 1st point is the one moving.
  1495. event.type = "pointermove";
  1496. event.clientX = 1700;
  1497. event.clientY = 1700;
  1498. event.button = -1;
  1499. event.pointerId = 1;
  1500. simulateEvent(this.cameraInput, event);
  1501. expect(verifyChanges(
  1502. this.camera,
  1503. this.cameraCachePos,
  1504. {inertialRadiusOffset: ValChange.Decrease})
  1505. ).to.be.true;
  1506. // One of the buttons button up. (Leave zoom mode.)
  1507. event.type = "pointerup";
  1508. event.pointerType = "touch";
  1509. event.button = 0;
  1510. event.pointerId = 1;
  1511. simulateEvent(this.cameraInput, event);
  1512. // Move X and Y coordinate of remaining pressed point.
  1513. event.type = "pointermove";
  1514. event.clientX = 2000;
  1515. event.clientY = 2700;
  1516. event.button = -1;
  1517. event.pointerId = 2;
  1518. simulateEvent(this.cameraInput, event);
  1519. expect(verifyChanges(
  1520. this.camera,
  1521. this.cameraCachePos,
  1522. {inertialBetaOffset: ValChange.Decrease})
  1523. ).to.be.true;
  1524. // 1st button down again
  1525. event.type = "pointerdown";
  1526. event.pointerType = "touch";
  1527. event.button = 0;
  1528. event.pointerId = 1;
  1529. simulateEvent(this.cameraInput, event);
  1530. // Start move of 1st button.
  1531. // This time trigger more than 20 pointermove events without moving more
  1532. // than pinchToPanMaxDistance to lock into "pan" mode.
  1533. event.type = "pointermove";
  1534. event.clientX = 1000;
  1535. event.clientY = 1000;
  1536. event.button = -1;
  1537. event.pointerId = 1;
  1538. for (let i = 0; i < 21; i++) {
  1539. event.clientX++;
  1540. simulateEvent(this.cameraInput, event);
  1541. }
  1542. expect(verifyChanges(
  1543. this.camera,
  1544. this.cameraCachePos,
  1545. {inertialPanningX: ValChange.Decrease})
  1546. ).to.be.true;
  1547. // Now we are in "pan" mode, we can move 1st pointer larger distances.
  1548. event.type = "pointermove";
  1549. event.clientX = 5000;
  1550. event.clientY = 5000;
  1551. event.button = -1;
  1552. event.pointerId = 2;
  1553. simulateEvent(this.cameraInput, event);
  1554. expect(verifyChanges(
  1555. this.camera,
  1556. this.cameraCachePos,
  1557. {inertialPanningX: ValChange.Decrease,
  1558. inertialPanningY: ValChange.Increase})
  1559. ).to.be.true;
  1560. // One of the buttons button up. (Leave pan mode.)
  1561. event.type = "pointerup";
  1562. event.pointerType = "touch";
  1563. event.button = 0;
  1564. event.pointerId = 1;
  1565. simulateEvent(this.cameraInput, event);
  1566. // Other button button up. (Now moves should have no affect.)
  1567. event.type = "pointerup";
  1568. event.pointerType = "touch";
  1569. event.button = 1;
  1570. event.pointerId = 2;
  1571. simulateEvent(this.cameraInput, event);
  1572. // Move X and Y coordinate.
  1573. event.type = "pointermove";
  1574. event.clientX = 3000;
  1575. event.clientY = 4000;
  1576. event.button = -1;
  1577. event.pointerId = 1;
  1578. simulateEvent(this.cameraInput, event);
  1579. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  1580. });
  1581. });
  1582. });
  1583. describe('loose focus', function() {
  1584. it('cancels drag', function() {
  1585. // Multiple button presses interpreted as "pinch" and "swipe".
  1586. this.cameraInput.multiTouchPanAndZoom = true;
  1587. // Zoom changes are a percentage of current value.
  1588. this.cameraInput.pinchDeltaPercentage = 10;
  1589. // Panning not enabled.
  1590. this.cameraInput.panningSensibility = 0;
  1591. var event: MockPointerEvent = eventTemplate(<HTMLElement>this._canvas);
  1592. // 1st button down.
  1593. event.type = "pointerdown";
  1594. event.pointerType = "touch";
  1595. event.clientX = 1000;
  1596. event.clientY = 200;
  1597. event.button = 0;
  1598. event.pointerId = 1;
  1599. simulateEvent(this.cameraInput, event);
  1600. // Start moving before 2nd button has been pressed.
  1601. event.type = "pointermove";
  1602. event.button = -1;
  1603. event.pointerId = 1;
  1604. simulateEvent(this.cameraInput, event);
  1605. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  1606. // Move X coordinate.
  1607. event.type = "pointermove";
  1608. event.clientX = 1500;
  1609. event.clientY = 200;
  1610. event.button = -1;
  1611. event.pointerId = 1;
  1612. simulateEvent(this.cameraInput, event);
  1613. expect(verifyChanges(
  1614. this.camera,
  1615. this.cameraCachePos,
  1616. {inertialAlphaOffset: ValChange.Decrease})
  1617. ).to.be.true;
  1618. // Lost focus
  1619. (<any>this.cameraInput)._onLostFocus();
  1620. // Move X + Y coordinate. Should have no affect after loosing focus.
  1621. event.type = "pointermove";
  1622. event.clientX = 1700;
  1623. event.clientY = 1700;
  1624. event.button = -1;
  1625. event.pointerId = 1;
  1626. simulateEvent(this.cameraInput, event);
  1627. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  1628. });
  1629. it('cancels double drag', function() {
  1630. // Multiple button presses interpreted as "pinch" and "swipe".
  1631. this.cameraInput.multiTouchPanAndZoom = true;
  1632. // Zoom changes are a percentage of current value.
  1633. this.cameraInput.pinchDeltaPercentage = 10;
  1634. // Panning not enabled.
  1635. this.cameraInput.panningSensibility = 0;
  1636. var event: MockPointerEvent = eventTemplate(<HTMLElement>this._canvas);
  1637. // 1st button down.
  1638. event.type = "pointerdown";
  1639. event.pointerType = "touch";
  1640. event.clientX = 1000;
  1641. event.clientY = 200;
  1642. event.button = 0;
  1643. event.pointerId = 1;
  1644. simulateEvent(this.cameraInput, event);
  1645. // Start moving before 2nd button has been pressed.
  1646. event.type = "pointermove";
  1647. event.button = -1;
  1648. event.pointerId = 1;
  1649. simulateEvent(this.cameraInput, event);
  1650. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  1651. // Move X coordinate.
  1652. event.type = "pointermove";
  1653. event.clientX = 1500;
  1654. event.clientY = 200;
  1655. event.button = -1;
  1656. event.pointerId = 1;
  1657. simulateEvent(this.cameraInput, event);
  1658. expect(verifyChanges(
  1659. this.camera,
  1660. this.cameraCachePos,
  1661. {inertialAlphaOffset: ValChange.Decrease})
  1662. ).to.be.true;
  1663. // 2nd button down. (Enter zoom mode.)
  1664. event.type = "pointerdown";
  1665. event.pointerType = "touch";
  1666. event.button = 1;
  1667. event.pointerId = 2;
  1668. simulateEvent(this.cameraInput, event);
  1669. // Start move of 2nd pointer.
  1670. event.type = "pointermove";
  1671. event.clientX = 2000;
  1672. event.clientY = 2000;
  1673. event.button = -1;
  1674. event.pointerId = 2;
  1675. simulateEvent(this.cameraInput, event);
  1676. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  1677. // Move Y coordinate. 2nd point is the one moving.
  1678. event.type = "pointermove";
  1679. event.clientX = 2000;
  1680. event.clientY = 2500;
  1681. event.button = -1;
  1682. event.pointerId = 2;
  1683. simulateEvent(this.cameraInput, event);
  1684. expect(verifyChanges(
  1685. this.camera,
  1686. this.cameraCachePos,
  1687. {inertialRadiusOffset: ValChange.Increase})
  1688. ).to.be.true;
  1689. // Lost focus
  1690. (<any>this.cameraInput)._onLostFocus();
  1691. // Move X + Y coordinate. Should have no affect after loosing focus.
  1692. event.type = "pointermove";
  1693. event.clientX = 1700;
  1694. event.clientY = 1700;
  1695. event.button = -1;
  1696. event.pointerId = 1;
  1697. simulateEvent(this.cameraInput, event);
  1698. expect(verifyChanges(this.camera, this.cameraCachePos, {})).to.be.true;
  1699. });
  1700. });
  1701. describe('double click', function() {
  1702. it('doesnt restore save position', function() {
  1703. // Disable restoring position.
  1704. this.camera.useInputToRestoreState = false;
  1705. this.camera.alpha = 10;
  1706. this.camera.beta = 10;
  1707. this.camera.radius = 10;
  1708. this.camera.storeState();
  1709. this.camera.alpha = 20;
  1710. this.camera.beta = 20;
  1711. this.camera.radius = 20;
  1712. var event: MockPointerEvent = eventTemplate(<HTMLElement>this._canvas);
  1713. event.type = "POINTERDOUBLETAP";
  1714. simulateEvent(this.cameraInput, event);
  1715. expect(this.camera.alpha).to.be.equal(20);
  1716. expect(this.camera.beta).to.be.equal(20);
  1717. expect(this.camera.radius).to.be.equal(20);
  1718. });
  1719. it('restores save position', function() {
  1720. // Enable restoring position.
  1721. this.camera.useInputToRestoreState = true;
  1722. this.camera.alpha = 10;
  1723. this.camera.beta = 10;
  1724. this.camera.radius = 10;
  1725. this.camera.storeState();
  1726. this.camera.alpha = 20;
  1727. this.camera.beta = 20;
  1728. this.camera.radius = 20;
  1729. var event: MockPointerEvent = eventTemplate(<HTMLElement>this._canvas);
  1730. event.type = "POINTERDOUBLETAP";
  1731. simulateEvent(this.cameraInput, event);
  1732. expect(this.camera.alpha).to.be.equal(10);
  1733. expect(this.camera.beta).to.be.equal(10);
  1734. expect(this.camera.radius).to.be.equal(10);
  1735. });
  1736. });
  1737. });