PinchZoom.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
  2. * full list of contributors). Published under the 2-clause BSD license.
  3. * See license.txt in the OpenLayers distribution or repository 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: pinchOrigin
  22. * {Object} Cached object representing the pinch start (in pixels).
  23. */
  24. pinchOrigin: null,
  25. /**
  26. * Property: currentCenter
  27. * {Object} Cached object representing the latest pinch center (in pixels).
  28. */
  29. currentCenter: null,
  30. /**
  31. * APIProperty: autoActivate
  32. * {Boolean} Activate the control when it is added to a map. Default is
  33. * true.
  34. */
  35. autoActivate: true,
  36. /**
  37. * APIProperty: preserveCenter
  38. * {Boolean} Set this to true if you don't want the map center to change
  39. * while pinching. For example you may want to set preserveCenter to
  40. * true when the user location is being watched and you want to preserve
  41. * the user location at the center of the map even if he zooms in or
  42. * out using pinch. This property's value can be changed any time on an
  43. * existing instance. Default is false.
  44. */
  45. preserveCenter: false,
  46. /**
  47. * APIProperty: handlerOptions
  48. * {Object} Used to set non-default properties on the pinch handler
  49. */
  50. /**
  51. * Constructor: OpenLayers.Control.PinchZoom
  52. * Create a control for zooming with pinch gestures. This works on devices
  53. * with multi-touch support.
  54. *
  55. * Parameters:
  56. * options - {Object} An optional object whose properties will be set on
  57. * the control
  58. */
  59. initialize: function(options) {
  60. OpenLayers.Control.prototype.initialize.apply(this, arguments);
  61. this.handler = new OpenLayers.Handler.Pinch(this, {
  62. start: this.pinchStart,
  63. move: this.pinchMove,
  64. done: this.pinchDone
  65. }, this.handlerOptions);
  66. },
  67. /**
  68. * Method: pinchStart
  69. *
  70. * Parameters:
  71. * evt - {Event}
  72. * pinchData - {Object} pinch data object related to the current touchmove
  73. * of the pinch gesture. This give us the current scale of the pinch.
  74. */
  75. pinchStart: function(evt, pinchData) {
  76. var xy = (this.preserveCenter) ?
  77. this.map.getPixelFromLonLat(this.map.getCenter()) : evt.xy;
  78. this.pinchOrigin = xy;
  79. this.currentCenter = xy;
  80. },
  81. /**
  82. * Method: pinchMove
  83. *
  84. * Parameters:
  85. * evt - {Event}
  86. * pinchData - {Object} pinch data object related to the current touchmove
  87. * of the pinch gesture. This give us the current scale of the pinch.
  88. */
  89. pinchMove: function(evt, pinchData) {
  90. var scale = pinchData.scale;
  91. var containerOrigin = this.map.layerContainerOriginPx;
  92. var pinchOrigin = this.pinchOrigin;
  93. var current = (this.preserveCenter) ?
  94. this.map.getPixelFromLonLat(this.map.getCenter()) : evt.xy;
  95. var dx = Math.round((containerOrigin.x + current.x - pinchOrigin.x) + (scale - 1) * (containerOrigin.x - pinchOrigin.x));
  96. var dy = Math.round((containerOrigin.y + current.y - pinchOrigin.y) + (scale - 1) * (containerOrigin.y - pinchOrigin.y));
  97. this.map.applyTransform(dx, dy, scale);
  98. this.currentCenter = current;
  99. },
  100. /**
  101. * Method: pinchDone
  102. *
  103. * Parameters:
  104. * evt - {Event}
  105. * start - {Object} pinch data object related to the touchstart event that
  106. * started the pinch gesture.
  107. * last - {Object} pinch data object related to the last touchmove event
  108. * of the pinch gesture. This give us the final scale of the pinch.
  109. */
  110. pinchDone: function(evt, start, last) {
  111. this.map.applyTransform();
  112. var zoom = this.map.getZoomForResolution(this.map.getResolution() / last.scale, true);
  113. if (zoom !== this.map.getZoom() || !this.currentCenter.equals(this.pinchOrigin)) {
  114. var resolution = this.map.getResolutionForZoom(zoom);
  115. var location = this.map.getLonLatFromPixel(this.pinchOrigin);
  116. var zoomPixel = this.currentCenter;
  117. var size = this.map.getSize();
  118. location.lon += resolution * ((size.w / 2) - zoomPixel.x);
  119. location.lat -= resolution * ((size.h / 2) - zoomPixel.y);
  120. // Force a reflow before calling setCenter. This is to work
  121. // around an issue occuring in iOS.
  122. //
  123. // See https://github.com/openlayers/openlayers/pull/351.
  124. //
  125. // Without a reflow setting the layer container div's top left
  126. // style properties to "0px" - as done in Map.moveTo when zoom
  127. // is changed - won't actually correctly reposition the layer
  128. // container div.
  129. //
  130. // Also, we need to use a statement that the Google Closure
  131. // compiler won't optimize away.
  132. this.map.div.clientWidth = this.map.div.clientWidth;
  133. this.map.setCenter(location, zoom);
  134. }
  135. },
  136. CLASS_NAME: "OpenLayers.Control.PinchZoom"
  137. });