PinchZoom.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /* Copyright (c) 2006-2011 by OpenLayers Contributors (see authors.txt for
  2. * full list of contributors). Published under the Clear BSD license.
  3. * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  4. * full text of the license. */
  5. /**
  6. * @requires OpenLayers/Handler/Pinch.js
  7. */
  8. /**
  9. * Class: OpenLayers.Control.PinchZoom
  10. *
  11. * Inherits:
  12. * - <OpenLayers.Control>
  13. */
  14. OpenLayers.Control.PinchZoom = OpenLayers.Class(OpenLayers.Control, {
  15. /**
  16. * Property: type
  17. * {OpenLayers.Control.TYPES}
  18. */
  19. type: OpenLayers.Control.TYPE_TOOL,
  20. /**
  21. * Property: containerOrigin
  22. * {Object} Cached object representing the layer container origin (in pixels).
  23. */
  24. containerOrigin: null,
  25. /**
  26. * Property: pinchOrigin
  27. * {Object} Cached object representing the pinch start (in pixels).
  28. */
  29. pinchOrigin: null,
  30. /**
  31. * Property: currentCenter
  32. * {Object} Cached object representing the latest pinch center (in pixels).
  33. */
  34. currentCenter: null,
  35. /**
  36. * APIProperty: autoActivate
  37. * {Boolean} Activate the control when it is added to a map. Default is
  38. * true.
  39. */
  40. autoActivate: true,
  41. /**
  42. * Constructor: OpenLayers.Control.PinchZoom
  43. * Create a control for zooming with pinch gestures. This works on devices
  44. * with multi-touch support.
  45. *
  46. * Parameters:
  47. * options - {Object} An optional object whose properties will be set on
  48. * the control
  49. */
  50. initialize: function(options) {
  51. OpenLayers.Control.prototype.initialize.apply(this, arguments);
  52. this.handler = new OpenLayers.Handler.Pinch(this, {
  53. start: this.pinchStart,
  54. move: this.pinchMove,
  55. done: this.pinchDone
  56. }, this.handlerOptions);
  57. },
  58. /**
  59. * APIMethod: activate
  60. * Activate this control. Must be called after the control is added to a
  61. * map.
  62. *
  63. * Returns:
  64. * {Boolean} The control was successfully activated.
  65. */
  66. activate: function() {
  67. var activated = OpenLayers.Control.prototype.activate.apply(this,arguments);
  68. if (activated) {
  69. this.map.events.on({
  70. moveend: this.updateContainerOrigin,
  71. scope: this
  72. });
  73. this.updateContainerOrigin();
  74. }
  75. return activated;
  76. },
  77. /**
  78. * APIMethod: deactivate
  79. * Deactivate this control.
  80. *
  81. * Returns:
  82. * {Boolean} The control was successfully deactivated.
  83. */
  84. deactivate: function() {
  85. var deactivated = OpenLayers.Control.prototype.deactivate.apply(this,arguments);
  86. if (this.map && this.map.events) {
  87. this.map.events.un({
  88. moveend: this.updateContainerOrigin,
  89. scope: this
  90. });
  91. }
  92. return deactivated;
  93. },
  94. /**
  95. * Method: updateContainerOrigin
  96. * Must be called each time the layer container origin changes.
  97. */
  98. updateContainerOrigin: function() {
  99. var container = this.map.layerContainerDiv;
  100. this.containerOrigin = {
  101. x: parseInt(container.style.left, 10),
  102. y: parseInt(container.style.top, 10)
  103. };
  104. },
  105. /**
  106. * Method: pinchStart
  107. *
  108. * Parameters:
  109. * evt - {Event}
  110. * pinchData - {Object} pinch data object related to the current touchmove
  111. * of the pinch gesture. This give us the current scale of the pinch.
  112. */
  113. pinchStart: function(evt, pinchData) {
  114. this.pinchOrigin = evt.xy;
  115. this.currentCenter = evt.xy;
  116. },
  117. /**
  118. * Method: pinchMove
  119. *
  120. * Parameters:
  121. * evt - {Event}
  122. * pinchData - {Object} pinch data object related to the current touchmove
  123. * of the pinch gesture. This give us the current scale of the pinch.
  124. */
  125. pinchMove: function(evt, pinchData) {
  126. var scale = pinchData.scale;
  127. var containerOrigin = this.containerOrigin;
  128. var pinchOrigin = this.pinchOrigin;
  129. var current = evt.xy;
  130. var dx = Math.round((current.x - pinchOrigin.x) + (scale - 1) * (containerOrigin.x - pinchOrigin.x));
  131. var dy = Math.round((current.y - pinchOrigin.y) + (scale - 1) * (containerOrigin.y - pinchOrigin.y));
  132. this.applyTransform(
  133. "translate(" + dx + "px, " + dy + "px) scale(" + scale + ")"
  134. );
  135. this.currentCenter = current;
  136. },
  137. /**
  138. * Method: applyTransform
  139. * Applies the given transform to layers.
  140. */
  141. applyTransform: function(transform) {
  142. var style = this.map.layerContainerDiv.style;
  143. style['-webkit-transform'] = transform;
  144. style['-moz-transform'] = transform;
  145. },
  146. /**
  147. * Method: pinchDone
  148. *
  149. * Parameters:
  150. * evt - {Event}
  151. * start - {Object} pinch data object related to the touchstart event that
  152. * started the pinch gesture.
  153. * last - {Object} pinch data object related to the last touchmove event
  154. * of the pinch gesture. This give us the final scale of the pinch.
  155. */
  156. pinchDone: function(evt, start, last) {
  157. this.applyTransform("");
  158. var zoom = this.map.getZoomForResolution(this.map.getResolution() / last.scale, true);
  159. if (zoom !== this.map.getZoom() || !this.currentCenter.equals(this.pinchOrigin)) {
  160. var resolution = this.map.getResolutionForZoom(zoom);
  161. var location = this.map.getLonLatFromPixel(this.pinchOrigin);
  162. var zoomPixel = this.currentCenter;
  163. var size = this.map.getSize();
  164. location.lon += resolution * ((size.w / 2) - zoomPixel.x);
  165. location.lat -= resolution * ((size.h / 2) - zoomPixel.y);
  166. this.map.setCenter(location, zoom);
  167. }
  168. },
  169. CLASS_NAME: "OpenLayers.Control.PinchZoom"
  170. });