transform.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /**
  2. * DevExtreme (events/transform.js)
  3. * Version: 19.1.16
  4. * Build date: Tue Oct 18 2022
  5. *
  6. * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED
  7. * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
  8. */
  9. "use strict";
  10. var mathUtils = require("../core/utils/math");
  11. var iteratorUtils = require("../core/utils/iterator");
  12. var errors = require("../core/errors");
  13. var eventUtils = require("./utils");
  14. var Emitter = require("./core/emitter");
  15. var registerEmitter = require("./core/emitter_registrator");
  16. var DX_PREFIX = "dx";
  17. var TRANSFORM = "transform";
  18. var TRANSLATE = "translate";
  19. var ZOOM = "zoom";
  20. var PINCH = "pinch";
  21. var ROTATE = "rotate";
  22. var START_POSTFIX = "start";
  23. var UPDATE_POSTFIX = "";
  24. var END_POSTFIX = "end";
  25. var eventAliases = [];
  26. var addAlias = function(eventName, eventArgs) {
  27. eventAliases.push({
  28. name: eventName,
  29. args: eventArgs
  30. })
  31. };
  32. addAlias(TRANSFORM, {
  33. scale: true,
  34. deltaScale: true,
  35. rotation: true,
  36. deltaRotation: true,
  37. translation: true,
  38. deltaTranslation: true
  39. });
  40. addAlias(TRANSLATE, {
  41. translation: true,
  42. deltaTranslation: true
  43. });
  44. addAlias(ZOOM, {
  45. scale: true,
  46. deltaScale: true
  47. });
  48. addAlias(PINCH, {
  49. scale: true,
  50. deltaScale: true
  51. });
  52. addAlias(ROTATE, {
  53. rotation: true,
  54. deltaRotation: true
  55. });
  56. var getVector = function(first, second) {
  57. return {
  58. x: second.pageX - first.pageX,
  59. y: -second.pageY + first.pageY,
  60. centerX: .5 * (second.pageX + first.pageX),
  61. centerY: .5 * (second.pageY + first.pageY)
  62. }
  63. };
  64. var getEventVector = function(e) {
  65. var pointers = e.pointers;
  66. return getVector(pointers[0], pointers[1])
  67. };
  68. var getDistance = function(vector) {
  69. return Math.sqrt(vector.x * vector.x + vector.y * vector.y)
  70. };
  71. var getScale = function(firstVector, secondVector) {
  72. return getDistance(firstVector) / getDistance(secondVector)
  73. };
  74. var getRotation = function(firstVector, secondVector) {
  75. var scalarProduct = firstVector.x * secondVector.x + firstVector.y * secondVector.y;
  76. var distanceProduct = getDistance(firstVector) * getDistance(secondVector);
  77. if (0 === distanceProduct) {
  78. return 0
  79. }
  80. var sign = mathUtils.sign(firstVector.x * secondVector.y - secondVector.x * firstVector.y);
  81. var angle = Math.acos(mathUtils.fitIntoRange(scalarProduct / distanceProduct, -1, 1));
  82. return sign * angle
  83. };
  84. var getTranslation = function(firstVector, secondVector) {
  85. return {
  86. x: firstVector.centerX - secondVector.centerX,
  87. y: firstVector.centerY - secondVector.centerY
  88. }
  89. };
  90. var TransformEmitter = Emitter.inherit({
  91. configure: function(data, eventName) {
  92. if (eventName.indexOf(ZOOM) > -1) {
  93. errors.log("W0005", eventName, "15.1", "Use '" + eventName.replace(ZOOM, PINCH) + "' event instead")
  94. }
  95. this.callBase(data)
  96. },
  97. validatePointers: function(e) {
  98. return eventUtils.hasTouches(e) > 1
  99. },
  100. start: function(e) {
  101. this._accept(e);
  102. var startVector = getEventVector(e);
  103. this._startVector = startVector;
  104. this._prevVector = startVector;
  105. this._fireEventAliases(START_POSTFIX, e)
  106. },
  107. move: function(e) {
  108. var currentVector = getEventVector(e);
  109. var eventArgs = this._getEventArgs(currentVector);
  110. this._fireEventAliases(UPDATE_POSTFIX, e, eventArgs);
  111. this._prevVector = currentVector
  112. },
  113. end: function(e) {
  114. var eventArgs = this._getEventArgs(this._prevVector);
  115. this._fireEventAliases(END_POSTFIX, e, eventArgs)
  116. },
  117. _getEventArgs: function(vector) {
  118. return {
  119. scale: getScale(vector, this._startVector),
  120. deltaScale: getScale(vector, this._prevVector),
  121. rotation: getRotation(vector, this._startVector),
  122. deltaRotation: getRotation(vector, this._prevVector),
  123. translation: getTranslation(vector, this._startVector),
  124. deltaTranslation: getTranslation(vector, this._prevVector)
  125. }
  126. },
  127. _fireEventAliases: function(eventPostfix, originalEvent, eventArgs) {
  128. eventArgs = eventArgs || {};
  129. iteratorUtils.each(eventAliases, function(_, eventAlias) {
  130. var args = {};
  131. iteratorUtils.each(eventAlias.args, function(name) {
  132. if (name in eventArgs) {
  133. args[name] = eventArgs[name]
  134. }
  135. });
  136. this._fireEvent(DX_PREFIX + eventAlias.name + eventPostfix, originalEvent, args)
  137. }.bind(this))
  138. }
  139. });
  140. var eventNames = eventAliases.reduce(function(result, eventAlias) {
  141. [START_POSTFIX, UPDATE_POSTFIX, END_POSTFIX].forEach(function(eventPostfix) {
  142. result.push(DX_PREFIX + eventAlias.name + eventPostfix)
  143. });
  144. return result
  145. }, []);
  146. registerEmitter({
  147. emitter: TransformEmitter,
  148. events: eventNames
  149. });
  150. iteratorUtils.each(eventNames, function(_, eventName) {
  151. exports[eventName.substring(DX_PREFIX.length)] = eventName
  152. });