@mapwhit/tilerenderer 0.47.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (356) hide show
  1. package/LICENSE.txt +87 -0
  2. package/README.md +25 -0
  3. package/build/min/.dir +0 -0
  4. package/build/min/package.json +3 -0
  5. package/build/min/src/shaders/_prelude.fragment.glsl.txt +13 -0
  6. package/build/min/src/shaders/_prelude.vertex.glsl.txt +14 -0
  7. package/build/min/src/shaders/background.fragment.glsl.txt +5 -0
  8. package/build/min/src/shaders/background.vertex.glsl.txt +1 -0
  9. package/build/min/src/shaders/background_pattern.fragment.glsl.txt +5 -0
  10. package/build/min/src/shaders/background_pattern.vertex.glsl.txt +1 -0
  11. package/build/min/src/shaders/circle.fragment.glsl.txt +20 -0
  12. package/build/min/src/shaders/circle.vertex.glsl.txt +17 -0
  13. package/build/min/src/shaders/clipping_mask.fragment.glsl.txt +1 -0
  14. package/build/min/src/shaders/clipping_mask.vertex.glsl.txt +1 -0
  15. package/build/min/src/shaders/collision_box.fragment.glsl.txt +1 -0
  16. package/build/min/src/shaders/collision_box.vertex.glsl.txt +1 -0
  17. package/build/min/src/shaders/collision_circle.fragment.glsl.txt +1 -0
  18. package/build/min/src/shaders/collision_circle.vertex.glsl.txt +1 -0
  19. package/build/min/src/shaders/debug.fragment.glsl.txt +1 -0
  20. package/build/min/src/shaders/debug.vertex.glsl.txt +1 -0
  21. package/build/min/src/shaders/fill.fragment.glsl.txt +10 -0
  22. package/build/min/src/shaders/fill.vertex.glsl.txt +7 -0
  23. package/build/min/src/shaders/fill_extrusion.fragment.glsl.txt +13 -0
  24. package/build/min/src/shaders/fill_extrusion.vertex.glsl.txt +9 -0
  25. package/build/min/src/shaders/fill_extrusion_pattern.fragment.glsl.txt +15 -0
  26. package/build/min/src/shaders/fill_extrusion_pattern.vertex.glsl.txt +11 -0
  27. package/build/min/src/shaders/fill_outline.fragment.glsl.txt +10 -0
  28. package/build/min/src/shaders/fill_outline.vertex.glsl.txt +7 -0
  29. package/build/min/src/shaders/fill_outline_pattern.fragment.glsl.txt +13 -0
  30. package/build/min/src/shaders/fill_outline_pattern.vertex.glsl.txt +9 -0
  31. package/build/min/src/shaders/fill_pattern.fragment.glsl.txt +13 -0
  32. package/build/min/src/shaders/fill_pattern.vertex.glsl.txt +9 -0
  33. package/build/min/src/shaders/heatmap.fragment.glsl.txt +10 -0
  34. package/build/min/src/shaders/heatmap.vertex.glsl.txt +8 -0
  35. package/build/min/src/shaders/heatmap_texture.fragment.glsl.txt +5 -0
  36. package/build/min/src/shaders/heatmap_texture.vertex.glsl.txt +1 -0
  37. package/build/min/src/shaders/hillshade.fragment.glsl.txt +7 -0
  38. package/build/min/src/shaders/hillshade.vertex.glsl.txt +1 -0
  39. package/build/min/src/shaders/hillshade_prepare.fragment.glsl.txt +8 -0
  40. package/build/min/src/shaders/hillshade_prepare.vertex.glsl.txt +1 -0
  41. package/build/min/src/shaders/line.fragment.glsl.txt +12 -0
  42. package/build/min/src/shaders/line.vertex.glsl.txt +17 -0
  43. package/build/min/src/shaders/line_gradient.fragment.glsl.txt +10 -0
  44. package/build/min/src/shaders/line_gradient.vertex.glsl.txt +16 -0
  45. package/build/min/src/shaders/line_pattern.fragment.glsl.txt +15 -0
  46. package/build/min/src/shaders/line_pattern.vertex.glsl.txt +20 -0
  47. package/build/min/src/shaders/line_sdf.fragment.glsl.txt +17 -0
  48. package/build/min/src/shaders/line_sdf.vertex.glsl.txt +20 -0
  49. package/build/min/src/shaders/raster.fragment.glsl.txt +5 -0
  50. package/build/min/src/shaders/raster.vertex.glsl.txt +1 -0
  51. package/build/min/src/shaders/symbol_icon.fragment.glsl.txt +9 -0
  52. package/build/min/src/shaders/symbol_icon.vertex.glsl.txt +5 -0
  53. package/build/min/src/shaders/symbol_sdf.fragment.glsl.txt +19 -0
  54. package/build/min/src/shaders/symbol_sdf.vertex.glsl.txt +13 -0
  55. package/package.json +44 -0
  56. package/src/css/mapbox-gl.css +506 -0
  57. package/src/css/svg/mapboxgl-ctrl-attrib.svg +3 -0
  58. package/src/css/svg/mapboxgl-ctrl-compass.svg +4 -0
  59. package/src/css/svg/mapboxgl-ctrl-fullscreen.svg +3 -0
  60. package/src/css/svg/mapboxgl-ctrl-geolocate-background.svg +3 -0
  61. package/src/css/svg/mapboxgl-ctrl-geolocate.svg +3 -0
  62. package/src/css/svg/mapboxgl-ctrl-logo-compact.svg +2 -0
  63. package/src/css/svg/mapboxgl-ctrl-logo.svg +1 -0
  64. package/src/css/svg/mapboxgl-ctrl-shrink.svg +3 -0
  65. package/src/css/svg/mapboxgl-ctrl-zoom-in.svg +3 -0
  66. package/src/css/svg/mapboxgl-ctrl-zoom-out.svg +3 -0
  67. package/src/data/array_types.js +1138 -0
  68. package/src/data/bucket/circle_attributes.js +5 -0
  69. package/src/data/bucket/circle_bucket.js +118 -0
  70. package/src/data/bucket/fill_attributes.js +5 -0
  71. package/src/data/bucket/fill_bucket.js +166 -0
  72. package/src/data/bucket/fill_extrusion_attributes.js +11 -0
  73. package/src/data/bucket/fill_extrusion_bucket.js +247 -0
  74. package/src/data/bucket/heatmap_bucket.js +12 -0
  75. package/src/data/bucket/line_attributes.js +11 -0
  76. package/src/data/bucket/line_bucket.js +625 -0
  77. package/src/data/bucket/pattern_attributes.js +9 -0
  78. package/src/data/bucket/pattern_bucket_features.js +44 -0
  79. package/src/data/bucket/symbol_attributes.js +95 -0
  80. package/src/data/bucket/symbol_bucket.js +697 -0
  81. package/src/data/bucket.js +53 -0
  82. package/src/data/dem_data.js +126 -0
  83. package/src/data/extent.js +17 -0
  84. package/src/data/feature_index.js +254 -0
  85. package/src/data/index_array_type.js +14 -0
  86. package/src/data/load_geometry.js +42 -0
  87. package/src/data/pos_attributes.js +3 -0
  88. package/src/data/program_configuration.js +782 -0
  89. package/src/data/raster_bounds_attributes.js +6 -0
  90. package/src/data/segment.js +63 -0
  91. package/src/geo/coordinate.js +78 -0
  92. package/src/geo/lng_lat.js +129 -0
  93. package/src/geo/lng_lat_bounds.js +253 -0
  94. package/src/geo/transform.js +605 -0
  95. package/src/gl/color_mode.js +21 -0
  96. package/src/gl/context.js +193 -0
  97. package/src/gl/cull_face_mode.js +22 -0
  98. package/src/gl/depth_mode.js +18 -0
  99. package/src/gl/framebuffer.js +28 -0
  100. package/src/gl/index_buffer.js +52 -0
  101. package/src/gl/stencil_mode.js +17 -0
  102. package/src/gl/types.js +0 -0
  103. package/src/gl/value.js +676 -0
  104. package/src/gl/vertex_buffer.js +101 -0
  105. package/src/index.js +50 -0
  106. package/src/render/draw_background.js +60 -0
  107. package/src/render/draw_circle.js +55 -0
  108. package/src/render/draw_collision_debug.js +45 -0
  109. package/src/render/draw_debug.js +429 -0
  110. package/src/render/draw_fill.js +143 -0
  111. package/src/render/draw_fill_extrusion.js +101 -0
  112. package/src/render/draw_heatmap.js +159 -0
  113. package/src/render/draw_hillshade.js +144 -0
  114. package/src/render/draw_line.js +99 -0
  115. package/src/render/draw_raster.js +151 -0
  116. package/src/render/draw_symbol.js +231 -0
  117. package/src/render/glyph_atlas.js +55 -0
  118. package/src/render/glyph_manager.js +145 -0
  119. package/src/render/image_atlas.js +97 -0
  120. package/src/render/image_manager.js +183 -0
  121. package/src/render/line_atlas.js +139 -0
  122. package/src/render/painter.js +483 -0
  123. package/src/render/program/background_program.js +46 -0
  124. package/src/render/program/circle_program.js +40 -0
  125. package/src/render/program/clipping_mask_program.js +11 -0
  126. package/src/render/program/collision_program.js +28 -0
  127. package/src/render/program/debug_program.js +13 -0
  128. package/src/render/program/fill_extrusion_program.js +76 -0
  129. package/src/render/program/fill_program.js +60 -0
  130. package/src/render/program/heatmap_program.js +46 -0
  131. package/src/render/program/hillshade_program.js +77 -0
  132. package/src/render/program/line_program.js +119 -0
  133. package/src/render/program/pattern.js +57 -0
  134. package/src/render/program/program_uniforms.js +46 -0
  135. package/src/render/program/raster_program.js +50 -0
  136. package/src/render/program/symbol_program.js +112 -0
  137. package/src/render/program.js +133 -0
  138. package/src/render/texture.js +88 -0
  139. package/src/render/tile_mask.js +108 -0
  140. package/src/render/uniform_binding.js +129 -0
  141. package/src/render/vertex_array_object.js +155 -0
  142. package/src/shaders/README.md +42 -0
  143. package/src/shaders/_prelude.fragment.glsl +17 -0
  144. package/src/shaders/_prelude.vertex.glsl +73 -0
  145. package/src/shaders/background.fragment.glsl +10 -0
  146. package/src/shaders/background.vertex.glsl +7 -0
  147. package/src/shaders/background_pattern.fragment.glsl +28 -0
  148. package/src/shaders/background_pattern.vertex.glsl +20 -0
  149. package/src/shaders/circle.fragment.glsl +39 -0
  150. package/src/shaders/circle.vertex.glsl +63 -0
  151. package/src/shaders/clipping_mask.fragment.glsl +3 -0
  152. package/src/shaders/clipping_mask.vertex.glsl +7 -0
  153. package/src/shaders/collision_box.fragment.glsl +21 -0
  154. package/src/shaders/collision_box.vertex.glsl +26 -0
  155. package/src/shaders/collision_circle.fragment.glsl +34 -0
  156. package/src/shaders/collision_circle.vertex.glsl +36 -0
  157. package/src/shaders/debug.fragment.glsl +5 -0
  158. package/src/shaders/debug.vertex.glsl +7 -0
  159. package/src/shaders/encode_attribute.js +19 -0
  160. package/src/shaders/fill.fragment.glsl +13 -0
  161. package/src/shaders/fill.vertex.glsl +13 -0
  162. package/src/shaders/fill_extrusion.fragment.glsl +16 -0
  163. package/src/shaders/fill_extrusion.vertex.glsl +66 -0
  164. package/src/shaders/fill_extrusion_pattern.fragment.glsl +41 -0
  165. package/src/shaders/fill_extrusion_pattern.vertex.glsl +76 -0
  166. package/src/shaders/fill_outline.fragment.glsl +17 -0
  167. package/src/shaders/fill_outline.vertex.glsl +17 -0
  168. package/src/shaders/fill_outline_pattern.fragment.glsl +43 -0
  169. package/src/shaders/fill_outline_pattern.vertex.glsl +41 -0
  170. package/src/shaders/fill_pattern.fragment.glsl +36 -0
  171. package/src/shaders/fill_pattern.vertex.glsl +36 -0
  172. package/src/shaders/heatmap.fragment.glsl +21 -0
  173. package/src/shaders/heatmap.vertex.glsl +53 -0
  174. package/src/shaders/heatmap_texture.fragment.glsl +14 -0
  175. package/src/shaders/heatmap_texture.vertex.glsl +11 -0
  176. package/src/shaders/hillshade.fragment.glsl +52 -0
  177. package/src/shaders/hillshade.vertex.glsl +11 -0
  178. package/src/shaders/hillshade_prepare.fragment.glsl +72 -0
  179. package/src/shaders/hillshade_prepare.vertex.glsl +15 -0
  180. package/src/shaders/index.js +194 -0
  181. package/src/shaders/line.fragment.glsl +28 -0
  182. package/src/shaders/line.vertex.glsl +84 -0
  183. package/src/shaders/line_gradient.fragment.glsl +34 -0
  184. package/src/shaders/line_gradient.vertex.glsl +84 -0
  185. package/src/shaders/line_pattern.fragment.glsl +69 -0
  186. package/src/shaders/line_pattern.vertex.glsl +88 -0
  187. package/src/shaders/line_sdf.fragment.glsl +44 -0
  188. package/src/shaders/line_sdf.vertex.glsl +95 -0
  189. package/src/shaders/raster.fragment.glsl +52 -0
  190. package/src/shaders/raster.vertex.glsl +21 -0
  191. package/src/shaders/symbol_icon.fragment.glsl +17 -0
  192. package/src/shaders/symbol_icon.vertex.glsl +91 -0
  193. package/src/shaders/symbol_sdf.fragment.glsl +50 -0
  194. package/src/shaders/symbol_sdf.vertex.glsl +117 -0
  195. package/src/source/geojson_source.js +267 -0
  196. package/src/source/geojson_worker_source.js +210 -0
  197. package/src/source/geojson_wrapper.js +67 -0
  198. package/src/source/image_source.js +213 -0
  199. package/src/source/load_tilejson.js +40 -0
  200. package/src/source/pixels_to_tile_units.js +17 -0
  201. package/src/source/query_features.js +198 -0
  202. package/src/source/raster_dem_tile_source.js +140 -0
  203. package/src/source/raster_dem_tile_worker_source.js +26 -0
  204. package/src/source/raster_tile_source.js +126 -0
  205. package/src/source/rtl_text_plugin.js +63 -0
  206. package/src/source/source.js +75 -0
  207. package/src/source/source_cache.js +794 -0
  208. package/src/source/source_state.js +55 -0
  209. package/src/source/tile.js +332 -0
  210. package/src/source/tile_bounds.js +40 -0
  211. package/src/source/tile_cache.js +122 -0
  212. package/src/source/tile_id.js +150 -0
  213. package/src/source/vector_tile_source.js +144 -0
  214. package/src/source/vector_tile_worker_source.js +126 -0
  215. package/src/source/worker.js +175 -0
  216. package/src/source/worker_source.js +14 -0
  217. package/src/source/worker_tile.js +199 -0
  218. package/src/style/create_style_layer.js +25 -0
  219. package/src/style/evaluation_parameters.js +45 -0
  220. package/src/style/light.js +112 -0
  221. package/src/style/load_glyph_range.js +17 -0
  222. package/src/style/load_sprite.js +26 -0
  223. package/src/style/parse_glyph_pbf.js +45 -0
  224. package/src/style/pauseable_placement.js +88 -0
  225. package/src/style/properties.js +691 -0
  226. package/src/style/query_utils.js +39 -0
  227. package/src/style/style.js +955 -0
  228. package/src/style/style_layer/background_style_layer.js +11 -0
  229. package/src/style/style_layer/background_style_layer_properties.js +25 -0
  230. package/src/style/style_layer/circle_style_layer.js +93 -0
  231. package/src/style/style_layer/circle_style_layer_properties.js +76 -0
  232. package/src/style/style_layer/fill_extrusion_style_layer.js +194 -0
  233. package/src/style/style_layer/fill_extrusion_style_layer_properties.js +56 -0
  234. package/src/style/style_layer/fill_style_layer.js +46 -0
  235. package/src/style/style_layer/fill_style_layer_properties.js +45 -0
  236. package/src/style/style_layer/heatmap_style_layer.js +51 -0
  237. package/src/style/style_layer/heatmap_style_layer_properties.js +52 -0
  238. package/src/style/style_layer/hillshade_style_layer.js +15 -0
  239. package/src/style/style_layer/hillshade_style_layer_properties.js +43 -0
  240. package/src/style/style_layer/line_style_layer.js +129 -0
  241. package/src/style/style_layer/line_style_layer_properties.js +104 -0
  242. package/src/style/style_layer/raster_style_layer.js +11 -0
  243. package/src/style/style_layer/raster_style_layer_properties.js +55 -0
  244. package/src/style/style_layer/symbol_style_layer.js +66 -0
  245. package/src/style/style_layer/symbol_style_layer_properties.js +288 -0
  246. package/src/style/style_layer.js +183 -0
  247. package/src/style/style_layer_index.js +61 -0
  248. package/src/style/zoom_history.js +36 -0
  249. package/src/style-spec/deref.js +51 -0
  250. package/src/style-spec/error/parsing_error.js +8 -0
  251. package/src/style-spec/error/validation_error.js +10 -0
  252. package/src/style-spec/expression/compound_expression.js +118 -0
  253. package/src/style-spec/expression/definitions/array.js +82 -0
  254. package/src/style-spec/expression/definitions/assertion.js +69 -0
  255. package/src/style-spec/expression/definitions/at.js +57 -0
  256. package/src/style-spec/expression/definitions/case.js +73 -0
  257. package/src/style-spec/expression/definitions/coalesce.js +68 -0
  258. package/src/style-spec/expression/definitions/coercion.js +96 -0
  259. package/src/style-spec/expression/definitions/collator.js +102 -0
  260. package/src/style-spec/expression/definitions/equals.js +93 -0
  261. package/src/style-spec/expression/definitions/index.js +407 -0
  262. package/src/style-spec/expression/definitions/interpolate.js +235 -0
  263. package/src/style-spec/expression/definitions/length.js +54 -0
  264. package/src/style-spec/expression/definitions/let.js +60 -0
  265. package/src/style-spec/expression/definitions/literal.js +64 -0
  266. package/src/style-spec/expression/definitions/match.js +142 -0
  267. package/src/style-spec/expression/definitions/step.js +116 -0
  268. package/src/style-spec/expression/definitions/var.js +38 -0
  269. package/src/style-spec/expression/evaluation_context.js +35 -0
  270. package/src/style-spec/expression/index.js +329 -0
  271. package/src/style-spec/expression/is_constant.js +63 -0
  272. package/src/style-spec/expression/parsing_context.js +213 -0
  273. package/src/style-spec/expression/parsing_error.js +9 -0
  274. package/src/style-spec/expression/runtime_error.js +12 -0
  275. package/src/style-spec/expression/scope.js +34 -0
  276. package/src/style-spec/expression/stops.js +37 -0
  277. package/src/style-spec/expression/types.js +77 -0
  278. package/src/style-spec/expression/values.js +126 -0
  279. package/src/style-spec/feature_filter/README.md +55 -0
  280. package/src/style-spec/feature_filter/index.js +158 -0
  281. package/src/style-spec/function/convert.js +256 -0
  282. package/src/style-spec/function/index.js +299 -0
  283. package/src/style-spec/group_by_layout.js +68 -0
  284. package/src/style-spec/reference/v8.json +5356 -0
  285. package/src/style-spec/util/color.js +73 -0
  286. package/src/style-spec/util/color_spaces.js +128 -0
  287. package/src/style-spec/util/eval_support.js +8 -0
  288. package/src/style-spec/util/get_type.js +18 -0
  289. package/src/style-spec/util/interpolate.js +21 -0
  290. package/src/style-spec/util/properties.js +17 -0
  291. package/src/style-spec/util/ref_properties.js +1 -0
  292. package/src/style-spec/util/result.js +19 -0
  293. package/src/symbol/anchor.js +21 -0
  294. package/src/symbol/check_max_angle.js +75 -0
  295. package/src/symbol/clip_line.js +73 -0
  296. package/src/symbol/collision_feature.js +230 -0
  297. package/src/symbol/collision_index.js +379 -0
  298. package/src/symbol/cross_tile_symbol_index.js +270 -0
  299. package/src/symbol/get_anchors.js +177 -0
  300. package/src/symbol/grid_index.js +318 -0
  301. package/src/symbol/mergelines.js +75 -0
  302. package/src/symbol/opacity_state.js +21 -0
  303. package/src/symbol/placement.js +563 -0
  304. package/src/symbol/projection.js +601 -0
  305. package/src/symbol/quads.js +173 -0
  306. package/src/symbol/shaping.js +347 -0
  307. package/src/symbol/symbol_layout.js +519 -0
  308. package/src/symbol/symbol_size.js +110 -0
  309. package/src/symbol/transform_text.js +16 -0
  310. package/src/ui/anchor.js +24 -0
  311. package/src/ui/bind_handlers.js +199 -0
  312. package/src/ui/camera.js +954 -0
  313. package/src/ui/events.js +210 -0
  314. package/src/ui/handler/box_zoom.js +151 -0
  315. package/src/ui/handler/dblclick_zoom.js +91 -0
  316. package/src/ui/handler/drag_pan.js +285 -0
  317. package/src/ui/handler/drag_rotate.js +290 -0
  318. package/src/ui/handler/frame.js +28 -0
  319. package/src/ui/handler/inertia.js +45 -0
  320. package/src/ui/handler/keyboard.js +148 -0
  321. package/src/ui/handler/scroll_zoom.js +284 -0
  322. package/src/ui/handler/touch_zoom_rotate.js +263 -0
  323. package/src/ui/map.js +1645 -0
  324. package/src/util/actor.js +104 -0
  325. package/src/util/async.js +23 -0
  326. package/src/util/browser.js +61 -0
  327. package/src/util/callback.js +26 -0
  328. package/src/util/classify_rings.js +43 -0
  329. package/src/util/color_ramp.js +24 -0
  330. package/src/util/config.js +24 -0
  331. package/src/util/dictionary_coder.js +25 -0
  332. package/src/util/dispatcher.js +68 -0
  333. package/src/util/dom.js +102 -0
  334. package/src/util/evented.js +182 -0
  335. package/src/util/find_pole_of_inaccessibility.js +129 -0
  336. package/src/util/global_worker_pool.js +15 -0
  337. package/src/util/image.js +124 -0
  338. package/src/util/interpolate.js +5 -0
  339. package/src/util/intersection_tests.js +207 -0
  340. package/src/util/is_char_in_unicode_block.js +287 -0
  341. package/src/util/loader/image.js +32 -0
  342. package/src/util/object.js +178 -0
  343. package/src/util/script_detection.js +337 -0
  344. package/src/util/struct_array.js +197 -0
  345. package/src/util/task_queue.js +57 -0
  346. package/src/util/throttle.js +26 -0
  347. package/src/util/tile_cover.js +114 -0
  348. package/src/util/token.js +13 -0
  349. package/src/util/unique_id.js +12 -0
  350. package/src/util/util.js +192 -0
  351. package/src/util/vectortile_to_geojson.js +44 -0
  352. package/src/util/verticalize_punctuation.js +112 -0
  353. package/src/util/warn.js +21 -0
  354. package/src/util/web_worker.js +5 -0
  355. package/src/util/web_worker_transfer.js +228 -0
  356. package/src/util/worker_pool.js +41 -0
@@ -0,0 +1,954 @@
1
+ const { bindAll, deepEqual } = require('../util/object');
2
+ const { clamp, wrap, ease: defaultEasing } = require('../util/util');
3
+ const warn = require('../util/warn');
4
+ const interpolate = require('../util/interpolate');
5
+ const browser = require('../util/browser');
6
+ const LngLat = require('../geo/lng_lat');
7
+ const LngLatBounds = require('../geo/lng_lat_bounds');
8
+ const Point = require('@mapbox/point-geometry');
9
+ const { Event, Evented } = require('../util/evented');
10
+
11
+ /**
12
+ * Options common to {@link Map#jumpTo}, {@link Map#easeTo}, and {@link Map#flyTo}, controlling the desired location,
13
+ * zoom, bearing, and pitch of the camera. All properties are optional, and when a property is omitted, the current
14
+ * camera value for that property will remain unchanged.
15
+ *
16
+ * @typedef {Object} CameraOptions
17
+ * @property {LngLatLike} center The desired center.
18
+ * @property {number} zoom The desired zoom level.
19
+ * @property {number} bearing The desired bearing, in degrees. The bearing is the compass direction that
20
+ * is "up"; for example, a bearing of 90° orients the map so that east is up.
21
+ * @property {number} pitch The desired pitch, in degrees.
22
+ * @property {LngLatLike} around If `zoom` is specified, `around` determines the point around which the zoom is centered.
23
+ */
24
+
25
+ /**
26
+ * Options common to map movement methods that involve animation, such as {@link Map#panBy} and
27
+ * {@link Map#easeTo}, controlling the duration and easing function of the animation. All properties
28
+ * are optional.
29
+ *
30
+ * @typedef {Object} AnimationOptions
31
+ * @property {number} duration The animation's duration, measured in milliseconds.
32
+ * @property {Function} easing A function taking a time in the range 0..1 and returning a number where 0 is
33
+ * the initial state and 1 is the final state.
34
+ * @property {PointLike} offset of the target center relative to real map container center at the end of animation.
35
+ * @property {boolean} animate If `false`, no animation will occur.
36
+ */
37
+
38
+ /**
39
+ * Options for setting padding on a call to {@link Map#fitBounds}. All properties of this object must be
40
+ * non-negative integers.
41
+ *
42
+ * @typedef {Object} PaddingOptions
43
+ * @property {number} top Padding in pixels from the top of the map canvas.
44
+ * @property {number} bottom Padding in pixels from the bottom of the map canvas.
45
+ * @property {number} left Padding in pixels from the left of the map canvas.
46
+ * @property {number} right Padding in pixels from the right of the map canvas.
47
+ */
48
+
49
+ class Camera extends Evented {
50
+ constructor(transform, options) {
51
+ super();
52
+ this._moving = false;
53
+ this._zooming = false;
54
+ this.transform = transform;
55
+ this._bearingSnap = options.bearingSnap;
56
+
57
+ bindAll(['_renderFrameCallback'], this);
58
+ }
59
+
60
+ /**
61
+ * Returns the map's geographical centerpoint.
62
+ *
63
+ * @memberof Map#
64
+ * @returns The map's geographical centerpoint.
65
+ */
66
+ getCenter() {
67
+ return this.transform.center;
68
+ }
69
+
70
+ /**
71
+ * Sets the map's geographical centerpoint. Equivalent to `jumpTo({center: center})`.
72
+ *
73
+ * @memberof Map#
74
+ * @param center The centerpoint to set.
75
+ * @param eventData Additional properties to be added to event objects of events triggered by this method.
76
+ * @fires movestart
77
+ * @fires moveend
78
+ * @returns {Map} `this`
79
+ * @example
80
+ * map.setCenter([-74, 38]);
81
+ * @see [Move symbol with the keyboard](https://www.mapbox.com/mapbox-gl-js/example/rotating-controllable-marker/)
82
+ */
83
+ setCenter(center, eventData) {
84
+ return this.jumpTo({ center: center }, eventData);
85
+ }
86
+
87
+ /**
88
+ * Pans the map by the specified offest.
89
+ *
90
+ * @memberof Map#
91
+ * @param offset `x` and `y` coordinates by which to pan the map.
92
+ * @param options
93
+ * @param eventData Additional properties to be added to event objects of events triggered by this method.
94
+ * @fires movestart
95
+ * @fires moveend
96
+ * @returns {Map} `this`
97
+ * @see [Navigate the map with game-like controls](https://www.mapbox.com/mapbox-gl-js/example/game-controls/)
98
+ */
99
+ panBy(offset, options, eventData) {
100
+ offset = Point.convert(offset).mult(-1);
101
+ return this.panTo(this.transform.center, Object.assign({ offset }, options), eventData);
102
+ }
103
+
104
+ /**
105
+ * Pans the map to the specified location, with an animated transition.
106
+ *
107
+ * @memberof Map#
108
+ * @param lnglat The location to pan the map to.
109
+ * @param options
110
+ * @param eventData Additional properties to be added to event objects of events triggered by this method.
111
+ * @fires movestart
112
+ * @fires moveend
113
+ * @returns {Map} `this`
114
+ */
115
+ panTo(lnglat, options, eventData) {
116
+ return this.easeTo(
117
+ Object.assign(
118
+ {
119
+ center: lnglat
120
+ },
121
+ options
122
+ ),
123
+ eventData
124
+ );
125
+ }
126
+
127
+ /**
128
+ * Returns the map's current zoom level.
129
+ *
130
+ * @memberof Map#
131
+ * @returns The map's current zoom level.
132
+ */
133
+ getZoom() {
134
+ return this.transform.zoom;
135
+ }
136
+
137
+ /**
138
+ * Sets the map's zoom level. Equivalent to `jumpTo({zoom: zoom})`.
139
+ *
140
+ * @memberof Map#
141
+ * @param zoom The zoom level to set (0-20).
142
+ * @param eventData Additional properties to be added to event objects of events triggered by this method.
143
+ * @fires movestart
144
+ * @fires zoomstart
145
+ * @fires move
146
+ * @fires zoom
147
+ * @fires moveend
148
+ * @fires zoomend
149
+ * @returns {Map} `this`
150
+ * @example
151
+ * // zoom the map to 5
152
+ * map.setZoom(5);
153
+ */
154
+ setZoom(zoom, eventData) {
155
+ this.jumpTo({ zoom: zoom }, eventData);
156
+ return this;
157
+ }
158
+
159
+ /**
160
+ * Zooms the map to the specified zoom level, with an animated transition.
161
+ *
162
+ * @memberof Map#
163
+ * @param zoom The zoom level to transition to.
164
+ * @param options
165
+ * @param eventData Additional properties to be added to event objects of events triggered by this method.
166
+ * @fires movestart
167
+ * @fires zoomstart
168
+ * @fires move
169
+ * @fires zoom
170
+ * @fires moveend
171
+ * @fires zoomend
172
+ * @returns {Map} `this`
173
+ */
174
+ zoomTo(zoom, options, eventData) {
175
+ return this.easeTo(
176
+ Object.assign(
177
+ {
178
+ zoom: zoom
179
+ },
180
+ options
181
+ ),
182
+ eventData
183
+ );
184
+ }
185
+
186
+ /**
187
+ * Increases the map's zoom level by 1.
188
+ *
189
+ * @memberof Map#
190
+ * @param options
191
+ * @param eventData Additional properties to be added to event objects of events triggered by this method.
192
+ * @fires movestart
193
+ * @fires zoomstart
194
+ * @fires move
195
+ * @fires zoom
196
+ * @fires moveend
197
+ * @fires zoomend
198
+ * @returns {Map} `this`
199
+ */
200
+ zoomIn(options, eventData) {
201
+ this.zoomTo(this.getZoom() + 1, options, eventData);
202
+ return this;
203
+ }
204
+
205
+ /**
206
+ * Decreases the map's zoom level by 1.
207
+ *
208
+ * @memberof Map#
209
+ * @param options
210
+ * @param eventData Additional properties to be added to event objects of events triggered by this method.
211
+ * @fires movestart
212
+ * @fires zoomstart
213
+ * @fires move
214
+ * @fires zoom
215
+ * @fires moveend
216
+ * @fires zoomend
217
+ * @returns {Map} `this`
218
+ */
219
+ zoomOut(options, eventData) {
220
+ this.zoomTo(this.getZoom() - 1, options, eventData);
221
+ return this;
222
+ }
223
+
224
+ /**
225
+ * Returns the map's current bearing. The bearing is the compass direction that is \"up\"; for example, a bearing
226
+ * of 90° orients the map so that east is up.
227
+ *
228
+ * @memberof Map#
229
+ * @returns The map's current bearing.
230
+ * @see [Navigate the map with game-like controls](https://www.mapbox.com/mapbox-gl-js/example/game-controls/)
231
+ */
232
+ getBearing() {
233
+ return this.transform.bearing;
234
+ }
235
+
236
+ /**
237
+ * Sets the map's bearing (rotation). The bearing is the compass direction that is \"up\"; for example, a bearing
238
+ * of 90° orients the map so that east is up.
239
+ *
240
+ * Equivalent to `jumpTo({bearing: bearing})`.
241
+ *
242
+ * @memberof Map#
243
+ * @param bearing The desired bearing.
244
+ * @param eventData Additional properties to be added to event objects of events triggered by this method.
245
+ * @fires movestart
246
+ * @fires moveend
247
+ * @returns {Map} `this`
248
+ * @example
249
+ * // rotate the map to 90 degrees
250
+ * map.setBearing(90);
251
+ */
252
+ setBearing(bearing, eventData) {
253
+ this.jumpTo({ bearing: bearing }, eventData);
254
+ return this;
255
+ }
256
+
257
+ /**
258
+ * Rotates the map to the specified bearing, with an animated transition. The bearing is the compass direction
259
+ * that is \"up\"; for example, a bearing of 90° orients the map so that east is up.
260
+ *
261
+ * @memberof Map#
262
+ * @param bearing The desired bearing.
263
+ * @param options
264
+ * @param eventData Additional properties to be added to event objects of events triggered by this method.
265
+ * @fires movestart
266
+ * @fires moveend
267
+ * @returns {Map} `this`
268
+ */
269
+ rotateTo(bearing, options, eventData) {
270
+ return this.easeTo(
271
+ Object.assign(
272
+ {
273
+ bearing: bearing
274
+ },
275
+ options
276
+ ),
277
+ eventData
278
+ );
279
+ }
280
+
281
+ /**
282
+ * Rotates the map so that north is up (0° bearing), with an animated transition.
283
+ *
284
+ * @memberof Map#
285
+ * @param options
286
+ * @param eventData Additional properties to be added to event objects of events triggered by this method.
287
+ * @fires movestart
288
+ * @fires moveend
289
+ * @returns {Map} `this`
290
+ */
291
+ resetNorth(options, eventData) {
292
+ this.rotateTo(0, Object.assign({ duration: 1000 }, options), eventData);
293
+ return this;
294
+ }
295
+
296
+ /**
297
+ * Snaps the map so that north is up (0° bearing), if the current bearing is close enough to it (i.e. within the
298
+ * `bearingSnap` threshold).
299
+ *
300
+ * @memberof Map#
301
+ * @param options
302
+ * @param eventData Additional properties to be added to event objects of events triggered by this method.
303
+ * @fires movestart
304
+ * @fires moveend
305
+ * @returns {Map} `this`
306
+ */
307
+ snapToNorth(options, eventData) {
308
+ if (Math.abs(this.getBearing()) < this._bearingSnap) {
309
+ return this.resetNorth(options, eventData);
310
+ }
311
+ return this;
312
+ }
313
+
314
+ /**
315
+ * Returns the map's current pitch (tilt).
316
+ *
317
+ * @memberof Map#
318
+ * @returns The map's current pitch, measured in degrees away from the plane of the screen.
319
+ */
320
+ getPitch() {
321
+ return this.transform.pitch;
322
+ }
323
+
324
+ /**
325
+ * Sets the map's pitch (tilt). Equivalent to `jumpTo({pitch: pitch})`.
326
+ *
327
+ * @memberof Map#
328
+ * @param pitch The pitch to set, measured in degrees away from the plane of the screen (0-60).
329
+ * @param eventData Additional properties to be added to event objects of events triggered by this method.
330
+ * @fires pitchstart
331
+ * @fires movestart
332
+ * @fires moveend
333
+ * @returns {Map} `this`
334
+ */
335
+ setPitch(pitch, eventData) {
336
+ this.jumpTo({ pitch: pitch }, eventData);
337
+ return this;
338
+ }
339
+
340
+ /**
341
+ * Pans and zooms the map to contain its visible area within the specified geographical bounds.
342
+ * This function will also reset the map's bearing to 0 if bearing is nonzero.
343
+ *
344
+ * @memberof Map#
345
+ * @param bounds Center these bounds in the viewport and use the highest
346
+ * zoom level up to and including `Map#getMaxZoom()` that fits them in the viewport.
347
+ * @param options
348
+ * @param {number | PaddingOptions} [options.padding] The amount of padding in pixels to add to the given bounds.
349
+ * @param {boolean} [options.linear=false] If `true`, the map transitions using
350
+ * {@link Map#easeTo}. If `false`, the map transitions using {@link Map#flyTo}. See
351
+ * those functions and {@link AnimationOptions} for information about options available.
352
+ * @param {Function} [options.easing] An easing function for the animated transition. See {@link AnimationOptions}.
353
+ * @param {PointLike} [options.offset=[0, 0]] The center of the given bounds relative to the map's center, measured in pixels.
354
+ * @param {number} [options.maxZoom] The maximum zoom level to allow when the map view transitions to the specified bounds.
355
+ * @param eventData Additional properties to be added to event objects of events triggered by this method.
356
+ * @fires movestart
357
+ * @fires moveend
358
+ * @returns {Map} `this`
359
+ * @example
360
+ * var bbox = [[-79, 43], [-73, 45]];
361
+ * map.fitBounds(bbox, {
362
+ * padding: {top: 10, bottom:25, left: 15, right: 5}
363
+ * });
364
+ * @see [Fit a map to a bounding box](https://www.mapbox.com/mapbox-gl-js/example/fitbounds/)
365
+ */
366
+ fitBounds(bounds, options, eventData) {
367
+ options = Object.assign(
368
+ {
369
+ padding: {
370
+ top: 0,
371
+ bottom: 0,
372
+ right: 0,
373
+ left: 0
374
+ },
375
+ offset: [0, 0],
376
+ maxZoom: this.transform.maxZoom
377
+ },
378
+ options
379
+ );
380
+
381
+ if (typeof options.padding === 'number') {
382
+ const p = options.padding;
383
+ options.padding = {
384
+ top: p,
385
+ bottom: p,
386
+ right: p,
387
+ left: p
388
+ };
389
+ }
390
+ if (
391
+ !deepEqual(
392
+ Object.keys(options.padding).sort((a, b) => {
393
+ if (a < b) return -1;
394
+ if (a > b) return 1;
395
+ return 0;
396
+ }),
397
+ ['bottom', 'left', 'right', 'top']
398
+ )
399
+ ) {
400
+ warn.once("options.padding must be a positive number, or an Object with keys 'bottom', 'left', 'right', 'top'");
401
+ return this;
402
+ }
403
+
404
+ bounds = LngLatBounds.convert(bounds);
405
+
406
+ // we separate the passed padding option into two parts, the part that does not affect the map's center
407
+ // (lateral and vertical padding), and the part that does (paddingOffset). We add the padding offset
408
+ // to the options `offset` object where it can alter the map's center in the subsequent calls to
409
+ // `easeTo` and `flyTo`.
410
+ const paddingOffset = [
411
+ (options.padding.left - options.padding.right) / 2,
412
+ (options.padding.top - options.padding.bottom) / 2
413
+ ];
414
+ const lateralPadding = Math.min(options.padding.right, options.padding.left);
415
+ const verticalPadding = Math.min(options.padding.top, options.padding.bottom);
416
+ options.offset = [options.offset[0] + paddingOffset[0], options.offset[1] + paddingOffset[1]];
417
+
418
+ const offset = Point.convert(options.offset);
419
+ const tr = this.transform;
420
+ const nw = tr.project(bounds.getNorthWest());
421
+ const se = tr.project(bounds.getSouthEast());
422
+ const size = se.sub(nw);
423
+ const scaleX = (tr.width - lateralPadding * 2 - Math.abs(offset.x) * 2) / size.x;
424
+ const scaleY = (tr.height - verticalPadding * 2 - Math.abs(offset.y) * 2) / size.y;
425
+
426
+ if (scaleY < 0 || scaleX < 0) {
427
+ warn.once('Map cannot fit within canvas with the given bounds, padding, and/or offset.');
428
+ return this;
429
+ }
430
+
431
+ options.center = tr.unproject(nw.add(se).div(2));
432
+ options.zoom = Math.min(tr.scaleZoom(tr.scale * Math.min(scaleX, scaleY)), options.maxZoom);
433
+ options.bearing = 0;
434
+
435
+ return options.linear
436
+ ? this.easeTo(options, eventData)
437
+ : options.animate === false
438
+ ? this.jumpTo(options, eventData)
439
+ : this.flyTo(options, eventData);
440
+ }
441
+
442
+ /**
443
+ * Changes any combination of center, zoom, bearing, and pitch, without
444
+ * an animated transition. The map will retain its current values for any
445
+ * details not specified in `options`.
446
+ *
447
+ * @memberof Map#
448
+ * @param options
449
+ * @param eventData Additional properties to be added to event objects of events triggered by this method.
450
+ * @fires movestart
451
+ * @fires zoomstart
452
+ * @fires pitchstart
453
+ * @fires rotate
454
+ * @fires move
455
+ * @fires zoom
456
+ * @fires pitch
457
+ * @fires moveend
458
+ * @fires zoomend
459
+ * @fires pitchend
460
+ * @returns {Map} `this`
461
+ */
462
+ jumpTo(options, eventData) {
463
+ this.stop();
464
+
465
+ const tr = this.transform;
466
+ let zoomChanged = false;
467
+ let bearingChanged = false;
468
+ let pitchChanged = false;
469
+
470
+ if ('zoom' in options && tr.zoom !== +options.zoom) {
471
+ zoomChanged = true;
472
+ tr.zoom = +options.zoom;
473
+ }
474
+
475
+ if (options.center !== undefined) {
476
+ tr.center = LngLat.convert(options.center);
477
+ }
478
+
479
+ if ('bearing' in options && tr.bearing !== +options.bearing) {
480
+ bearingChanged = true;
481
+ tr.bearing = +options.bearing;
482
+ }
483
+
484
+ if ('pitch' in options && tr.pitch !== +options.pitch) {
485
+ pitchChanged = true;
486
+ tr.pitch = +options.pitch;
487
+ }
488
+
489
+ this.fire(new Event('movestart', eventData)).fire(new Event('move', eventData));
490
+
491
+ if (zoomChanged) {
492
+ this.fire(new Event('zoomstart', eventData))
493
+ .fire(new Event('zoom', eventData))
494
+ .fire(new Event('zoomend', eventData));
495
+ }
496
+
497
+ if (bearingChanged) {
498
+ this.fire(new Event('rotatestart', eventData))
499
+ .fire(new Event('rotate', eventData))
500
+ .fire(new Event('rotateend', eventData));
501
+ }
502
+
503
+ if (pitchChanged) {
504
+ this.fire(new Event('pitchstart', eventData))
505
+ .fire(new Event('pitch', eventData))
506
+ .fire(new Event('pitchend', eventData));
507
+ }
508
+
509
+ return this.fire(new Event('moveend', eventData));
510
+ }
511
+
512
+ /**
513
+ * Changes any combination of center, zoom, bearing, and pitch, with an animated transition
514
+ * between old and new values. The map will retain its current values for any
515
+ * details not specified in `options`.
516
+ *
517
+ * @memberof Map#
518
+ * @param options Options describing the destination and animation of the transition.
519
+ * Accepts {@link CameraOptions} and {@link AnimationOptions}.
520
+ * @param eventData Additional properties to be added to event objects of events triggered by this method.
521
+ * @fires movestart
522
+ * @fires zoomstart
523
+ * @fires pitchstart
524
+ * @fires rotate
525
+ * @fires move
526
+ * @fires zoom
527
+ * @fires pitch
528
+ * @fires moveend
529
+ * @fires zoomend
530
+ * @fires pitchend
531
+ * @returns {Map} `this`
532
+ * @see [Navigate the map with game-like controls](https://www.mapbox.com/mapbox-gl-js/example/game-controls/)
533
+ */
534
+ easeTo(options, eventData) {
535
+ this.stop();
536
+
537
+ options = Object.assign(
538
+ {
539
+ offset: [0, 0],
540
+ duration: 500,
541
+ easing: defaultEasing
542
+ },
543
+ options
544
+ );
545
+
546
+ if (options.animate === false) options.duration = 0;
547
+
548
+ const tr = this.transform;
549
+ const startZoom = this.getZoom();
550
+ const startBearing = this.getBearing();
551
+ const startPitch = this.getPitch();
552
+ const zoom = 'zoom' in options ? +options.zoom : startZoom;
553
+ const bearing = 'bearing' in options ? this._normalizeBearing(options.bearing, startBearing) : startBearing;
554
+ const pitch = 'pitch' in options ? +options.pitch : startPitch;
555
+
556
+ const pointAtOffset = tr.centerPoint.add(Point.convert(options.offset));
557
+ const locationAtOffset = tr.pointLocation(pointAtOffset);
558
+ const center = LngLat.convert(options.center || locationAtOffset);
559
+ this._normalizeCenter(center);
560
+
561
+ const from = tr.project(locationAtOffset);
562
+ const delta = tr.project(center).sub(from);
563
+ const finalScale = tr.zoomScale(zoom - startZoom);
564
+
565
+ let around;
566
+ let aroundPoint;
567
+
568
+ if (options.around) {
569
+ around = LngLat.convert(options.around);
570
+ aroundPoint = tr.locationPoint(around);
571
+ }
572
+
573
+ this._zooming = zoom !== startZoom;
574
+ this._rotating = startBearing !== bearing;
575
+ this._pitching = pitch !== startPitch;
576
+
577
+ this._prepareEase(eventData, options.noMoveStart);
578
+
579
+ clearTimeout(this._easeEndTimeoutID);
580
+
581
+ this._ease(
582
+ k => {
583
+ if (this._zooming) {
584
+ tr.zoom = interpolate(startZoom, zoom, k);
585
+ }
586
+ if (this._rotating) {
587
+ tr.bearing = interpolate(startBearing, bearing, k);
588
+ }
589
+ if (this._pitching) {
590
+ tr.pitch = interpolate(startPitch, pitch, k);
591
+ }
592
+
593
+ if (around) {
594
+ tr.setLocationAtPoint(around, aroundPoint);
595
+ } else {
596
+ const scale = tr.zoomScale(tr.zoom - startZoom);
597
+ const base = zoom > startZoom ? Math.min(2, finalScale) : Math.max(0.5, finalScale);
598
+ const speedup = base ** (1 - k);
599
+ const newCenter = tr.unproject(from.add(delta.mult(k * speedup)).mult(scale));
600
+ tr.setLocationAtPoint(tr.renderWorldCopies ? newCenter.wrap() : newCenter, pointAtOffset);
601
+ }
602
+
603
+ this._fireMoveEvents(eventData);
604
+ },
605
+ () => {
606
+ if (options.delayEndEvents) {
607
+ this._easeEndTimeoutID = setTimeout(() => this._afterEase(eventData), options.delayEndEvents);
608
+ } else {
609
+ this._afterEase(eventData);
610
+ }
611
+ },
612
+ options
613
+ );
614
+
615
+ return this;
616
+ }
617
+
618
+ _prepareEase(eventData, noMoveStart) {
619
+ this._moving = true;
620
+
621
+ if (!noMoveStart) {
622
+ this.fire(new Event('movestart', eventData));
623
+ }
624
+ if (this._zooming) {
625
+ this.fire(new Event('zoomstart', eventData));
626
+ }
627
+ if (this._rotating) {
628
+ this.fire(new Event('rotatestart', eventData));
629
+ }
630
+ if (this._pitching) {
631
+ this.fire(new Event('pitchstart', eventData));
632
+ }
633
+ }
634
+
635
+ _fireMoveEvents(eventData) {
636
+ this.fire(new Event('move', eventData));
637
+ if (this._zooming) {
638
+ this.fire(new Event('zoom', eventData));
639
+ }
640
+ if (this._rotating) {
641
+ this.fire(new Event('rotate', eventData));
642
+ }
643
+ if (this._pitching) {
644
+ this.fire(new Event('pitch', eventData));
645
+ }
646
+ }
647
+
648
+ _afterEase(eventData) {
649
+ const wasZooming = this._zooming;
650
+ const wasRotating = this._rotating;
651
+ const wasPitching = this._pitching;
652
+ this._moving = false;
653
+ this._zooming = false;
654
+ this._rotating = false;
655
+ this._pitching = false;
656
+
657
+ if (wasZooming) {
658
+ this.fire(new Event('zoomend', eventData));
659
+ }
660
+ if (wasRotating) {
661
+ this.fire(new Event('rotateend', eventData));
662
+ }
663
+ if (wasPitching) {
664
+ this.fire(new Event('pitchend', eventData));
665
+ }
666
+ this.fire(new Event('moveend', eventData));
667
+ }
668
+
669
+ /**
670
+ * Changes any combination of center, zoom, bearing, and pitch, animating the transition along a curve that
671
+ * evokes flight. The animation seamlessly incorporates zooming and panning to help
672
+ * the user maintain her bearings even after traversing a great distance.
673
+ *
674
+ * @memberof Map#
675
+ * @param {Object} options Options describing the destination and animation of the transition.
676
+ * Accepts {@link CameraOptions}, {@link AnimationOptions},
677
+ * and the following additional options.
678
+ * @param {number} [options.curve=1.42] The zooming "curve" that will occur along the
679
+ * flight path. A high value maximizes zooming for an exaggerated animation, while a low
680
+ * value minimizes zooming for an effect closer to {@link Map#easeTo}. 1.42 is the average
681
+ * value selected by participants in the user study discussed in
682
+ * [van Wijk (2003)](https://www.win.tue.nl/~vanwijk/zoompan.pdf). A value of
683
+ * `Math.pow(6, 0.25)` would be equivalent to the root mean squared average velocity. A
684
+ * value of 1 would produce a circular motion.
685
+ * @param {number} [options.minZoom] The zero-based zoom level at the peak of the flight path. If
686
+ * `options.curve` is specified, this option is ignored.
687
+ * @param {number} [options.speed=1.2] The average speed of the animation defined in relation to
688
+ * `options.curve`. A speed of 1.2 means that the map appears to move along the flight path
689
+ * by 1.2 times `options.curve` screenfuls every second. A _screenful_ is the map's visible span.
690
+ * It does not correspond to a fixed physical distance, but varies by zoom level.
691
+ * @param {number} [options.screenSpeed] The average speed of the animation measured in screenfuls
692
+ * per second, assuming a linear timing curve. If `options.speed` is specified, this option is ignored.
693
+ * @param {number} [options.maxDuration] The animation's maximum duration, measured in milliseconds.
694
+ * If duration exceeds maximum duration, it resets to 0.
695
+ * @param eventData Additional properties to be added to event objects of events triggered by this method.
696
+ * @fires movestart
697
+ * @fires zoomstart
698
+ * @fires pitchstart
699
+ * @fires move
700
+ * @fires zoom
701
+ * @fires rotate
702
+ * @fires pitch
703
+ * @fires moveend
704
+ * @fires zoomend
705
+ * @fires pitchend
706
+ * @returns {Map} `this`
707
+ * @example
708
+ * // fly with default options to null island
709
+ * map.flyTo({center: [0, 0], zoom: 9});
710
+ * // using flyTo options
711
+ * map.flyTo({
712
+ * center: [0, 0],
713
+ * zoom: 9,
714
+ * speed: 0.2,
715
+ * curve: 1,
716
+ * easing(t) {
717
+ * return t;
718
+ * }
719
+ * });
720
+ * @see [Fly to a location](https://www.mapbox.com/mapbox-gl-js/example/flyto/)
721
+ * @see [Slowly fly to a location](https://www.mapbox.com/mapbox-gl-js/example/flyto-options/)
722
+ * @see [Fly to a location based on scroll position](https://www.mapbox.com/mapbox-gl-js/example/scroll-fly-to/)
723
+ */
724
+ flyTo(options, eventData) {
725
+ // This method implements an “optimal path” animation, as detailed in:
726
+ //
727
+ // Van Wijk, Jarke J.; Nuij, Wim A. A. “Smooth and efficient zooming and panning.” INFOVIS
728
+ // ’03. pp. 15–22. <https://www.win.tue.nl/~vanwijk/zoompan.pdf#page=5>.
729
+ //
730
+ // Where applicable, local variable documentation begins with the associated variable or
731
+ // function in van Wijk (2003).
732
+
733
+ this.stop();
734
+
735
+ options = Object.assign(
736
+ {
737
+ offset: [0, 0],
738
+ speed: 1.2,
739
+ curve: 1.42,
740
+ easing: defaultEasing
741
+ },
742
+ options
743
+ );
744
+
745
+ const tr = this.transform;
746
+ const startZoom = this.getZoom();
747
+ const startBearing = this.getBearing();
748
+ const startPitch = this.getPitch();
749
+
750
+ const zoom = 'zoom' in options ? clamp(+options.zoom, tr.minZoom, tr.maxZoom) : startZoom;
751
+ const bearing = 'bearing' in options ? this._normalizeBearing(options.bearing, startBearing) : startBearing;
752
+ const pitch = 'pitch' in options ? +options.pitch : startPitch;
753
+
754
+ const scale = tr.zoomScale(zoom - startZoom);
755
+ const pointAtOffset = tr.centerPoint.add(Point.convert(options.offset));
756
+ const locationAtOffset = tr.pointLocation(pointAtOffset);
757
+ const center = LngLat.convert(options.center || locationAtOffset);
758
+ this._normalizeCenter(center);
759
+
760
+ const from = tr.project(locationAtOffset);
761
+ const delta = tr.project(center).sub(from);
762
+
763
+ let rho = options.curve;
764
+
765
+ // w₀: Initial visible span, measured in pixels at the initial scale.
766
+ const w0 = Math.max(tr.width, tr.height);
767
+ // w₁: Final visible span, measured in pixels with respect to the initial scale.
768
+ const w1 = w0 / scale;
769
+ // Length of the flight path as projected onto the ground plane, measured in pixels from
770
+ // the world image origin at the initial scale.
771
+ const u1 = delta.mag();
772
+
773
+ if ('minZoom' in options) {
774
+ const minZoom = clamp(Math.min(options.minZoom, startZoom, zoom), tr.minZoom, tr.maxZoom);
775
+ // w<sub>m</sub>: Maximum visible span, measured in pixels with respect to the initial
776
+ // scale.
777
+ const wMax = w0 / tr.zoomScale(minZoom - startZoom);
778
+ rho = Math.sqrt((wMax / u1) * 2);
779
+ }
780
+
781
+ // ρ²
782
+ const rho2 = rho * rho;
783
+
784
+ /**
785
+ * rᵢ: Returns the zoom-out factor at one end of the animation.
786
+ *
787
+ * @param i 0 for the ascent or 1 for the descent.
788
+ * @private
789
+ */
790
+ function r(i) {
791
+ const b = (w1 * w1 - w0 * w0 + (i ? -1 : 1) * rho2 * rho2 * u1 * u1) / (2 * (i ? w1 : w0) * rho2 * u1);
792
+ return Math.log(Math.sqrt(b * b + 1) - b);
793
+ }
794
+
795
+ function sinh(n) {
796
+ return (Math.exp(n) - Math.exp(-n)) / 2;
797
+ }
798
+ function cosh(n) {
799
+ return (Math.exp(n) + Math.exp(-n)) / 2;
800
+ }
801
+ function tanh(n) {
802
+ return sinh(n) / cosh(n);
803
+ }
804
+
805
+ // r₀: Zoom-out factor during ascent.
806
+ const r0 = r(0);
807
+
808
+ // w(s): Returns the visible span on the ground, measured in pixels with respect to the
809
+ // initial scale. Assumes an angular field of view of 2 arctan ½ ≈ 53°.
810
+ let w = function (s) {
811
+ return cosh(r0) / cosh(r0 + rho * s);
812
+ };
813
+
814
+ // u(s): Returns the distance along the flight path as projected onto the ground plane,
815
+ // measured in pixels from the world image origin at the initial scale.
816
+ let u = function (s) {
817
+ return (w0 * ((cosh(r0) * tanh(r0 + rho * s) - sinh(r0)) / rho2)) / u1;
818
+ };
819
+
820
+ // S: Total length of the flight path, measured in ρ-screenfuls.
821
+ let S = (r(1) - r0) / rho;
822
+
823
+ // When u₀ = u₁, the optimal path doesn’t require both ascent and descent.
824
+ if (Math.abs(u1) < 0.000001 || !Number.isFinite(S)) {
825
+ // Perform a more or less instantaneous transition if the path is too short.
826
+ if (Math.abs(w0 - w1) < 0.000001) return this.easeTo(options, eventData);
827
+
828
+ const k = w1 < w0 ? -1 : 1;
829
+ S = Math.abs(Math.log(w1 / w0)) / rho;
830
+
831
+ u = function () {
832
+ return 0;
833
+ };
834
+ w = function (s) {
835
+ return Math.exp(k * rho * s);
836
+ };
837
+ }
838
+
839
+ if ('duration' in options) {
840
+ options.duration = +options.duration;
841
+ } else {
842
+ const V = 'screenSpeed' in options ? +options.screenSpeed / rho : +options.speed;
843
+ options.duration = (1000 * S) / V;
844
+ }
845
+
846
+ if (options.maxDuration && options.duration > options.maxDuration) {
847
+ options.duration = 0;
848
+ }
849
+
850
+ this._zooming = true;
851
+ this._rotating = startBearing !== bearing;
852
+ this._pitching = pitch !== startPitch;
853
+
854
+ this._prepareEase(eventData, false);
855
+
856
+ this._ease(
857
+ k => {
858
+ // s: The distance traveled along the flight path, measured in ρ-screenfuls.
859
+ const s = k * S;
860
+ const scale = 1 / w(s);
861
+ tr.zoom = k === 1 ? zoom : startZoom + tr.scaleZoom(scale);
862
+
863
+ if (this._rotating) {
864
+ tr.bearing = interpolate(startBearing, bearing, k);
865
+ }
866
+ if (this._pitching) {
867
+ tr.pitch = interpolate(startPitch, pitch, k);
868
+ }
869
+
870
+ const newCenter = k === 1 ? center : tr.unproject(from.add(delta.mult(u(s))).mult(scale));
871
+ tr.setLocationAtPoint(tr.renderWorldCopies ? newCenter.wrap() : newCenter, pointAtOffset);
872
+
873
+ this._fireMoveEvents(eventData);
874
+ },
875
+ () => this._afterEase(eventData),
876
+ options
877
+ );
878
+
879
+ return this;
880
+ }
881
+
882
+ isEasing() {
883
+ return !!this._easeFrameId;
884
+ }
885
+
886
+ /**
887
+ * Stops any animated transition underway.
888
+ *
889
+ * @memberof Map#
890
+ * @returns {Map} `this`
891
+ */
892
+ stop() {
893
+ if (this._easeFrameId) {
894
+ this._cancelRenderFrame(this._easeFrameId);
895
+ delete this._easeFrameId;
896
+ delete this._onEaseFrame;
897
+ }
898
+
899
+ if (this._onEaseEnd) {
900
+ // The _onEaseEnd function might emit events which trigger new
901
+ // animation, which sets a new _onEaseEnd. Ensure we don't delete
902
+ // it unintentionally.
903
+ const onEaseEnd = this._onEaseEnd;
904
+ delete this._onEaseEnd;
905
+ onEaseEnd.call(this);
906
+ }
907
+ return this;
908
+ }
909
+
910
+ _ease(frame, finish, options) {
911
+ if (options.animate === false || options.duration === 0) {
912
+ frame(1);
913
+ finish();
914
+ } else {
915
+ this._easeStart = browser.now();
916
+ this._easeOptions = options;
917
+ this._onEaseFrame = frame;
918
+ this._onEaseEnd = finish;
919
+ this._easeFrameId = this._requestRenderFrame(this._renderFrameCallback);
920
+ }
921
+ }
922
+
923
+ // Callback for map._requestRenderFrame
924
+ _renderFrameCallback() {
925
+ const t = Math.min((browser.now() - this._easeStart) / this._easeOptions.duration, 1);
926
+ this._onEaseFrame(this._easeOptions.easing(t));
927
+ if (t < 1) {
928
+ this._easeFrameId = this._requestRenderFrame(this._renderFrameCallback);
929
+ } else {
930
+ this.stop();
931
+ }
932
+ }
933
+
934
+ // convert bearing so that it's numerically close to the current one so that it interpolates properly
935
+ _normalizeBearing(bearing, currentBearing) {
936
+ bearing = wrap(bearing, -180, 180);
937
+ const diff = Math.abs(bearing - currentBearing);
938
+ if (Math.abs(bearing - 360 - currentBearing) < diff) bearing -= 360;
939
+ if (Math.abs(bearing + 360 - currentBearing) < diff) bearing += 360;
940
+ return bearing;
941
+ }
942
+
943
+ // If a path crossing the antimeridian would be shorter, extend the final coordinate so that
944
+ // interpolating between the two endpoints will cross it.
945
+ _normalizeCenter(center) {
946
+ const tr = this.transform;
947
+ if (!tr.renderWorldCopies || tr.lngRange) return;
948
+
949
+ const delta = center.lng - tr.center.lng;
950
+ center.lng += delta > 180 ? -360 : delta < -180 ? 360 : 0;
951
+ }
952
+ }
953
+
954
+ module.exports = Camera;