@scoova/mgl 1.0.0
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.
- package/LICENSE.txt +116 -0
- package/README.md +174 -0
- package/build/banner.ts +12 -0
- package/build/bump-version-changelog.js +26 -0
- package/build/check-bundle-size.js +77 -0
- package/build/generate-dist-package.js +26 -0
- package/build/generate-doc-images.ts +78 -0
- package/build/generate-docs.ts +190 -0
- package/build/generate-shaders.ts +68 -0
- package/build/generate-struct-arrays.ts +438 -0
- package/build/generate-style-code.ts +283 -0
- package/build/readme.md +56 -0
- package/build/release-notes.js +45 -0
- package/build/rollup/bundle_prelude.js +29 -0
- package/build/rollup/maplibregl.js +22 -0
- package/build/rollup_plugins.ts +58 -0
- package/dist/LICENSE.txt +116 -0
- package/dist/maplibre-gl.css +1 -0
- package/dist/maplibre-gl.d.ts +13304 -0
- package/dist/maplibre-gl.js +59 -0
- package/dist/maplibre-gl.js.map +1 -0
- package/dist/package.json +1 -0
- package/package.json +192 -0
- package/src/css/maplibre-gl.css +854 -0
- package/src/css/svg/maplibregl-ctrl-attrib.svg +3 -0
- package/src/css/svg/maplibregl-ctrl-compass.svg +4 -0
- package/src/css/svg/maplibregl-ctrl-fullscreen.svg +3 -0
- package/src/css/svg/maplibregl-ctrl-geolocate.svg +5 -0
- package/src/css/svg/maplibregl-ctrl-logo.svg +11 -0
- package/src/css/svg/maplibregl-ctrl-shrink.svg +3 -0
- package/src/css/svg/maplibregl-ctrl-terrain.svg +3 -0
- package/src/css/svg/maplibregl-ctrl-zoom-in.svg +3 -0
- package/src/css/svg/maplibregl-ctrl-zoom-out.svg +3 -0
- package/src/data/array_types.g.ts +1130 -0
- package/src/data/bucket/circle_attributes.ts +8 -0
- package/src/data/bucket/circle_bucket.ts +197 -0
- package/src/data/bucket/fill_attributes.ts +8 -0
- package/src/data/bucket/fill_bucket.test.ts +95 -0
- package/src/data/bucket/fill_bucket.ts +228 -0
- package/src/data/bucket/fill_extrusion_attributes.ts +13 -0
- package/src/data/bucket/fill_extrusion_bucket.ts +305 -0
- package/src/data/bucket/heatmap_bucket.ts +12 -0
- package/src/data/bucket/line_attributes.ts +8 -0
- package/src/data/bucket/line_attributes_ext.ts +8 -0
- package/src/data/bucket/line_bucket.test.ts +142 -0
- package/src/data/bucket/line_bucket.ts +592 -0
- package/src/data/bucket/pattern_attributes.ts +9 -0
- package/src/data/bucket/pattern_bucket_features.ts +57 -0
- package/src/data/bucket/symbol_attributes.ts +122 -0
- package/src/data/bucket/symbol_bucket.test.ts +243 -0
- package/src/data/bucket/symbol_bucket.ts +975 -0
- package/src/data/bucket.ts +123 -0
- package/src/data/dem_data.test.ts +237 -0
- package/src/data/dem_data.ts +171 -0
- package/src/data/evaluation_feature.ts +18 -0
- package/src/data/extent.ts +13 -0
- package/src/data/feature_index.ts +337 -0
- package/src/data/feature_position_map.test.ts +33 -0
- package/src/data/feature_position_map.ts +126 -0
- package/src/data/index_array_type.ts +9 -0
- package/src/data/load_geometry.test.ts +49 -0
- package/src/data/load_geometry.ts +44 -0
- package/src/data/pos3d_attributes.ts +5 -0
- package/src/data/pos_attributes.ts +5 -0
- package/src/data/program_configuration.ts +735 -0
- package/src/data/raster_bounds_attributes.ts +6 -0
- package/src/data/segment.ts +89 -0
- package/src/geo/edge_insets.test.ts +83 -0
- package/src/geo/edge_insets.ts +146 -0
- package/src/geo/lng_lat.test.ts +65 -0
- package/src/geo/lng_lat.ts +169 -0
- package/src/geo/lng_lat_bounds.test.ts +357 -0
- package/src/geo/lng_lat_bounds.ts +356 -0
- package/src/geo/mercator_coordinate.test.ts +34 -0
- package/src/geo/mercator_coordinate.ts +157 -0
- package/src/geo/projection/projection.ts +72 -0
- package/src/geo/transform.test.ts +509 -0
- package/src/geo/transform.ts +1072 -0
- package/src/gl/color_mode.ts +31 -0
- package/src/gl/context.ts +321 -0
- package/src/gl/cull_face_mode.ts +22 -0
- package/src/gl/depth_mode.ts +26 -0
- package/src/gl/framebuffer.ts +48 -0
- package/src/gl/index_buffer.ts +55 -0
- package/src/gl/render_pool.test.ts +69 -0
- package/src/gl/render_pool.ts +93 -0
- package/src/gl/state.test.ts +125 -0
- package/src/gl/stencil_mode.ts +27 -0
- package/src/gl/types.ts +59 -0
- package/src/gl/value.ts +534 -0
- package/src/gl/vertex_buffer.test.ts +57 -0
- package/src/gl/vertex_buffer.ts +111 -0
- package/src/gl/webgl2.ts +12 -0
- package/src/index.test.ts +121 -0
- package/src/index.ts +250 -0
- package/src/render/draw_background.ts +53 -0
- package/src/render/draw_circle.ts +113 -0
- package/src/render/draw_collision_debug.ts +168 -0
- package/src/render/draw_custom.test.ts +73 -0
- package/src/render/draw_custom.ts +45 -0
- package/src/render/draw_debug.test.ts +122 -0
- package/src/render/draw_debug.ts +148 -0
- package/src/render/draw_fill.test.ts +137 -0
- package/src/render/draw_fill.ts +128 -0
- package/src/render/draw_fill_extrusion.ts +97 -0
- package/src/render/draw_heatmap.ts +228 -0
- package/src/render/draw_hillshade.ts +119 -0
- package/src/render/draw_line.ts +125 -0
- package/src/render/draw_raster.ts +133 -0
- package/src/render/draw_sky.ts +44 -0
- package/src/render/draw_symbol.test.ts +223 -0
- package/src/render/draw_symbol.ts +499 -0
- package/src/render/draw_terrain.ts +99 -0
- package/src/render/glyph_atlas.ts +83 -0
- package/src/render/glyph_manager.test.ts +147 -0
- package/src/render/glyph_manager.ts +198 -0
- package/src/render/image_atlas.ts +159 -0
- package/src/render/image_manager.ts +337 -0
- package/src/render/line_atlas.test.ts +38 -0
- package/src/render/line_atlas.ts +214 -0
- package/src/render/mesh.ts +25 -0
- package/src/render/painter.test.ts +51 -0
- package/src/render/painter.ts +666 -0
- package/src/render/program/background_program.ts +100 -0
- package/src/render/program/circle_program.ts +61 -0
- package/src/render/program/clipping_mask_program.ts +19 -0
- package/src/render/program/collision_program.ts +47 -0
- package/src/render/program/debug_program.ts +29 -0
- package/src/render/program/fill_extrusion_program.ts +120 -0
- package/src/render/program/fill_program.ts +121 -0
- package/src/render/program/heatmap_program.ts +76 -0
- package/src/render/program/hillshade_program.ts +116 -0
- package/src/render/program/line_program.ts +207 -0
- package/src/render/program/pattern.ts +102 -0
- package/src/render/program/program_uniforms.ts +46 -0
- package/src/render/program/raster_program.ts +88 -0
- package/src/render/program/sky_program.ts +28 -0
- package/src/render/program/symbol_program.ts +266 -0
- package/src/render/program/terrain_program.ts +116 -0
- package/src/render/program.ts +233 -0
- package/src/render/render_to_texture.test.ts +151 -0
- package/src/render/render_to_texture.ts +197 -0
- package/src/render/terrain.test.ts +322 -0
- package/src/render/terrain.ts +464 -0
- package/src/render/texture.ts +114 -0
- package/src/render/uniform_binding.test.ts +122 -0
- package/src/render/uniform_binding.ts +157 -0
- package/src/render/update_pattern_positions_in_program.test.ts +74 -0
- package/src/render/update_pattern_positions_in_program.ts +50 -0
- package/src/render/vertex_array_object.ts +163 -0
- package/src/shaders/README.md +42 -0
- package/src/shaders/_prelude.fragment.glsl +19 -0
- package/src/shaders/_prelude.fragment.glsl.g.ts +2 -0
- package/src/shaders/_prelude.vertex.glsl +148 -0
- package/src/shaders/_prelude.vertex.glsl.g.ts +2 -0
- package/src/shaders/background.fragment.glsl +10 -0
- package/src/shaders/background.fragment.glsl.g.ts +2 -0
- package/src/shaders/background.vertex.glsl +7 -0
- package/src/shaders/background.vertex.glsl.g.ts +2 -0
- package/src/shaders/background_pattern.fragment.glsl +28 -0
- package/src/shaders/background_pattern.fragment.glsl.g.ts +2 -0
- package/src/shaders/background_pattern.vertex.glsl +19 -0
- package/src/shaders/background_pattern.vertex.glsl.g.ts +2 -0
- package/src/shaders/circle.fragment.glsl +34 -0
- package/src/shaders/circle.fragment.glsl.g.ts +2 -0
- package/src/shaders/circle.vertex.glsl +68 -0
- package/src/shaders/circle.vertex.glsl.g.ts +2 -0
- package/src/shaders/clipping_mask.fragment.glsl +3 -0
- package/src/shaders/clipping_mask.fragment.glsl.g.ts +2 -0
- package/src/shaders/clipping_mask.vertex.glsl +7 -0
- package/src/shaders/clipping_mask.vertex.glsl.g.ts +2 -0
- package/src/shaders/collision_box.fragment.glsl +20 -0
- package/src/shaders/collision_box.fragment.glsl.g.ts +2 -0
- package/src/shaders/collision_box.vertex.glsl +27 -0
- package/src/shaders/collision_box.vertex.glsl.g.ts +2 -0
- package/src/shaders/collision_circle.fragment.glsl +17 -0
- package/src/shaders/collision_circle.fragment.glsl.g.ts +2 -0
- package/src/shaders/collision_circle.vertex.glsl +59 -0
- package/src/shaders/collision_circle.vertex.glsl.g.ts +2 -0
- package/src/shaders/debug.fragment.glsl +9 -0
- package/src/shaders/debug.fragment.glsl.g.ts +2 -0
- package/src/shaders/debug.vertex.glsl +12 -0
- package/src/shaders/debug.vertex.glsl.g.ts +2 -0
- package/src/shaders/encode_attribute.test.ts +11 -0
- package/src/shaders/encode_attribute.ts +13 -0
- package/src/shaders/fill.fragment.glsl +13 -0
- package/src/shaders/fill.fragment.glsl.g.ts +2 -0
- package/src/shaders/fill.vertex.glsl +13 -0
- package/src/shaders/fill.vertex.glsl.g.ts +2 -0
- package/src/shaders/fill_extrusion.fragment.glsl +9 -0
- package/src/shaders/fill_extrusion.fragment.glsl.g.ts +2 -0
- package/src/shaders/fill_extrusion.vertex.glsl +84 -0
- package/src/shaders/fill_extrusion.vertex.glsl.g.ts +2 -0
- package/src/shaders/fill_extrusion_pattern.fragment.glsl +47 -0
- package/src/shaders/fill_extrusion_pattern.fragment.glsl.g.ts +2 -0
- package/src/shaders/fill_extrusion_pattern.vertex.glsl +96 -0
- package/src/shaders/fill_extrusion_pattern.vertex.glsl.g.ts +2 -0
- package/src/shaders/fill_outline.fragment.glsl +17 -0
- package/src/shaders/fill_outline.fragment.glsl.g.ts +2 -0
- package/src/shaders/fill_outline.vertex.glsl +17 -0
- package/src/shaders/fill_outline.vertex.glsl.g.ts +2 -0
- package/src/shaders/fill_outline_pattern.fragment.glsl +43 -0
- package/src/shaders/fill_outline_pattern.fragment.glsl.g.ts +2 -0
- package/src/shaders/fill_outline_pattern.vertex.glsl +44 -0
- package/src/shaders/fill_outline_pattern.vertex.glsl.g.ts +2 -0
- package/src/shaders/fill_pattern.fragment.glsl +39 -0
- package/src/shaders/fill_pattern.fragment.glsl.g.ts +2 -0
- package/src/shaders/fill_pattern.vertex.glsl +39 -0
- package/src/shaders/fill_pattern.vertex.glsl.g.ts +2 -0
- package/src/shaders/heatmap.fragment.glsl +22 -0
- package/src/shaders/heatmap.fragment.glsl.g.ts +2 -0
- package/src/shaders/heatmap.vertex.glsl +54 -0
- package/src/shaders/heatmap.vertex.glsl.g.ts +2 -0
- package/src/shaders/heatmap_texture.fragment.glsl +15 -0
- package/src/shaders/heatmap_texture.fragment.glsl.g.ts +2 -0
- package/src/shaders/heatmap_texture.vertex.glsl +11 -0
- package/src/shaders/heatmap_texture.vertex.glsl.g.ts +2 -0
- package/src/shaders/hillshade.fragment.glsl +52 -0
- package/src/shaders/hillshade.fragment.glsl.g.ts +2 -0
- package/src/shaders/hillshade.vertex.glsl +11 -0
- package/src/shaders/hillshade.vertex.glsl.g.ts +2 -0
- package/src/shaders/hillshade_prepare.fragment.glsl +77 -0
- package/src/shaders/hillshade_prepare.fragment.glsl.g.ts +2 -0
- package/src/shaders/hillshade_prepare.vertex.glsl +15 -0
- package/src/shaders/hillshade_prepare.vertex.glsl.g.ts +2 -0
- package/src/shaders/line.fragment.glsl +30 -0
- package/src/shaders/line.fragment.glsl.g.ts +2 -0
- package/src/shaders/line.vertex.glsl +89 -0
- package/src/shaders/line.vertex.glsl.g.ts +2 -0
- package/src/shaders/line_gradient.fragment.glsl +34 -0
- package/src/shaders/line_gradient.fragment.glsl.g.ts +2 -0
- package/src/shaders/line_gradient.vertex.glsl +92 -0
- package/src/shaders/line_gradient.vertex.glsl.g.ts +2 -0
- package/src/shaders/line_pattern.fragment.glsl +77 -0
- package/src/shaders/line_pattern.fragment.glsl.g.ts +2 -0
- package/src/shaders/line_pattern.vertex.glsl +103 -0
- package/src/shaders/line_pattern.vertex.glsl.g.ts +2 -0
- package/src/shaders/line_sdf.fragment.glsl +45 -0
- package/src/shaders/line_sdf.fragment.glsl.g.ts +2 -0
- package/src/shaders/line_sdf.vertex.glsl +101 -0
- package/src/shaders/line_sdf.vertex.glsl.g.ts +2 -0
- package/src/shaders/raster.fragment.glsl +53 -0
- package/src/shaders/raster.fragment.glsl.g.ts +2 -0
- package/src/shaders/raster.vertex.glsl +21 -0
- package/src/shaders/raster.vertex.glsl.g.ts +2 -0
- package/src/shaders/shaders.ts +197 -0
- package/src/shaders/sky.fragment.glsl +17 -0
- package/src/shaders/sky.fragment.glsl.g.ts +2 -0
- package/src/shaders/sky.vertex.glsl +5 -0
- package/src/shaders/sky.vertex.glsl.g.ts +2 -0
- package/src/shaders/symbol_icon.fragment.glsl +17 -0
- package/src/shaders/symbol_icon.fragment.glsl.g.ts +2 -0
- package/src/shaders/symbol_icon.vertex.glsl +117 -0
- package/src/shaders/symbol_icon.vertex.glsl.g.ts +2 -0
- package/src/shaders/symbol_sdf.fragment.glsl +58 -0
- package/src/shaders/symbol_sdf.fragment.glsl.g.ts +2 -0
- package/src/shaders/symbol_sdf.vertex.glsl +142 -0
- package/src/shaders/symbol_sdf.vertex.glsl.g.ts +2 -0
- package/src/shaders/symbol_text_and_icon.fragment.glsl +68 -0
- package/src/shaders/symbol_text_and_icon.fragment.glsl.g.ts +2 -0
- package/src/shaders/symbol_text_and_icon.vertex.glsl +140 -0
- package/src/shaders/symbol_text_and_icon.vertex.glsl.g.ts +2 -0
- package/src/shaders/terrain.fragment.glsl +32 -0
- package/src/shaders/terrain.fragment.glsl.g.ts +2 -0
- package/src/shaders/terrain.vertex.glsl +17 -0
- package/src/shaders/terrain.vertex.glsl.g.ts +2 -0
- package/src/shaders/terrain_coords.fragment.glsl +11 -0
- package/src/shaders/terrain_coords.fragment.glsl.g.ts +2 -0
- package/src/shaders/terrain_coords.vertex.glsl +13 -0
- package/src/shaders/terrain_coords.vertex.glsl.g.ts +2 -0
- package/src/shaders/terrain_depth.fragment.glsl +15 -0
- package/src/shaders/terrain_depth.fragment.glsl.g.ts +2 -0
- package/src/shaders/terrain_depth.vertex.glsl +13 -0
- package/src/shaders/terrain_depth.vertex.glsl.g.ts +2 -0
- package/src/source/canvas_source.test.ts +210 -0
- package/src/source/canvas_source.ts +227 -0
- package/src/source/geojson_source.test.ts +492 -0
- package/src/source/geojson_source.ts +431 -0
- package/src/source/geojson_source_diff.test.ts +364 -0
- package/src/source/geojson_source_diff.ts +172 -0
- package/src/source/geojson_worker_source.test.ts +399 -0
- package/src/source/geojson_worker_source.ts +303 -0
- package/src/source/geojson_wrapper.test.ts +32 -0
- package/src/source/geojson_wrapper.ts +81 -0
- package/src/source/image_source.test.ts +235 -0
- package/src/source/image_source.ts +338 -0
- package/src/source/load_tilejson.ts +47 -0
- package/src/source/pixels_to_tile_units.ts +25 -0
- package/src/source/protocol_crud.ts +48 -0
- package/src/source/query_features.test.ts +31 -0
- package/src/source/query_features.ts +252 -0
- package/src/source/raster_dem_tile_source.test.ts +158 -0
- package/src/source/raster_dem_tile_source.ts +166 -0
- package/src/source/raster_dem_tile_worker_source.test.ts +36 -0
- package/src/source/raster_dem_tile_worker_source.ts +38 -0
- package/src/source/raster_tile_source.test.ts +206 -0
- package/src/source/raster_tile_source.ts +227 -0
- package/src/source/rtl_text_plugin_main_thread.test.ts +170 -0
- package/src/source/rtl_text_plugin_main_thread.ts +89 -0
- package/src/source/rtl_text_plugin_status.ts +33 -0
- package/src/source/rtl_text_plugin_worker.ts +49 -0
- package/src/source/source.test.ts +41 -0
- package/src/source/source.ts +186 -0
- package/src/source/source_cache.test.ts +2069 -0
- package/src/source/source_cache.ts +1102 -0
- package/src/source/source_state.ts +157 -0
- package/src/source/terrain_source_cache.test.ts +105 -0
- package/src/source/terrain_source_cache.ts +204 -0
- package/src/source/tile.test.ts +290 -0
- package/src/source/tile.ts +478 -0
- package/src/source/tile_bounds.ts +34 -0
- package/src/source/tile_cache.test.ts +130 -0
- package/src/source/tile_cache.ts +208 -0
- package/src/source/tile_id.test.ts +112 -0
- package/src/source/tile_id.ts +221 -0
- package/src/source/vector_tile_source.test.ts +401 -0
- package/src/source/vector_tile_source.ts +283 -0
- package/src/source/vector_tile_worker_source.test.ts +396 -0
- package/src/source/vector_tile_worker_source.ts +199 -0
- package/src/source/video_source.test.ts +124 -0
- package/src/source/video_source.ts +204 -0
- package/src/source/worker.test.ts +233 -0
- package/src/source/worker.ts +301 -0
- package/src/source/worker_source.ts +117 -0
- package/src/source/worker_tile.test.ts +226 -0
- package/src/source/worker_tile.ts +208 -0
- package/src/style/create_style_layer.ts +39 -0
- package/src/style/evaluation_parameters.ts +62 -0
- package/src/style/format_section_override.test.ts +62 -0
- package/src/style/format_section_override.ts +50 -0
- package/src/style/light.test.ts +86 -0
- package/src/style/light.ts +135 -0
- package/src/style/load_glyph_range.test.ts +40 -0
- package/src/style/load_glyph_range.ts +32 -0
- package/src/style/load_sprite.test.ts +227 -0
- package/src/style/load_sprite.ts +71 -0
- package/src/style/parse_glyph_pbf.ts +42 -0
- package/src/style/pauseable_placement.ts +138 -0
- package/src/style/properties.ts +726 -0
- package/src/style/query_utils.test.ts +107 -0
- package/src/style/query_utils.ts +70 -0
- package/src/style/sky.ts +127 -0
- package/src/style/style.test.ts +2654 -0
- package/src/style/style.ts +1814 -0
- package/src/style/style_glyph.ts +25 -0
- package/src/style/style_image.ts +188 -0
- package/src/style/style_layer/background_style_layer.ts +17 -0
- package/src/style/style_layer/background_style_layer_properties.g.ts +40 -0
- package/src/style/style_layer/circle_style_layer.ts +98 -0
- package/src/style/style_layer/circle_style_layer_properties.g.ts +76 -0
- package/src/style/style_layer/custom_style_layer.ts +233 -0
- package/src/style/style_layer/fill_extrusion_style_layer.ts +224 -0
- package/src/style/style_layer/fill_extrusion_style_layer_properties.g.ts +55 -0
- package/src/style/style_layer/fill_style_layer.test.ts +37 -0
- package/src/style/style_layer/fill_style_layer.ts +65 -0
- package/src/style/style_layer/fill_style_layer_properties.g.ts +64 -0
- package/src/style/style_layer/heatmap_style_layer.ts +74 -0
- package/src/style/style_layer/heatmap_style_layer_properties.g.ts +46 -0
- package/src/style/style_layer/hillshade_style_layer.ts +21 -0
- package/src/style/style_layer/hillshade_style_layer_properties.g.ts +49 -0
- package/src/style/style_layer/line_style_layer.test.ts +50 -0
- package/src/style/style_layer/line_style_layer.ts +131 -0
- package/src/style/style_layer/line_style_layer_properties.g.ts +88 -0
- package/src/style/style_layer/overlap_mode.test.ts +57 -0
- package/src/style/style_layer/overlap_mode.ts +25 -0
- package/src/style/style_layer/raster_style_layer.ts +17 -0
- package/src/style/style_layer/raster_style_layer_properties.g.ts +55 -0
- package/src/style/style_layer/symbol_style_layer.ts +195 -0
- package/src/style/style_layer/symbol_style_layer_properties.g.ts +218 -0
- package/src/style/style_layer/typed_style_layer.ts +9 -0
- package/src/style/style_layer/variable_text_anchor.test.ts +117 -0
- package/src/style/style_layer/variable_text_anchor.ts +163 -0
- package/src/style/style_layer.test.ts +372 -0
- package/src/style/style_layer.ts +287 -0
- package/src/style/style_layer_index.test.ts +99 -0
- package/src/style/style_layer_index.ts +78 -0
- package/src/style/validate_style.ts +53 -0
- package/src/style/zoom_history.ts +40 -0
- package/src/symbol/anchor.test.ts +14 -0
- package/src/symbol/anchor.ts +22 -0
- package/src/symbol/check_max_angle.test.ts +54 -0
- package/src/symbol/check_max_angle.ts +76 -0
- package/src/symbol/clip_line.test.ts +154 -0
- package/src/symbol/clip_line.ts +66 -0
- package/src/symbol/collision_feature.test.ts +98 -0
- package/src/symbol/collision_feature.ts +114 -0
- package/src/symbol/collision_index.test.ts +19 -0
- package/src/symbol/collision_index.ts +618 -0
- package/src/symbol/cross_tile_symbol_index.test.ts +260 -0
- package/src/symbol/cross_tile_symbol_index.ts +367 -0
- package/src/symbol/get_anchors.test.ts +113 -0
- package/src/symbol/get_anchors.ts +167 -0
- package/src/symbol/grid_index.test.ts +75 -0
- package/src/symbol/grid_index.ts +414 -0
- package/src/symbol/merge_lines.test.ts +30 -0
- package/src/symbol/merge_lines.ts +80 -0
- package/src/symbol/one_em.ts +3 -0
- package/src/symbol/opacity_state.ts +23 -0
- package/src/symbol/path_interpolator.test.ts +134 -0
- package/src/symbol/path_interpolator.ts +55 -0
- package/src/symbol/placement.ts +1371 -0
- package/src/symbol/projection.test.ts +171 -0
- package/src/symbol/projection.ts +833 -0
- package/src/symbol/quads.test.ts +157 -0
- package/src/symbol/quads.ts +349 -0
- package/src/symbol/shaping.test.ts +360 -0
- package/src/symbol/shaping.ts +911 -0
- package/src/symbol/symbol_layout.ts +739 -0
- package/src/symbol/symbol_size.ts +129 -0
- package/src/symbol/symbol_style_layer.test.ts +103 -0
- package/src/symbol/transform_text.ts +27 -0
- package/src/ui/anchor.ts +27 -0
- package/src/ui/camera.test.ts +2301 -0
- package/src/ui/camera.ts +1520 -0
- package/src/ui/control/attribution_control.test.ts +543 -0
- package/src/ui/control/attribution_control.ts +209 -0
- package/src/ui/control/control.ts +67 -0
- package/src/ui/control/fullscreen_control.test.ts +114 -0
- package/src/ui/control/fullscreen_control.ts +189 -0
- package/src/ui/control/geolocate_control.test.ts +619 -0
- package/src/ui/control/geolocate_control.ts +725 -0
- package/src/ui/control/logo_control.test.ts +88 -0
- package/src/ui/control/logo_control.ts +86 -0
- package/src/ui/control/navigation_control.test.ts +238 -0
- package/src/ui/control/navigation_control.ts +294 -0
- package/src/ui/control/scale_control.test.ts +52 -0
- package/src/ui/control/scale_control.ts +152 -0
- package/src/ui/control/terrain_control.test.ts +58 -0
- package/src/ui/control/terrain_control.ts +74 -0
- package/src/ui/default_locale.ts +25 -0
- package/src/ui/events.ts +758 -0
- package/src/ui/handler/box_zoom.test.ts +163 -0
- package/src/ui/handler/box_zoom.ts +171 -0
- package/src/ui/handler/click_zoom.ts +55 -0
- package/src/ui/handler/cooperative_gestures.test.ts +338 -0
- package/src/ui/handler/cooperative_gestures.ts +111 -0
- package/src/ui/handler/dblclick_zoom.test.ts +151 -0
- package/src/ui/handler/drag_handler.ts +174 -0
- package/src/ui/handler/drag_move_state_manager.ts +115 -0
- package/src/ui/handler/drag_pan.test.ts +487 -0
- package/src/ui/handler/drag_rotate.test.ts +859 -0
- package/src/ui/handler/handler_util.ts +10 -0
- package/src/ui/handler/keyboard.test.ts +235 -0
- package/src/ui/handler/keyboard.ts +212 -0
- package/src/ui/handler/map_event.test.ts +158 -0
- package/src/ui/handler/map_event.ts +161 -0
- package/src/ui/handler/mouse.ts +92 -0
- package/src/ui/handler/mouse_handler_interface.test.ts +111 -0
- package/src/ui/handler/mouse_rotate.test.ts +62 -0
- package/src/ui/handler/one_finger_touch_drag.ts +45 -0
- package/src/ui/handler/one_finger_touch_drag_handler_interface.test.ts +77 -0
- package/src/ui/handler/scroll_zoom.test.ts +382 -0
- package/src/ui/handler/scroll_zoom.ts +379 -0
- package/src/ui/handler/shim/dblclick_zoom.ts +64 -0
- package/src/ui/handler/shim/drag_pan.ts +104 -0
- package/src/ui/handler/shim/drag_rotate.ts +76 -0
- package/src/ui/handler/shim/two_fingers_touch.ts +112 -0
- package/src/ui/handler/tap_drag_zoom.test.ts +113 -0
- package/src/ui/handler/tap_drag_zoom.ts +112 -0
- package/src/ui/handler/tap_recognizer.ts +138 -0
- package/src/ui/handler/tap_zoom.ts +98 -0
- package/src/ui/handler/touch_pan.ts +115 -0
- package/src/ui/handler/transform-provider.ts +44 -0
- package/src/ui/handler/two_fingers_touch.test.ts +283 -0
- package/src/ui/handler/two_fingers_touch.ts +336 -0
- package/src/ui/handler_inertia.ts +157 -0
- package/src/ui/handler_manager.ts +637 -0
- package/src/ui/hash.test.ts +404 -0
- package/src/ui/hash.ts +153 -0
- package/src/ui/map.ts +3393 -0
- package/src/ui/map_tests/map_animation.test.ts +61 -0
- package/src/ui/map_tests/map_basic.test.ts +223 -0
- package/src/ui/map_tests/map_bounds.test.ts +123 -0
- package/src/ui/map_tests/map_calculate_camera_options.test.ts +113 -0
- package/src/ui/map_tests/map_canvas.test.ts +59 -0
- package/src/ui/map_tests/map_control.test.ts +61 -0
- package/src/ui/map_tests/map_disable_handlers.test.ts +38 -0
- package/src/ui/map_tests/map_events.test.ts +1001 -0
- package/src/ui/map_tests/map_feature_state.test.ts +421 -0
- package/src/ui/map_tests/map_images.test.ts +175 -0
- package/src/ui/map_tests/map_is_moving.test.ts +164 -0
- package/src/ui/map_tests/map_is_rotating.test.ts +62 -0
- package/src/ui/map_tests/map_is_zooming.test.ts +86 -0
- package/src/ui/map_tests/map_layer.test.ts +457 -0
- package/src/ui/map_tests/map_options.test.ts +64 -0
- package/src/ui/map_tests/map_pitch.test.ts +90 -0
- package/src/ui/map_tests/map_pixel_ratio.test.ts +75 -0
- package/src/ui/map_tests/map_query_rendered_features.test.ts +93 -0
- package/src/ui/map_tests/map_render.test.ts +90 -0
- package/src/ui/map_tests/map_request_render_frame.test.ts +51 -0
- package/src/ui/map_tests/map_resize.test.ts +120 -0
- package/src/ui/map_tests/map_style.test.ts +541 -0
- package/src/ui/map_tests/map_terrian.test.ts +104 -0
- package/src/ui/map_tests/map_webgl.test.ts +72 -0
- package/src/ui/map_tests/map_world_copies.test.ts +103 -0
- package/src/ui/map_tests/map_zoom.test.ts +95 -0
- package/src/ui/marker.test.ts +1149 -0
- package/src/ui/marker.ts +880 -0
- package/src/ui/popup.test.ts +827 -0
- package/src/ui/popup.ts +717 -0
- package/src/util/abort_error.ts +21 -0
- package/src/util/actor.test.ts +218 -0
- package/src/util/actor.ts +241 -0
- package/src/util/actor_messages.ts +149 -0
- package/src/util/ajax.test.ts +237 -0
- package/src/util/ajax.ts +297 -0
- package/src/util/browser.test.ts +23 -0
- package/src/util/browser.ts +63 -0
- package/src/util/color_ramp.test.ts +105 -0
- package/src/util/color_ramp.ts +56 -0
- package/src/util/config.ts +29 -0
- package/src/util/dictionary_coder.ts +23 -0
- package/src/util/dispatcher.test.ts +76 -0
- package/src/util/dispatcher.ts +78 -0
- package/src/util/dom.ts +135 -0
- package/src/util/evented.test.ts +231 -0
- package/src/util/evented.ts +178 -0
- package/src/util/find_pole_of_inaccessibility.test.ts +21 -0
- package/src/util/find_pole_of_inaccessibility.ts +130 -0
- package/src/util/geolocation_support.test.ts +43 -0
- package/src/util/geolocation_support.ts +23 -0
- package/src/util/global_worker_pool.ts +65 -0
- package/src/util/image.ts +150 -0
- package/src/util/image_request.test.ts +408 -0
- package/src/util/image_request.ts +246 -0
- package/src/util/intersection_tests.ts +206 -0
- package/src/util/is_char_in_unicode_block.test.ts +15 -0
- package/src/util/is_char_in_unicode_block.ts +345 -0
- package/src/util/offscreen_canvas_distorted.test.ts +13 -0
- package/src/util/offscreen_canvas_distorted.ts +39 -0
- package/src/util/offscreen_canvas_supported.ts +11 -0
- package/src/util/performance.ts +117 -0
- package/src/util/primitives.test.ts +140 -0
- package/src/util/primitives.ts +143 -0
- package/src/util/request_manager.ts +42 -0
- package/src/util/resolve_tokens.test.ts +45 -0
- package/src/util/resolve_tokens.ts +17 -0
- package/src/util/script_detection.test.ts +138 -0
- package/src/util/script_detection.ts +376 -0
- package/src/util/smart_wrap.test.ts +97 -0
- package/src/util/smart_wrap.ts +58 -0
- package/src/util/struct_array.test.ts +101 -0
- package/src/util/struct_array.ts +246 -0
- package/src/util/style.test.ts +34 -0
- package/src/util/style.ts +28 -0
- package/src/util/task_queue.test.ts +114 -0
- package/src/util/task_queue.ts +64 -0
- package/src/util/test/util.ts +185 -0
- package/src/util/throttle.test.ts +42 -0
- package/src/util/throttle.ts +28 -0
- package/src/util/throttled_invoker.ts +41 -0
- package/src/util/transferable_grid_index.test.ts +56 -0
- package/src/util/transferable_grid_index.ts +214 -0
- package/src/util/util.test.ts +414 -0
- package/src/util/util.ts +724 -0
- package/src/util/vectortile_to_geojson.ts +72 -0
- package/src/util/verticalize_punctuation.ts +110 -0
- package/src/util/web_worker.ts +16 -0
- package/src/util/web_worker_transfer.test.ts +153 -0
- package/src/util/web_worker_transfer.ts +254 -0
- package/src/util/webp_supported.ts +63 -0
- package/src/util/worker_pool.test.ts +43 -0
- package/src/util/worker_pool.ts +58 -0
- package/src/util/world_bounds.test.ts +59 -0
- package/src/util/world_bounds.ts +46 -0
|
@@ -0,0 +1,2301 @@
|
|
|
1
|
+
import {Camera, CameraOptions} from '../ui/camera';
|
|
2
|
+
import {Transform} from '../geo/transform';
|
|
3
|
+
import {TaskQueue, TaskID} from '../util/task_queue';
|
|
4
|
+
import {browser} from '../util/browser';
|
|
5
|
+
import {fixedLngLat, fixedNum} from '../../test/unit/lib/fixed';
|
|
6
|
+
import {setMatchMedia} from '../util/test/util';
|
|
7
|
+
import {mercatorZfromAltitude} from '../geo/mercator_coordinate';
|
|
8
|
+
import {Terrain} from '../render/terrain';
|
|
9
|
+
import {LngLat, LngLatLike} from '../geo/lng_lat';
|
|
10
|
+
import {Event} from '../util/evented';
|
|
11
|
+
import {LngLatBounds} from '../geo/lng_lat_bounds';
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
setMatchMedia();
|
|
15
|
+
Object.defineProperty(browser, 'prefersReducedMotion', {value: false});
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
class CameraMock extends Camera {
|
|
19
|
+
// eslint-disable-next-line
|
|
20
|
+
_requestRenderFrame(a: () => void): TaskID {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
_cancelRenderFrame(_: TaskID): void {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function attachSimulateFrame(camera) {
|
|
30
|
+
const queue = new TaskQueue();
|
|
31
|
+
camera._requestRenderFrame = (cb) => queue.add(cb);
|
|
32
|
+
camera._cancelRenderFrame = (id) => queue.remove(id);
|
|
33
|
+
camera.simulateFrame = () => queue.run();
|
|
34
|
+
return camera;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function createCamera(options?) {
|
|
38
|
+
options = options || {};
|
|
39
|
+
|
|
40
|
+
const transform = new Transform(0, 20, 0, 60, options.renderWorldCopies);
|
|
41
|
+
transform.resize(512, 512);
|
|
42
|
+
|
|
43
|
+
const camera = attachSimulateFrame(new CameraMock(transform, {} as any))
|
|
44
|
+
.jumpTo(options);
|
|
45
|
+
|
|
46
|
+
camera._update = () => {};
|
|
47
|
+
camera._elevateCameraIfInsideTerrain = (_tr : any) => ({});
|
|
48
|
+
|
|
49
|
+
return camera;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function assertTransitionTime(done, camera, min, max) {
|
|
53
|
+
let startTime;
|
|
54
|
+
camera
|
|
55
|
+
.on('movestart', () => { startTime = new Date(); })
|
|
56
|
+
.on('moveend', () => {
|
|
57
|
+
const endTime = new Date();
|
|
58
|
+
const timeDiff = endTime.getTime() - startTime.getTime();
|
|
59
|
+
expect(timeDiff >= min && timeDiff < max).toBeTruthy();
|
|
60
|
+
done();
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
describe('#calculateCameraOptionsFromTo', () => {
|
|
65
|
+
// Choose initial zoom to avoid center being constrained by mercator latitude limits.
|
|
66
|
+
const camera = createCamera({zoom: 1});
|
|
67
|
+
|
|
68
|
+
test('look at north', () => {
|
|
69
|
+
const cameraOptions: CameraOptions = camera.calculateCameraOptionsFromTo({lng: 1, lat: 0}, 0, {lng: 1, lat: 1});
|
|
70
|
+
expect(cameraOptions).toBeDefined();
|
|
71
|
+
expect(cameraOptions.center).toBeDefined();
|
|
72
|
+
expect(cameraOptions.bearing).toBeCloseTo(0);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test('look at west', () => {
|
|
76
|
+
const cameraOptions = camera.calculateCameraOptionsFromTo({lng: 1, lat: 0}, 0, {lng: 0, lat: 0});
|
|
77
|
+
expect(cameraOptions).toBeDefined();
|
|
78
|
+
expect(cameraOptions.bearing).toBeCloseTo(-90);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test('pitch 45', () => {
|
|
82
|
+
// altitude same as grounddistance => 45°
|
|
83
|
+
// distance between lng x and lng x+1 is 111.2km at same lat
|
|
84
|
+
const cameraOptions: CameraOptions = camera.calculateCameraOptionsFromTo({lng: 1, lat: 0}, 111200, {lng: 0, lat: 0});
|
|
85
|
+
expect(cameraOptions).toBeDefined();
|
|
86
|
+
expect(cameraOptions.pitch).toBeCloseTo(45);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test('pitch 90', () => {
|
|
90
|
+
const cameraOptions = camera.calculateCameraOptionsFromTo({lng: 1, lat: 0}, 0, {lng: 0, lat: 0});
|
|
91
|
+
expect(cameraOptions).toBeDefined();
|
|
92
|
+
expect(cameraOptions.pitch).toBeCloseTo(90);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test('pitch 153.435', () => {
|
|
96
|
+
|
|
97
|
+
// distance between lng x and lng x+1 is 111.2km at same lat
|
|
98
|
+
// (elevation difference of cam and center) / 2 = grounddistance =>
|
|
99
|
+
// acos(111.2 / sqrt(111.2² + (111.2 * 2)²)) = acos(1/sqrt(5)) => 63.435 + 90 (looking up) = 153.435
|
|
100
|
+
const cameraOptions: CameraOptions = camera.calculateCameraOptionsFromTo({lng: 1, lat: 0}, 111200, {lng: 0, lat: 0}, 111200 * 3);
|
|
101
|
+
expect(cameraOptions).toBeDefined();
|
|
102
|
+
expect(cameraOptions.pitch).toBeCloseTo(153.435);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test('zoom distance 1000', () => {
|
|
106
|
+
const expectedZoom = Math.log2(camera.transform.cameraToCenterDistance / mercatorZfromAltitude(1000, 0) / camera.transform.tileSize);
|
|
107
|
+
const cameraOptions = camera.calculateCameraOptionsFromTo({lng: 0, lat: 0}, 0, {lng: 0, lat: 0}, 1000);
|
|
108
|
+
|
|
109
|
+
expect(cameraOptions).toBeDefined();
|
|
110
|
+
expect(cameraOptions.zoom).toBeCloseTo(expectedZoom);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
test('zoom distance 1 lng (111.2km), 111.2km altitude away', () => {
|
|
114
|
+
const expectedZoom = Math.log2(camera.transform.cameraToCenterDistance / mercatorZfromAltitude(Math.hypot(111200, 111200), 0) / camera.transform.tileSize);
|
|
115
|
+
const cameraOptions = camera.calculateCameraOptionsFromTo({lng: 0, lat: 0}, 0, {lng: 1, lat: 0}, 111200);
|
|
116
|
+
|
|
117
|
+
expect(cameraOptions).toBeDefined();
|
|
118
|
+
expect(cameraOptions.zoom).toBeCloseTo(expectedZoom);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test('same To as From error', () => {
|
|
122
|
+
expect(() => { camera.calculateCameraOptionsFromTo({lng: 0, lat: 0}, 0, {lng: 0, lat: 0}, 0); }).toThrow();
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
describe('#jumpTo', () => {
|
|
127
|
+
// Choose initial zoom to avoid center being constrained by mercator latitude limits.
|
|
128
|
+
const camera = createCamera({zoom: 1});
|
|
129
|
+
|
|
130
|
+
test('sets center', () => {
|
|
131
|
+
camera.jumpTo({center: [1, 2]});
|
|
132
|
+
expect(camera.getCenter()).toEqual({lng: 1, lat: 2});
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
test('throws on invalid center argument', () => {
|
|
136
|
+
expect(() => {
|
|
137
|
+
camera.jumpTo({center: 1});
|
|
138
|
+
}).toThrow(Error);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test('keeps current center if not specified', () => {
|
|
142
|
+
camera.jumpTo({});
|
|
143
|
+
expect(camera.getCenter()).toEqual({lng: 1, lat: 2});
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
test('sets zoom', () => {
|
|
147
|
+
camera.jumpTo({zoom: 3});
|
|
148
|
+
expect(camera.getZoom()).toBe(3);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test('keeps current zoom if not specified', () => {
|
|
152
|
+
camera.jumpTo({});
|
|
153
|
+
expect(camera.getZoom()).toBe(3);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
test('sets bearing', () => {
|
|
157
|
+
camera.jumpTo({bearing: 4});
|
|
158
|
+
expect(camera.getBearing()).toBe(4);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
test('keeps current bearing if not specified', () => {
|
|
162
|
+
camera.jumpTo({});
|
|
163
|
+
expect(camera.getBearing()).toBe(4);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
test('sets pitch', () => {
|
|
167
|
+
camera.jumpTo({pitch: 45});
|
|
168
|
+
expect(camera.getPitch()).toBe(45);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
test('keeps current pitch if not specified', () => {
|
|
172
|
+
camera.jumpTo({});
|
|
173
|
+
expect(camera.getPitch()).toBe(45);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
test('sets multiple properties', () => {
|
|
177
|
+
camera.jumpTo({
|
|
178
|
+
center: [10, 20],
|
|
179
|
+
zoom: 10,
|
|
180
|
+
bearing: 180,
|
|
181
|
+
pitch: 60
|
|
182
|
+
});
|
|
183
|
+
expect(camera.getCenter()).toEqual({lng: 10, lat: 20});
|
|
184
|
+
expect(camera.getZoom()).toBe(10);
|
|
185
|
+
expect(camera.getBearing()).toBe(180);
|
|
186
|
+
expect(camera.getPitch()).toBe(60);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
test('emits move events, preserving eventData', () => {
|
|
190
|
+
let started, moved, ended;
|
|
191
|
+
const eventData = {data: 'ok'};
|
|
192
|
+
|
|
193
|
+
camera
|
|
194
|
+
.on('movestart', (d) => { started = d.data; })
|
|
195
|
+
.on('move', (d) => { moved = d.data; })
|
|
196
|
+
.on('moveend', (d) => { ended = d.data; });
|
|
197
|
+
|
|
198
|
+
camera.jumpTo({center: [1, 2]}, eventData);
|
|
199
|
+
expect(started).toBe('ok');
|
|
200
|
+
expect(moved).toBe('ok');
|
|
201
|
+
expect(ended).toBe('ok');
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
test('emits zoom events, preserving eventData', () => {
|
|
205
|
+
let started, zoomed, ended;
|
|
206
|
+
const eventData = {data: 'ok'};
|
|
207
|
+
|
|
208
|
+
camera
|
|
209
|
+
.on('zoomstart', (d) => { started = d.data; })
|
|
210
|
+
.on('zoom', (d) => { zoomed = d.data; })
|
|
211
|
+
.on('zoomend', (d) => { ended = d.data; });
|
|
212
|
+
|
|
213
|
+
camera.jumpTo({zoom: 3}, eventData);
|
|
214
|
+
expect(started).toBe('ok');
|
|
215
|
+
expect(zoomed).toBe('ok');
|
|
216
|
+
expect(ended).toBe('ok');
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
test('emits rotate events, preserving eventData', () => {
|
|
220
|
+
let started, rotated, ended;
|
|
221
|
+
const eventData = {data: 'ok'};
|
|
222
|
+
|
|
223
|
+
camera
|
|
224
|
+
.on('rotatestart', (d) => { started = d.data; })
|
|
225
|
+
.on('rotate', (d) => { rotated = d.data; })
|
|
226
|
+
.on('rotateend', (d) => { ended = d.data; });
|
|
227
|
+
|
|
228
|
+
camera.jumpTo({bearing: 90}, eventData);
|
|
229
|
+
expect(started).toBe('ok');
|
|
230
|
+
expect(rotated).toBe('ok');
|
|
231
|
+
expect(ended).toBe('ok');
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
test('emits pitch events, preserving eventData', () => {
|
|
235
|
+
let started, pitched, ended;
|
|
236
|
+
const eventData = {data: 'ok'};
|
|
237
|
+
|
|
238
|
+
camera
|
|
239
|
+
.on('pitchstart', (d) => { started = d.data; })
|
|
240
|
+
.on('pitch', (d) => { pitched = d.data; })
|
|
241
|
+
.on('pitchend', (d) => { ended = d.data; });
|
|
242
|
+
|
|
243
|
+
camera.jumpTo({pitch: 10}, eventData);
|
|
244
|
+
expect(started).toBe('ok');
|
|
245
|
+
expect(pitched).toBe('ok');
|
|
246
|
+
expect(ended).toBe('ok');
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
test('cancels in-progress easing', () => {
|
|
250
|
+
camera.panTo([3, 4]);
|
|
251
|
+
expect(camera.isEasing()).toBeTruthy();
|
|
252
|
+
camera.jumpTo({center: [1, 2]});
|
|
253
|
+
expect(!camera.isEasing()).toBeTruthy();
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
describe('#setCenter', () => {
|
|
258
|
+
// Choose initial zoom to avoid center being constrained by mercator latitude limits.
|
|
259
|
+
const camera = createCamera({zoom: 1});
|
|
260
|
+
|
|
261
|
+
test('sets center', () => {
|
|
262
|
+
camera.setCenter([1, 2]);
|
|
263
|
+
expect(camera.getCenter()).toEqual({lng: 1, lat: 2});
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
test('throws on invalid center argument', () => {
|
|
267
|
+
expect(() => {
|
|
268
|
+
camera.jumpTo({center: 1});
|
|
269
|
+
}).toThrow(Error);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
test('emits move events, preserving eventData', () => {
|
|
273
|
+
let started, moved, ended;
|
|
274
|
+
const eventData = {data: 'ok'};
|
|
275
|
+
|
|
276
|
+
camera.on('movestart', (d) => { started = d.data; })
|
|
277
|
+
.on('move', (d) => { moved = d.data; })
|
|
278
|
+
.on('moveend', (d) => { ended = d.data; });
|
|
279
|
+
|
|
280
|
+
camera.setCenter([10, 20], eventData);
|
|
281
|
+
expect(started).toBe('ok');
|
|
282
|
+
expect(moved).toBe('ok');
|
|
283
|
+
expect(ended).toBe('ok');
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
test('cancels in-progress easing', () => {
|
|
287
|
+
camera.panTo([3, 4]);
|
|
288
|
+
expect(camera.isEasing()).toBeTruthy();
|
|
289
|
+
camera.setCenter([1, 2]);
|
|
290
|
+
expect(!camera.isEasing()).toBeTruthy();
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
describe('#setZoom', () => {
|
|
295
|
+
const camera = createCamera();
|
|
296
|
+
|
|
297
|
+
test('sets zoom', () => {
|
|
298
|
+
camera.setZoom(3);
|
|
299
|
+
expect(camera.getZoom()).toBe(3);
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
test('emits move and zoom events, preserving eventData', () => {
|
|
303
|
+
let movestarted, moved, moveended, zoomstarted, zoomed, zoomended;
|
|
304
|
+
const eventData = {data: 'ok'};
|
|
305
|
+
|
|
306
|
+
camera
|
|
307
|
+
.on('movestart', (d) => { movestarted = d.data; })
|
|
308
|
+
.on('move', (d) => { moved = d.data; })
|
|
309
|
+
.on('moveend', (d) => { moveended = d.data; })
|
|
310
|
+
.on('zoomstart', (d) => { zoomstarted = d.data; })
|
|
311
|
+
.on('zoom', (d) => { zoomed = d.data; })
|
|
312
|
+
.on('zoomend', (d) => { zoomended = d.data; });
|
|
313
|
+
|
|
314
|
+
camera.setZoom(4, eventData);
|
|
315
|
+
expect(movestarted).toBe('ok');
|
|
316
|
+
expect(moved).toBe('ok');
|
|
317
|
+
expect(moveended).toBe('ok');
|
|
318
|
+
expect(zoomstarted).toBe('ok');
|
|
319
|
+
expect(zoomed).toBe('ok');
|
|
320
|
+
expect(zoomended).toBe('ok');
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
test('cancels in-progress easing', () => {
|
|
324
|
+
camera.panTo([3, 4]);
|
|
325
|
+
expect(camera.isEasing()).toBeTruthy();
|
|
326
|
+
camera.setZoom(5);
|
|
327
|
+
expect(!camera.isEasing()).toBeTruthy();
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
describe('#setBearing', () => {
|
|
332
|
+
const camera = createCamera();
|
|
333
|
+
|
|
334
|
+
test('sets bearing', () => {
|
|
335
|
+
camera.setBearing(4);
|
|
336
|
+
expect(camera.getBearing()).toBe(4);
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
test('emits move and rotate events, preserving eventData', () => {
|
|
340
|
+
let movestarted, moved, moveended, rotatestarted, rotated, rotateended;
|
|
341
|
+
const eventData = {data: 'ok'};
|
|
342
|
+
|
|
343
|
+
camera
|
|
344
|
+
.on('movestart', (d) => { movestarted = d.data; })
|
|
345
|
+
.on('move', (d) => { moved = d.data; })
|
|
346
|
+
.on('moveend', (d) => { moveended = d.data; })
|
|
347
|
+
.on('rotatestart', (d) => { rotatestarted = d.data; })
|
|
348
|
+
.on('rotate', (d) => { rotated = d.data; })
|
|
349
|
+
.on('rotateend', (d) => { rotateended = d.data; });
|
|
350
|
+
|
|
351
|
+
camera.setBearing(5, eventData);
|
|
352
|
+
expect(movestarted).toBe('ok');
|
|
353
|
+
expect(moved).toBe('ok');
|
|
354
|
+
expect(moveended).toBe('ok');
|
|
355
|
+
expect(rotatestarted).toBe('ok');
|
|
356
|
+
expect(rotated).toBe('ok');
|
|
357
|
+
expect(rotateended).toBe('ok');
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
test('cancels in-progress easing', () => {
|
|
361
|
+
camera.panTo([3, 4]);
|
|
362
|
+
expect(camera.isEasing()).toBeTruthy();
|
|
363
|
+
camera.setBearing(6);
|
|
364
|
+
expect(!camera.isEasing()).toBeTruthy();
|
|
365
|
+
});
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
describe('#setPadding', () => {
|
|
369
|
+
test('sets padding', () => {
|
|
370
|
+
const camera = createCamera();
|
|
371
|
+
const padding = {left: 300, top: 100, right: 50, bottom: 10};
|
|
372
|
+
camera.setPadding(padding);
|
|
373
|
+
expect(camera.getPadding()).toEqual(padding);
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
test('existing padding is retained if no new values are passed in', () => {
|
|
377
|
+
const camera = createCamera();
|
|
378
|
+
const padding = {left: 300, top: 100, right: 50, bottom: 10};
|
|
379
|
+
camera.setPadding(padding);
|
|
380
|
+
camera.setPadding({});
|
|
381
|
+
|
|
382
|
+
const currentPadding = camera.getPadding();
|
|
383
|
+
expect(currentPadding).toEqual(padding);
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
test('doesn\'t change padding thats already present if new value isn\'t passed in', () => {
|
|
387
|
+
const camera = createCamera();
|
|
388
|
+
const padding = {left: 300, top: 100, right: 50, bottom: 10};
|
|
389
|
+
camera.setPadding(padding);
|
|
390
|
+
const padding1 = {right: 100};
|
|
391
|
+
camera.setPadding(padding1);
|
|
392
|
+
|
|
393
|
+
const currentPadding = camera.getPadding();
|
|
394
|
+
expect(currentPadding.left).toBe(padding.left);
|
|
395
|
+
expect(currentPadding.top).toBe(padding.top);
|
|
396
|
+
// padding1 here
|
|
397
|
+
expect(currentPadding.right).toBe(padding1.right);
|
|
398
|
+
expect(currentPadding.bottom).toBe(padding.bottom);
|
|
399
|
+
});
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
describe('#panBy', () => {
|
|
403
|
+
test('pans by specified amount', () => {
|
|
404
|
+
const camera = createCamera();
|
|
405
|
+
camera.panBy([100, 0], {duration: 0});
|
|
406
|
+
expect(fixedLngLat(camera.getCenter())).toEqual({lng: 70.3125, lat: 0});
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
test('pans relative to viewport on a rotated camera', () => {
|
|
410
|
+
const camera = createCamera({bearing: 180});
|
|
411
|
+
camera.panBy([100, 0], {duration: 0});
|
|
412
|
+
expect(fixedLngLat(camera.getCenter())).toEqual({lng: -70.3125, lat: 0});
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
test('emits move events, preserving eventData', () => new Promise<void>(done => {
|
|
416
|
+
const camera = createCamera();
|
|
417
|
+
let started, moved;
|
|
418
|
+
const eventData = {data: 'ok'};
|
|
419
|
+
|
|
420
|
+
camera
|
|
421
|
+
.on('movestart', (d) => { started = d.data; })
|
|
422
|
+
.on('move', (d) => { moved = d.data; })
|
|
423
|
+
.on('moveend', (d) => {
|
|
424
|
+
expect(started).toBe('ok');
|
|
425
|
+
expect(moved).toBe('ok');
|
|
426
|
+
expect(d.data).toBe('ok');
|
|
427
|
+
done();
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
camera.panBy([100, 0], {duration: 0}, eventData);
|
|
431
|
+
}));
|
|
432
|
+
|
|
433
|
+
test('suppresses movestart if noMoveStart option is true', () => new Promise<void>(done => {
|
|
434
|
+
const camera = createCamera();
|
|
435
|
+
let started;
|
|
436
|
+
|
|
437
|
+
// fire once in advance to satisfy assertions that moveend only comes after movestart
|
|
438
|
+
camera.fire('movestart');
|
|
439
|
+
|
|
440
|
+
camera
|
|
441
|
+
.on('movestart', () => { started = true; })
|
|
442
|
+
.on('moveend', () => {
|
|
443
|
+
expect(!started).toBeTruthy();
|
|
444
|
+
done();
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
camera.panBy([100, 0], {duration: 0, noMoveStart: true});
|
|
448
|
+
}));
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
describe('#panTo', () => {
|
|
452
|
+
test('pans to specified location', () => {
|
|
453
|
+
const camera = createCamera();
|
|
454
|
+
camera.panTo([100, 0], {duration: 0});
|
|
455
|
+
expect(camera.getCenter()).toEqual({lng: 100, lat: 0});
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
test('throws on invalid center argument', () => {
|
|
459
|
+
const camera = createCamera();
|
|
460
|
+
expect(() => {
|
|
461
|
+
camera.panTo({center: 1});
|
|
462
|
+
}).toThrow(Error);
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
test('pans with specified offset', () => {
|
|
466
|
+
const camera = createCamera();
|
|
467
|
+
camera.panTo([100, 0], {offset: [100, 0], duration: 0});
|
|
468
|
+
expect(fixedLngLat(camera.getCenter())).toEqual({lng: 29.6875, lat: 0});
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
test('pans with specified offset relative to viewport on a rotated camera', () => {
|
|
472
|
+
const camera = createCamera({bearing: 180});
|
|
473
|
+
camera.panTo([100, 0], {offset: [100, 0], duration: 0});
|
|
474
|
+
expect(fixedLngLat(camera.getCenter())).toEqual({lng: 170.3125, lat: 0});
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
test('emits move events, preserving eventData', () => new Promise<void>(done => {
|
|
478
|
+
const camera = createCamera();
|
|
479
|
+
let started, moved;
|
|
480
|
+
const eventData = {data: 'ok'};
|
|
481
|
+
|
|
482
|
+
camera
|
|
483
|
+
.on('movestart', (d) => { started = d.data; })
|
|
484
|
+
.on('move', (d) => { moved = d.data; })
|
|
485
|
+
.on('moveend', (d) => {
|
|
486
|
+
expect(started).toBe('ok');
|
|
487
|
+
expect(moved).toBe('ok');
|
|
488
|
+
expect(d.data).toBe('ok');
|
|
489
|
+
done();
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
camera.panTo([100, 0], {duration: 0}, eventData);
|
|
493
|
+
}));
|
|
494
|
+
|
|
495
|
+
test('suppresses movestart if noMoveStart option is true', () => new Promise<void>(done => {
|
|
496
|
+
const camera = createCamera();
|
|
497
|
+
let started;
|
|
498
|
+
|
|
499
|
+
// fire once in advance to satisfy assertions that moveend only comes after movestart
|
|
500
|
+
camera.fire('movestart');
|
|
501
|
+
|
|
502
|
+
camera
|
|
503
|
+
.on('movestart', () => { started = true; })
|
|
504
|
+
.on('moveend', () => {
|
|
505
|
+
expect(!started).toBeTruthy();
|
|
506
|
+
done();
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
camera.panTo([100, 0], {duration: 0, noMoveStart: true});
|
|
510
|
+
}));
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
describe('#zoomTo', () => {
|
|
514
|
+
test('zooms to specified level', () => {
|
|
515
|
+
const camera = createCamera();
|
|
516
|
+
camera.zoomTo(3.2, {duration: 0});
|
|
517
|
+
expect(camera.getZoom()).toBe(3.2);
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
test('zooms around specified location', () => {
|
|
521
|
+
const camera = createCamera();
|
|
522
|
+
camera.zoomTo(3.2, {around: [5, 0], duration: 0});
|
|
523
|
+
expect(camera.getZoom()).toBe(3.2);
|
|
524
|
+
expect(fixedLngLat(camera.getCenter())).toEqual(fixedLngLat({lng: 4.455905897939886, lat: 0}));
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
test('zooms with specified offset', () => {
|
|
528
|
+
const camera = createCamera();
|
|
529
|
+
camera.zoomTo(3.2, {offset: [100, 0], duration: 0});
|
|
530
|
+
expect(camera.getZoom()).toBe(3.2);
|
|
531
|
+
expect(fixedLngLat(camera.getCenter())).toEqual(fixedLngLat({lng: 62.66117668978015, lat: 0}));
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
test('zooms with specified offset relative to viewport on a rotated camera', () => {
|
|
535
|
+
const camera = createCamera({bearing: 180});
|
|
536
|
+
camera.zoomTo(3.2, {offset: [100, 0], duration: 0});
|
|
537
|
+
expect(camera.getZoom()).toBe(3.2);
|
|
538
|
+
expect(fixedLngLat(camera.getCenter())).toEqual(fixedLngLat({lng: -62.66117668978012, lat: 0}));
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
test('emits move and zoom events, preserving eventData', () => {
|
|
542
|
+
const camera = createCamera();
|
|
543
|
+
let movestarted, moved, zoomstarted, zoomed;
|
|
544
|
+
const eventData = {data: 'ok'};
|
|
545
|
+
|
|
546
|
+
expect.assertions(6);
|
|
547
|
+
|
|
548
|
+
camera
|
|
549
|
+
.on('movestart', (d) => { movestarted = d.data; })
|
|
550
|
+
.on('move', (d) => { moved = d.data; })
|
|
551
|
+
.on('moveend', (d) => {
|
|
552
|
+
expect(movestarted).toBe('ok');
|
|
553
|
+
expect(moved).toBe('ok');
|
|
554
|
+
expect(d.data).toBe('ok');
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
camera
|
|
558
|
+
.on('zoomstart', (d) => { zoomstarted = d.data; })
|
|
559
|
+
.on('zoom', (d) => { zoomed = d.data; })
|
|
560
|
+
.on('zoomend', (d) => {
|
|
561
|
+
expect(zoomstarted).toBe('ok');
|
|
562
|
+
expect(zoomed).toBe('ok');
|
|
563
|
+
expect(d.data).toBe('ok');
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
camera.zoomTo(5, {duration: 0}, eventData);
|
|
567
|
+
});
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
describe('#rotateTo', () => {
|
|
571
|
+
test('rotates to specified bearing', () => {
|
|
572
|
+
const camera = createCamera();
|
|
573
|
+
camera.rotateTo(90, {duration: 0});
|
|
574
|
+
expect(camera.getBearing()).toBe(90);
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
test('rotates around specified location', () => {
|
|
578
|
+
const camera = createCamera({zoom: 3});
|
|
579
|
+
camera.rotateTo(90, {around: [5, 0], duration: 0});
|
|
580
|
+
expect(camera.getBearing()).toBe(90);
|
|
581
|
+
expect(fixedLngLat(camera.getCenter())).toEqual(fixedLngLat({lng: 4.999999999999972, lat: 4.993665859353271}));
|
|
582
|
+
});
|
|
583
|
+
|
|
584
|
+
test('rotates around specified location, constrained to fit the view', () => {
|
|
585
|
+
const camera = createCamera({zoom: 0});
|
|
586
|
+
camera.rotateTo(90, {around: [5, 0], duration: 0});
|
|
587
|
+
expect(camera.getBearing()).toBe(90);
|
|
588
|
+
expect(fixedLngLat(camera.getCenter())).toEqual(fixedLngLat({lng: 4.999999999999972, lat: 0.000002552471840999715}));
|
|
589
|
+
});
|
|
590
|
+
|
|
591
|
+
test('rotates with specified offset', () => {
|
|
592
|
+
const camera = createCamera({zoom: 1});
|
|
593
|
+
camera.rotateTo(90, {offset: [200, 0], duration: 0});
|
|
594
|
+
expect(camera.getBearing()).toBe(90);
|
|
595
|
+
expect(fixedLngLat(camera.getCenter())).toEqual(fixedLngLat({lng: 70.3125, lat: 57.3265212252}));
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
test('rotates with specified offset, constrained to fit the view', () => {
|
|
599
|
+
const camera = createCamera({zoom: 0});
|
|
600
|
+
camera.rotateTo(90, {offset: [100, 0], duration: 0});
|
|
601
|
+
expect(camera.getBearing()).toBe(90);
|
|
602
|
+
expect(fixedLngLat(camera.getCenter())).toEqual(fixedLngLat({lng: 70.3125, lat: 0.000002552471840999715}));
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
test('rotates with specified offset relative to viewport on a rotated camera', () => {
|
|
606
|
+
const camera = createCamera({bearing: 180, zoom: 1});
|
|
607
|
+
camera.rotateTo(90, {offset: [200, 0], duration: 0});
|
|
608
|
+
expect(camera.getBearing()).toBe(90);
|
|
609
|
+
expect(fixedLngLat(camera.getCenter())).toEqual(fixedLngLat({lng: -70.3125, lat: 57.3265212252}));
|
|
610
|
+
});
|
|
611
|
+
|
|
612
|
+
test('emits move and rotate events, preserving eventData', () => {
|
|
613
|
+
const camera = createCamera();
|
|
614
|
+
let movestarted, moved, rotatestarted, rotated;
|
|
615
|
+
const eventData = {data: 'ok'};
|
|
616
|
+
|
|
617
|
+
expect.assertions(6);
|
|
618
|
+
|
|
619
|
+
camera
|
|
620
|
+
.on('movestart', (d) => { movestarted = d.data; })
|
|
621
|
+
.on('move', (d) => { moved = d.data; })
|
|
622
|
+
.on('moveend', (d) => {
|
|
623
|
+
expect(movestarted).toBe('ok');
|
|
624
|
+
expect(moved).toBe('ok');
|
|
625
|
+
expect(d.data).toBe('ok');
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
camera
|
|
629
|
+
.on('rotatestart', (d) => { rotatestarted = d.data; })
|
|
630
|
+
.on('rotate', (d) => { rotated = d.data; })
|
|
631
|
+
.on('rotateend', (d) => {
|
|
632
|
+
expect(rotatestarted).toBe('ok');
|
|
633
|
+
expect(rotated).toBe('ok');
|
|
634
|
+
expect(d.data).toBe('ok');
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
camera.rotateTo(90, {duration: 0}, eventData);
|
|
638
|
+
});
|
|
639
|
+
});
|
|
640
|
+
|
|
641
|
+
describe('#easeTo', () => {
|
|
642
|
+
test('pans to specified location', () => {
|
|
643
|
+
const camera = createCamera();
|
|
644
|
+
camera.easeTo({center: [100, 0], duration: 0});
|
|
645
|
+
expect(camera.getCenter()).toEqual({lng: 100, lat: 0});
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
test('zooms to specified level', () => {
|
|
649
|
+
const camera = createCamera();
|
|
650
|
+
camera.easeTo({zoom: 3.2, duration: 0});
|
|
651
|
+
expect(camera.getZoom()).toBe(3.2);
|
|
652
|
+
});
|
|
653
|
+
|
|
654
|
+
test('rotates to specified bearing', () => {
|
|
655
|
+
const camera = createCamera();
|
|
656
|
+
camera.easeTo({bearing: 90, duration: 0});
|
|
657
|
+
expect(camera.getBearing()).toBe(90);
|
|
658
|
+
});
|
|
659
|
+
|
|
660
|
+
test('pitches to specified pitch', () => {
|
|
661
|
+
const camera = createCamera();
|
|
662
|
+
camera.easeTo({pitch: 45, duration: 0});
|
|
663
|
+
expect(camera.getPitch()).toBe(45);
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
test('pans and zooms', () => {
|
|
667
|
+
const camera = createCamera();
|
|
668
|
+
camera.easeTo({center: [100, 0], zoom: 3.2, duration: 0});
|
|
669
|
+
expect(fixedLngLat(camera.getCenter())).toEqual(fixedLngLat({lng: 100, lat: 0}));
|
|
670
|
+
expect(camera.getZoom()).toBe(3.2);
|
|
671
|
+
});
|
|
672
|
+
|
|
673
|
+
test('zooms around a point', () => {
|
|
674
|
+
const camera = createCamera();
|
|
675
|
+
camera.easeTo({around: [100, 0], zoom: 3, duration: 0});
|
|
676
|
+
expect(fixedLngLat(camera.getCenter())).toEqual(fixedLngLat({lng: 87.5, lat: 0}));
|
|
677
|
+
expect(camera.getZoom()).toBe(3);
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
test('pans and rotates', () => {
|
|
681
|
+
const camera = createCamera();
|
|
682
|
+
camera.easeTo({center: [100, 0], bearing: 90, duration: 0});
|
|
683
|
+
expect(camera.getCenter()).toEqual({lng: 100, lat: 0});
|
|
684
|
+
expect(camera.getBearing()).toBe(90);
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
test('zooms and rotates', () => {
|
|
688
|
+
const camera = createCamera();
|
|
689
|
+
camera.easeTo({zoom: 3.2, bearing: 90, duration: 0});
|
|
690
|
+
expect(camera.getZoom()).toBe(3.2);
|
|
691
|
+
expect(camera.getBearing()).toBe(90);
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
test('pans, zooms, and rotates', () => {
|
|
695
|
+
const camera = createCamera({bearing: -90});
|
|
696
|
+
camera.easeTo({center: [100, 0], zoom: 3.2, bearing: 90, duration: 0});
|
|
697
|
+
expect(fixedLngLat(camera.getCenter())).toEqual(fixedLngLat({lng: 100, lat: 0}));
|
|
698
|
+
expect(camera.getZoom()).toBe(3.2);
|
|
699
|
+
expect(camera.getBearing()).toBe(90);
|
|
700
|
+
});
|
|
701
|
+
|
|
702
|
+
test('noop', () => {
|
|
703
|
+
const camera = createCamera();
|
|
704
|
+
camera.easeTo({duration: 0});
|
|
705
|
+
expect(fixedLngLat(camera.getCenter())).toEqual({lng: 0, lat: 0});
|
|
706
|
+
expect(camera.getZoom()).toBe(0);
|
|
707
|
+
expect(camera.getBearing()).toBeCloseTo(0);
|
|
708
|
+
});
|
|
709
|
+
|
|
710
|
+
test('noop with offset', () => {
|
|
711
|
+
const camera = createCamera();
|
|
712
|
+
camera.easeTo({offset: [100, 0], duration: 0});
|
|
713
|
+
expect(fixedLngLat(camera.getCenter())).toEqual({lng: 0, lat: 0});
|
|
714
|
+
expect(camera.getZoom()).toBe(0);
|
|
715
|
+
expect(camera.getBearing()).toBeCloseTo(0);
|
|
716
|
+
});
|
|
717
|
+
|
|
718
|
+
test('pans with specified offset', () => {
|
|
719
|
+
const camera = createCamera();
|
|
720
|
+
camera.easeTo({center: [100, 0], offset: [100, 0], duration: 0});
|
|
721
|
+
expect(fixedLngLat(camera.getCenter())).toEqual({lng: 29.6875, lat: 0});
|
|
722
|
+
});
|
|
723
|
+
|
|
724
|
+
test('pans with specified offset relative to viewport on a rotated camera', () => {
|
|
725
|
+
const camera = createCamera({bearing: 180});
|
|
726
|
+
camera.easeTo({center: [100, 0], offset: [100, 0], duration: 0});
|
|
727
|
+
expect(fixedLngLat(camera.getCenter())).toEqual({lng: 170.3125, lat: 0});
|
|
728
|
+
});
|
|
729
|
+
|
|
730
|
+
test('zooms with specified offset', () => {
|
|
731
|
+
const camera = createCamera();
|
|
732
|
+
camera.easeTo({zoom: 3.2, offset: [100, 0], duration: 0});
|
|
733
|
+
expect(camera.getZoom()).toBe(3.2);
|
|
734
|
+
expect(fixedLngLat(camera.getCenter())).toEqual(fixedLngLat({lng: 62.66117668978015, lat: 0}));
|
|
735
|
+
});
|
|
736
|
+
|
|
737
|
+
test('zooms with specified offset relative to viewport on a rotated camera', () => {
|
|
738
|
+
const camera = createCamera({bearing: 180});
|
|
739
|
+
camera.easeTo({zoom: 3.2, offset: [100, 0], duration: 0});
|
|
740
|
+
expect(camera.getZoom()).toBe(3.2);
|
|
741
|
+
expect(fixedLngLat(camera.getCenter())).toEqual(fixedLngLat({lng: -62.66117668978012, lat: 0}));
|
|
742
|
+
});
|
|
743
|
+
|
|
744
|
+
test('rotates with specified offset', () => {
|
|
745
|
+
const camera = createCamera();
|
|
746
|
+
camera.easeTo({bearing: 90, offset: [100, 0], duration: 0});
|
|
747
|
+
expect(camera.getBearing()).toBe(90);
|
|
748
|
+
expect(fixedLngLat(camera.getCenter())).toEqual(fixedLngLat({lng: 70.3125, lat: 0.000002552471840999715}));
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
test('rotates with specified offset relative to viewport on a rotated camera', () => {
|
|
752
|
+
const camera = createCamera({bearing: 180});
|
|
753
|
+
camera.easeTo({bearing: 90, offset: [100, 0], duration: 0});
|
|
754
|
+
expect(camera.getBearing()).toBe(90);
|
|
755
|
+
expect(fixedLngLat(camera.getCenter())).toEqual(fixedLngLat({lng: -70.3125, lat: 0.000002552471840999715}));
|
|
756
|
+
});
|
|
757
|
+
|
|
758
|
+
test('emits move, zoom, rotate, and pitch events, preserving eventData', () => {
|
|
759
|
+
const camera = createCamera();
|
|
760
|
+
let movestarted, moved, zoomstarted, zoomed, rotatestarted, rotated, pitchstarted, pitched;
|
|
761
|
+
const eventData = {data: 'ok'};
|
|
762
|
+
|
|
763
|
+
expect.assertions(18);
|
|
764
|
+
|
|
765
|
+
camera
|
|
766
|
+
.on('movestart', (d) => { movestarted = d.data; })
|
|
767
|
+
.on('move', (d) => { moved = d.data; })
|
|
768
|
+
.on('moveend', (d) => {
|
|
769
|
+
expect(camera._zooming).toBeFalsy();
|
|
770
|
+
expect(camera._panning).toBeFalsy();
|
|
771
|
+
expect(camera._rotating).toBeFalsy();
|
|
772
|
+
|
|
773
|
+
expect(movestarted).toBe('ok');
|
|
774
|
+
expect(moved).toBe('ok');
|
|
775
|
+
expect(zoomed).toBe('ok');
|
|
776
|
+
expect(rotated).toBe('ok');
|
|
777
|
+
expect(pitched).toBe('ok');
|
|
778
|
+
expect(d.data).toBe('ok');
|
|
779
|
+
});
|
|
780
|
+
|
|
781
|
+
camera
|
|
782
|
+
.on('zoomstart', (d) => { zoomstarted = d.data; })
|
|
783
|
+
.on('zoom', (d) => { zoomed = d.data; })
|
|
784
|
+
.on('zoomend', (d) => {
|
|
785
|
+
expect(zoomstarted).toBe('ok');
|
|
786
|
+
expect(zoomed).toBe('ok');
|
|
787
|
+
expect(d.data).toBe('ok');
|
|
788
|
+
});
|
|
789
|
+
|
|
790
|
+
camera
|
|
791
|
+
.on('rotatestart', (d) => { rotatestarted = d.data; })
|
|
792
|
+
.on('rotate', (d) => { rotated = d.data; })
|
|
793
|
+
.on('rotateend', (d) => {
|
|
794
|
+
expect(rotatestarted).toBe('ok');
|
|
795
|
+
expect(rotated).toBe('ok');
|
|
796
|
+
expect(d.data).toBe('ok');
|
|
797
|
+
});
|
|
798
|
+
|
|
799
|
+
camera
|
|
800
|
+
.on('pitchstart', (d) => { pitchstarted = d.data; })
|
|
801
|
+
.on('pitch', (d) => { pitched = d.data; })
|
|
802
|
+
.on('pitchend', (d) => {
|
|
803
|
+
expect(pitchstarted).toBe('ok');
|
|
804
|
+
expect(pitched).toBe('ok');
|
|
805
|
+
expect(d.data).toBe('ok');
|
|
806
|
+
});
|
|
807
|
+
|
|
808
|
+
camera.easeTo(
|
|
809
|
+
{center: [100, 0], zoom: 3.2, bearing: 90, duration: 0, pitch: 45},
|
|
810
|
+
eventData);
|
|
811
|
+
});
|
|
812
|
+
|
|
813
|
+
test('does not emit zoom events if not zooming', () => new Promise<void>((done) => {
|
|
814
|
+
const camera = createCamera();
|
|
815
|
+
|
|
816
|
+
camera
|
|
817
|
+
.on('zoomstart', () => { throw new Error('zoomstart failed'); })
|
|
818
|
+
.on('zoom', () => { throw new Error('zoom failed'); })
|
|
819
|
+
.on('zoomend', () => { throw new Error('zoomend failed'); })
|
|
820
|
+
.on('moveend', () => { done(); });
|
|
821
|
+
|
|
822
|
+
camera.easeTo({center: [100, 0], duration: 0});
|
|
823
|
+
}));
|
|
824
|
+
|
|
825
|
+
test('stops existing ease', () => {
|
|
826
|
+
const camera = createCamera();
|
|
827
|
+
camera.easeTo({center: [200, 0], duration: 100});
|
|
828
|
+
camera.easeTo({center: [100, 0], duration: 0});
|
|
829
|
+
expect(camera.getCenter()).toEqual({lng: 100, lat: 0});
|
|
830
|
+
});
|
|
831
|
+
|
|
832
|
+
test('can be called from within a moveend event handler', () => new Promise<void>(done => {
|
|
833
|
+
const camera = createCamera();
|
|
834
|
+
const stub = jest.spyOn(browser, 'now');
|
|
835
|
+
|
|
836
|
+
stub.mockImplementation(() => 0);
|
|
837
|
+
camera.easeTo({center: [100, 0], duration: 10});
|
|
838
|
+
|
|
839
|
+
camera.once('moveend', () => {
|
|
840
|
+
camera.easeTo({center: [200, 0], duration: 10});
|
|
841
|
+
camera.once('moveend', () => {
|
|
842
|
+
camera.easeTo({center: [300, 0], duration: 10});
|
|
843
|
+
camera.once('moveend', () => {
|
|
844
|
+
done();
|
|
845
|
+
});
|
|
846
|
+
|
|
847
|
+
setTimeout(() => {
|
|
848
|
+
stub.mockImplementation(() => 30);
|
|
849
|
+
camera.simulateFrame();
|
|
850
|
+
}, 0);
|
|
851
|
+
});
|
|
852
|
+
|
|
853
|
+
// setTimeout to avoid a synchronous callback
|
|
854
|
+
setTimeout(() => {
|
|
855
|
+
stub.mockImplementation(() => 20);
|
|
856
|
+
camera.simulateFrame();
|
|
857
|
+
}, 0);
|
|
858
|
+
});
|
|
859
|
+
|
|
860
|
+
// setTimeout to avoid a synchronous callback
|
|
861
|
+
setTimeout(() => {
|
|
862
|
+
stub.mockImplementation(() => 10);
|
|
863
|
+
camera.simulateFrame();
|
|
864
|
+
}, 0);
|
|
865
|
+
}));
|
|
866
|
+
|
|
867
|
+
test('pans eastward across the antimeridian', () => new Promise<void>(done => {
|
|
868
|
+
const camera = createCamera();
|
|
869
|
+
const stub = jest.spyOn(browser, 'now');
|
|
870
|
+
|
|
871
|
+
camera.setCenter([170, 0]);
|
|
872
|
+
let crossedAntimeridian;
|
|
873
|
+
|
|
874
|
+
camera.on('move', () => {
|
|
875
|
+
if (camera.getCenter().lng > 170) {
|
|
876
|
+
crossedAntimeridian = true;
|
|
877
|
+
}
|
|
878
|
+
});
|
|
879
|
+
|
|
880
|
+
camera.on('moveend', () => {
|
|
881
|
+
expect(crossedAntimeridian).toBeTruthy();
|
|
882
|
+
done();
|
|
883
|
+
});
|
|
884
|
+
|
|
885
|
+
stub.mockImplementation(() => 0);
|
|
886
|
+
camera.easeTo({center: [-170, 0], duration: 10});
|
|
887
|
+
|
|
888
|
+
setTimeout(() => {
|
|
889
|
+
stub.mockImplementation(() => 1);
|
|
890
|
+
camera.simulateFrame();
|
|
891
|
+
|
|
892
|
+
setTimeout(() => {
|
|
893
|
+
stub.mockImplementation(() => 10);
|
|
894
|
+
camera.simulateFrame();
|
|
895
|
+
}, 0);
|
|
896
|
+
}, 0);
|
|
897
|
+
}));
|
|
898
|
+
|
|
899
|
+
test('does not pan eastward across the antimeridian on a single-globe mercator map', () => new Promise<void>(done => {
|
|
900
|
+
const camera = createCamera({renderWorldCopies: false, zoom: 2});
|
|
901
|
+
camera.setCenter([170, 0]);
|
|
902
|
+
const initialLng = camera.getCenter().lng;
|
|
903
|
+
camera.on('moveend', () => {
|
|
904
|
+
expect(camera.getCenter().lng).toBeCloseTo(initialLng, 0);
|
|
905
|
+
done();
|
|
906
|
+
});
|
|
907
|
+
camera.easeTo({center: [210, 0], duration: 0});
|
|
908
|
+
}));
|
|
909
|
+
|
|
910
|
+
test('pans westward across the antimeridian', () => new Promise<void>(done => {
|
|
911
|
+
const camera = createCamera();
|
|
912
|
+
const stub = jest.spyOn(browser, 'now');
|
|
913
|
+
|
|
914
|
+
camera.setCenter([-170, 0]);
|
|
915
|
+
let crossedAntimeridian;
|
|
916
|
+
|
|
917
|
+
camera.on('move', () => {
|
|
918
|
+
if (camera.getCenter().lng < -170) {
|
|
919
|
+
crossedAntimeridian = true;
|
|
920
|
+
}
|
|
921
|
+
});
|
|
922
|
+
|
|
923
|
+
camera.on('moveend', () => {
|
|
924
|
+
expect(crossedAntimeridian).toBeTruthy();
|
|
925
|
+
done();
|
|
926
|
+
});
|
|
927
|
+
|
|
928
|
+
stub.mockImplementation(() => 0);
|
|
929
|
+
camera.easeTo({center: [170, 0], duration: 10});
|
|
930
|
+
|
|
931
|
+
setTimeout(() => {
|
|
932
|
+
stub.mockImplementation(() => 1);
|
|
933
|
+
camera.simulateFrame();
|
|
934
|
+
|
|
935
|
+
setTimeout(() => {
|
|
936
|
+
stub.mockImplementation(() => 10);
|
|
937
|
+
camera.simulateFrame();
|
|
938
|
+
}, 0);
|
|
939
|
+
}, 0);
|
|
940
|
+
}));
|
|
941
|
+
|
|
942
|
+
test('does not pan westward across the antimeridian on a single-globe mercator map', () => new Promise<void>(done => {
|
|
943
|
+
const camera = createCamera({renderWorldCopies: false, zoom: 2});
|
|
944
|
+
camera.setCenter([-170, 0]);
|
|
945
|
+
const initialLng = camera.getCenter().lng;
|
|
946
|
+
camera.on('moveend', () => {
|
|
947
|
+
expect(camera.getCenter().lng).toBeCloseTo(initialLng, 0);
|
|
948
|
+
done();
|
|
949
|
+
});
|
|
950
|
+
camera.easeTo({center: [-210, 0], duration: 0});
|
|
951
|
+
}));
|
|
952
|
+
|
|
953
|
+
test('animation occurs when prefers-reduced-motion: reduce is set but overridden by essential: true', () => new Promise<void>(done => {
|
|
954
|
+
const camera = createCamera();
|
|
955
|
+
Object.defineProperty(browser, 'prefersReducedMotion', {value: true});
|
|
956
|
+
const stubNow = jest.spyOn(browser, 'now');
|
|
957
|
+
|
|
958
|
+
// camera transition expected to take in this range when prefersReducedMotion is set and essential: true,
|
|
959
|
+
// when a duration of 200 is requested
|
|
960
|
+
const min = 100;
|
|
961
|
+
const max = 300;
|
|
962
|
+
|
|
963
|
+
let startTime;
|
|
964
|
+
camera
|
|
965
|
+
.on('movestart', () => { startTime = browser.now(); })
|
|
966
|
+
.on('moveend', () => {
|
|
967
|
+
const endTime = browser.now();
|
|
968
|
+
const timeDiff = endTime - startTime;
|
|
969
|
+
expect(timeDiff >= min && timeDiff < max).toBeTruthy();
|
|
970
|
+
done();
|
|
971
|
+
});
|
|
972
|
+
|
|
973
|
+
setTimeout(() => {
|
|
974
|
+
stubNow.mockImplementation(() => 0);
|
|
975
|
+
camera.simulateFrame();
|
|
976
|
+
|
|
977
|
+
camera.easeTo({center: [100, 0], zoom: 3.2, bearing: 90, duration: 200, essential: true});
|
|
978
|
+
|
|
979
|
+
setTimeout(() => {
|
|
980
|
+
stubNow.mockImplementation(() => 200);
|
|
981
|
+
camera.simulateFrame();
|
|
982
|
+
}, 0);
|
|
983
|
+
}, 0);
|
|
984
|
+
}));
|
|
985
|
+
|
|
986
|
+
test('duration is 0 when prefers-reduced-motion: reduce is set', () => new Promise<void>(done => {
|
|
987
|
+
const camera = createCamera();
|
|
988
|
+
Object.defineProperty(browser, 'prefersReducedMotion', {value: true});
|
|
989
|
+
assertTransitionTime(done, camera, 0, 10);
|
|
990
|
+
camera.easeTo({center: [100, 0], zoom: 3.2, bearing: 90, duration: 1000});
|
|
991
|
+
}));
|
|
992
|
+
|
|
993
|
+
test('jumpTo on("move") during easeTo with zoom, pitch, etc', () => new Promise<void>(done => {
|
|
994
|
+
const camera = createCamera();
|
|
995
|
+
|
|
996
|
+
camera.on('moveend', (e: Event & {done?: true}) => {
|
|
997
|
+
if ('done' in e) {
|
|
998
|
+
setTimeout(() => {
|
|
999
|
+
done();
|
|
1000
|
+
}, 50);
|
|
1001
|
+
}
|
|
1002
|
+
});
|
|
1003
|
+
|
|
1004
|
+
camera.easeTo({zoom: 20, bearing: 90, pitch: 60, duration: 500}, {done: true});
|
|
1005
|
+
camera.once('move', () => {
|
|
1006
|
+
camera.jumpTo({pitch: 40});
|
|
1007
|
+
});
|
|
1008
|
+
|
|
1009
|
+
camera.simulateFrame();
|
|
1010
|
+
camera.simulateFrame();
|
|
1011
|
+
}));
|
|
1012
|
+
|
|
1013
|
+
test('jumpTo on("zoom") during easeTo', () => new Promise<void>(done => {
|
|
1014
|
+
const camera = createCamera();
|
|
1015
|
+
|
|
1016
|
+
camera.on('moveend', (e: Event & {done?: true}) => {
|
|
1017
|
+
if ('done' in e) {
|
|
1018
|
+
setTimeout(() => {
|
|
1019
|
+
done();
|
|
1020
|
+
}, 50);
|
|
1021
|
+
}
|
|
1022
|
+
});
|
|
1023
|
+
|
|
1024
|
+
camera.easeTo({zoom: 20, duration: 500}, {done: true});
|
|
1025
|
+
camera.once('zoom', () => {
|
|
1026
|
+
camera.jumpTo({pitch: 40});
|
|
1027
|
+
});
|
|
1028
|
+
|
|
1029
|
+
camera.simulateFrame();
|
|
1030
|
+
camera.simulateFrame();
|
|
1031
|
+
}));
|
|
1032
|
+
|
|
1033
|
+
test('jumpTo on("pitch") during easeTo', () => new Promise<void>(done => {
|
|
1034
|
+
const camera = createCamera();
|
|
1035
|
+
|
|
1036
|
+
camera.on('moveend', (e: Event & {done?: true}) => {
|
|
1037
|
+
if ('done' in e) {
|
|
1038
|
+
setTimeout(() => {
|
|
1039
|
+
done();
|
|
1040
|
+
}, 50);
|
|
1041
|
+
}
|
|
1042
|
+
});
|
|
1043
|
+
|
|
1044
|
+
camera.easeTo({pitch: 60, duration: 500}, {done: true});
|
|
1045
|
+
camera.once('pitch', () => {
|
|
1046
|
+
camera.jumpTo({pitch: 40});
|
|
1047
|
+
});
|
|
1048
|
+
|
|
1049
|
+
camera.simulateFrame();
|
|
1050
|
+
camera.simulateFrame();
|
|
1051
|
+
}));
|
|
1052
|
+
|
|
1053
|
+
test('jumpTo on("rotate") during easeTo', () => new Promise<void>(done => {
|
|
1054
|
+
const camera = createCamera();
|
|
1055
|
+
|
|
1056
|
+
camera.on('moveend', (e: Event & {done?: true}) => {
|
|
1057
|
+
if ('done' in e) {
|
|
1058
|
+
setTimeout(() => {
|
|
1059
|
+
done();
|
|
1060
|
+
}, 50);
|
|
1061
|
+
}
|
|
1062
|
+
});
|
|
1063
|
+
|
|
1064
|
+
camera.easeTo({bearing: 90, duration: 500}, {done: true});
|
|
1065
|
+
camera.once('rotate', () => {
|
|
1066
|
+
camera.jumpTo({pitch: 40});
|
|
1067
|
+
});
|
|
1068
|
+
|
|
1069
|
+
camera.simulateFrame();
|
|
1070
|
+
camera.simulateFrame();
|
|
1071
|
+
}));
|
|
1072
|
+
});
|
|
1073
|
+
|
|
1074
|
+
describe('#flyTo', () => {
|
|
1075
|
+
test('pans to specified location', () => {
|
|
1076
|
+
const camera = createCamera();
|
|
1077
|
+
camera.flyTo({center: [100, 0], animate: false});
|
|
1078
|
+
expect(fixedLngLat(camera.getCenter())).toEqual({lng: 100, lat: 0});
|
|
1079
|
+
});
|
|
1080
|
+
|
|
1081
|
+
test('throws on invalid center argument', () => {
|
|
1082
|
+
const camera = createCamera();
|
|
1083
|
+
expect(() => {
|
|
1084
|
+
camera.flyTo({center: 1});
|
|
1085
|
+
}).toThrow(Error);
|
|
1086
|
+
});
|
|
1087
|
+
|
|
1088
|
+
test('does not throw when cameras current zoom is sufficiently greater than passed zoom option', () => {
|
|
1089
|
+
const camera = createCamera({zoom: 22, center: [0, 0]});
|
|
1090
|
+
expect(() => camera.flyTo({zoom: 10, center: [0, 0]})).not.toThrow();
|
|
1091
|
+
});
|
|
1092
|
+
|
|
1093
|
+
test('does not throw when cameras current zoom is above maxzoom and an offset creates infinite zoom out factor', () => {
|
|
1094
|
+
const transform = new Transform(0, 20.9999, 0, 60, true);
|
|
1095
|
+
transform.resize(512, 512);
|
|
1096
|
+
const camera = attachSimulateFrame(new CameraMock(transform, {} as any))
|
|
1097
|
+
.jumpTo({zoom: 21, center: [0, 0]});
|
|
1098
|
+
camera._update = () => {};
|
|
1099
|
+
expect(() => camera.flyTo({zoom: 7.5, center: [0, 0], offset: [0, 70]})).not.toThrow();
|
|
1100
|
+
});
|
|
1101
|
+
|
|
1102
|
+
test('zooms to specified level', () => {
|
|
1103
|
+
const camera = createCamera();
|
|
1104
|
+
camera.flyTo({zoom: 3.2, animate: false});
|
|
1105
|
+
expect(fixedNum(camera.getZoom())).toBe(3.2);
|
|
1106
|
+
});
|
|
1107
|
+
|
|
1108
|
+
test('zooms to integer level without floating point errors', () => {
|
|
1109
|
+
const camera = createCamera({zoom: 0.6});
|
|
1110
|
+
camera.flyTo({zoom: 2, animate: false});
|
|
1111
|
+
expect(camera.getZoom()).toBe(2);
|
|
1112
|
+
});
|
|
1113
|
+
|
|
1114
|
+
test('Zoom out from the same position to the same position with animation', () => new Promise<void>(done => {
|
|
1115
|
+
const pos = {lng: 0, lat: 0};
|
|
1116
|
+
const camera = createCamera({zoom: 20, center: pos});
|
|
1117
|
+
const stub = jest.spyOn(browser, 'now');
|
|
1118
|
+
|
|
1119
|
+
camera.once('zoomend', () => {
|
|
1120
|
+
expect(fixedLngLat(camera.getCenter())).toEqual(fixedLngLat(pos));
|
|
1121
|
+
expect(camera.getZoom()).toBe(19);
|
|
1122
|
+
done();
|
|
1123
|
+
});
|
|
1124
|
+
|
|
1125
|
+
stub.mockImplementation(() => 0);
|
|
1126
|
+
camera.flyTo({zoom: 19, center: pos, duration: 2});
|
|
1127
|
+
|
|
1128
|
+
stub.mockImplementation(() => 3);
|
|
1129
|
+
camera.simulateFrame();
|
|
1130
|
+
}));
|
|
1131
|
+
|
|
1132
|
+
test('rotates to specified bearing', () => {
|
|
1133
|
+
const camera = createCamera();
|
|
1134
|
+
camera.flyTo({bearing: 90, animate: false});
|
|
1135
|
+
expect(camera.getBearing()).toBe(90);
|
|
1136
|
+
});
|
|
1137
|
+
|
|
1138
|
+
test('tilts to specified pitch', () => {
|
|
1139
|
+
const camera = createCamera();
|
|
1140
|
+
camera.flyTo({pitch: 45, animate: false});
|
|
1141
|
+
expect(camera.getPitch()).toBe(45);
|
|
1142
|
+
});
|
|
1143
|
+
|
|
1144
|
+
test('pans and zooms', () => {
|
|
1145
|
+
const camera = createCamera();
|
|
1146
|
+
camera.flyTo({center: [100, 0], zoom: 3.2, animate: false});
|
|
1147
|
+
expect(fixedLngLat(camera.getCenter())).toEqual({lng: 100, lat: 0});
|
|
1148
|
+
expect(fixedNum(camera.getZoom())).toBe(3.2);
|
|
1149
|
+
});
|
|
1150
|
+
|
|
1151
|
+
test('pans and rotates', () => {
|
|
1152
|
+
const camera = createCamera();
|
|
1153
|
+
camera.flyTo({center: [100, 0], bearing: 90, animate: false});
|
|
1154
|
+
expect(fixedLngLat(camera.getCenter())).toEqual({lng: 100, lat: 0});
|
|
1155
|
+
expect(camera.getBearing()).toBe(90);
|
|
1156
|
+
});
|
|
1157
|
+
|
|
1158
|
+
test('zooms and rotates', () => {
|
|
1159
|
+
const camera = createCamera();
|
|
1160
|
+
camera.flyTo({zoom: 3.2, bearing: 90, animate: false});
|
|
1161
|
+
expect(fixedNum(camera.getZoom())).toBe(3.2);
|
|
1162
|
+
expect(camera.getBearing()).toBe(90);
|
|
1163
|
+
});
|
|
1164
|
+
|
|
1165
|
+
test('pans, zooms, and rotates', () => {
|
|
1166
|
+
const camera = createCamera();
|
|
1167
|
+
camera.flyTo({center: [100, 0], zoom: 3.2, bearing: 90, duration: 0, animate: false});
|
|
1168
|
+
expect(fixedLngLat(camera.getCenter())).toEqual({lng: 100, lat: 0});
|
|
1169
|
+
expect(fixedNum(camera.getZoom())).toBe(3.2);
|
|
1170
|
+
expect(camera.getBearing()).toBe(90);
|
|
1171
|
+
});
|
|
1172
|
+
|
|
1173
|
+
test('noop', () => {
|
|
1174
|
+
const camera = createCamera();
|
|
1175
|
+
camera.flyTo({animate: false});
|
|
1176
|
+
expect(fixedLngLat(camera.getCenter())).toEqual({lng: 0, lat: 0});
|
|
1177
|
+
expect(camera.getZoom()).toBe(0);
|
|
1178
|
+
expect(camera.getBearing()).toBeCloseTo(0);
|
|
1179
|
+
});
|
|
1180
|
+
|
|
1181
|
+
test('noop with offset', () => {
|
|
1182
|
+
const camera = createCamera();
|
|
1183
|
+
camera.flyTo({offset: [100, 0], animate: false});
|
|
1184
|
+
expect(fixedLngLat(camera.getCenter())).toEqual({lng: 0, lat: 0});
|
|
1185
|
+
expect(camera.getZoom()).toBe(0);
|
|
1186
|
+
expect(camera.getBearing()).toBeCloseTo(0);
|
|
1187
|
+
});
|
|
1188
|
+
|
|
1189
|
+
test('pans with specified offset', () => {
|
|
1190
|
+
const camera = createCamera();
|
|
1191
|
+
camera.flyTo({center: [100, 0], offset: [100, 0], animate: false});
|
|
1192
|
+
expect(fixedLngLat(camera.getCenter())).toEqual({lng: 29.6875, lat: 0});
|
|
1193
|
+
});
|
|
1194
|
+
|
|
1195
|
+
test('pans with specified offset relative to viewport on a rotated camera', () => {
|
|
1196
|
+
const camera = createCamera({bearing: 180});
|
|
1197
|
+
camera.easeTo({center: [100, 0], offset: [100, 0], animate: false});
|
|
1198
|
+
expect(fixedLngLat(camera.getCenter())).toEqual({lng: 170.3125, lat: 0});
|
|
1199
|
+
});
|
|
1200
|
+
|
|
1201
|
+
test('emits move, zoom, rotate, and pitch events, preserving eventData', () => {
|
|
1202
|
+
expect.assertions(18);
|
|
1203
|
+
|
|
1204
|
+
const camera = createCamera();
|
|
1205
|
+
let movestarted, moved, zoomstarted, zoomed, rotatestarted, rotated, pitchstarted, pitched;
|
|
1206
|
+
const eventData = {data: 'ok'};
|
|
1207
|
+
|
|
1208
|
+
camera
|
|
1209
|
+
.on('movestart', (d) => { movestarted = d.data; })
|
|
1210
|
+
.on('move', (d) => { moved = d.data; })
|
|
1211
|
+
.on('rotate', (d) => { rotated = d.data; })
|
|
1212
|
+
.on('pitch', (d) => { pitched = d.data; })
|
|
1213
|
+
.on('moveend', (d) => {
|
|
1214
|
+
expect(camera._zooming).toBeFalsy();
|
|
1215
|
+
expect(camera._panning).toBeFalsy();
|
|
1216
|
+
expect(camera._rotating).toBeFalsy();
|
|
1217
|
+
|
|
1218
|
+
expect(movestarted).toBe('ok');
|
|
1219
|
+
expect(moved).toBe('ok');
|
|
1220
|
+
expect(zoomed).toBe('ok');
|
|
1221
|
+
expect(rotated).toBe('ok');
|
|
1222
|
+
expect(pitched).toBe('ok');
|
|
1223
|
+
expect(d.data).toBe('ok');
|
|
1224
|
+
});
|
|
1225
|
+
|
|
1226
|
+
camera
|
|
1227
|
+
.on('zoomstart', (d) => { zoomstarted = d.data; })
|
|
1228
|
+
.on('zoom', (d) => { zoomed = d.data; })
|
|
1229
|
+
.on('zoomend', (d) => {
|
|
1230
|
+
expect(zoomstarted).toBe('ok');
|
|
1231
|
+
expect(zoomed).toBe('ok');
|
|
1232
|
+
expect(d.data).toBe('ok');
|
|
1233
|
+
});
|
|
1234
|
+
|
|
1235
|
+
camera
|
|
1236
|
+
.on('rotatestart', (d) => { rotatestarted = d.data; })
|
|
1237
|
+
.on('rotate', (d) => { rotated = d.data; })
|
|
1238
|
+
.on('rotateend', (d) => {
|
|
1239
|
+
expect(rotatestarted).toBe('ok');
|
|
1240
|
+
expect(rotated).toBe('ok');
|
|
1241
|
+
expect(d.data).toBe('ok');
|
|
1242
|
+
});
|
|
1243
|
+
|
|
1244
|
+
camera
|
|
1245
|
+
.on('pitchstart', (d) => { pitchstarted = d.data; })
|
|
1246
|
+
.on('pitch', (d) => { pitched = d.data; })
|
|
1247
|
+
.on('pitchend', (d) => {
|
|
1248
|
+
expect(pitchstarted).toBe('ok');
|
|
1249
|
+
expect(pitched).toBe('ok');
|
|
1250
|
+
expect(d.data).toBe('ok');
|
|
1251
|
+
});
|
|
1252
|
+
|
|
1253
|
+
camera.flyTo(
|
|
1254
|
+
{center: [100, 0], zoom: 3.2, bearing: 90, duration: 0, pitch: 45, animate: false},
|
|
1255
|
+
eventData);
|
|
1256
|
+
});
|
|
1257
|
+
|
|
1258
|
+
test('for short flights, emits (solely) move events, preserving eventData', () => new Promise<void>(done => {
|
|
1259
|
+
//As I type this, the code path for guiding super-short flights is (and will probably remain) different.
|
|
1260
|
+
//As such; it deserves a separate test case. This test case flies the map from A to A.
|
|
1261
|
+
const camera = createCamera({center: [100, 0]});
|
|
1262
|
+
let movestarted, moved,
|
|
1263
|
+
zoomstarted, zoomed, zoomended,
|
|
1264
|
+
rotatestarted, rotated, rotateended,
|
|
1265
|
+
pitchstarted, pitched, pitchended;
|
|
1266
|
+
const eventData = {data: 'ok'};
|
|
1267
|
+
|
|
1268
|
+
camera
|
|
1269
|
+
.on('movestart', (d) => { movestarted = d.data; })
|
|
1270
|
+
.on('move', (d) => { moved = d.data; })
|
|
1271
|
+
.on('zoomstart', (d) => { zoomstarted = d.data; })
|
|
1272
|
+
.on('zoom', (d) => { zoomed = d.data; })
|
|
1273
|
+
.on('zoomend', (d) => { zoomended = d.data; })
|
|
1274
|
+
.on('rotatestart', (d) => { rotatestarted = d.data; })
|
|
1275
|
+
.on('rotate', (d) => { rotated = d.data; })
|
|
1276
|
+
.on('rotateend', (d) => { rotateended = d.data; })
|
|
1277
|
+
.on('pitchstart', (d) => { pitchstarted = d.data; })
|
|
1278
|
+
.on('pitch', (d) => { pitched = d.data; })
|
|
1279
|
+
.on('pitchend', (d) => { pitchended = d.data; })
|
|
1280
|
+
.on('moveend', (d) => {
|
|
1281
|
+
expect(camera._zooming).toBeFalsy();
|
|
1282
|
+
expect(camera._panning).toBeFalsy();
|
|
1283
|
+
expect(camera._rotating).toBeFalsy();
|
|
1284
|
+
|
|
1285
|
+
expect(movestarted).toBe('ok');
|
|
1286
|
+
expect(moved).toBe('ok');
|
|
1287
|
+
expect(zoomstarted).toBeUndefined();
|
|
1288
|
+
expect(zoomed).toBeUndefined();
|
|
1289
|
+
expect(zoomended).toBeUndefined();
|
|
1290
|
+
expect(rotatestarted).toBeUndefined();
|
|
1291
|
+
expect(rotated).toBeUndefined();
|
|
1292
|
+
expect(rotateended).toBeUndefined();
|
|
1293
|
+
expect(pitched).toBeUndefined();
|
|
1294
|
+
expect(pitchstarted).toBeUndefined();
|
|
1295
|
+
expect(pitchended).toBeUndefined();
|
|
1296
|
+
expect(d.data).toBe('ok');
|
|
1297
|
+
done();
|
|
1298
|
+
});
|
|
1299
|
+
|
|
1300
|
+
const stub = jest.spyOn(browser, 'now');
|
|
1301
|
+
stub.mockImplementation(() => 0);
|
|
1302
|
+
|
|
1303
|
+
camera.flyTo({center: [100, 0], duration: 10}, eventData);
|
|
1304
|
+
|
|
1305
|
+
setTimeout(() => {
|
|
1306
|
+
stub.mockImplementation(() => 1);
|
|
1307
|
+
camera.simulateFrame();
|
|
1308
|
+
|
|
1309
|
+
setTimeout(() => {
|
|
1310
|
+
stub.mockImplementation(() => 10);
|
|
1311
|
+
camera.simulateFrame();
|
|
1312
|
+
}, 0);
|
|
1313
|
+
}, 0);
|
|
1314
|
+
}));
|
|
1315
|
+
|
|
1316
|
+
test('stops existing ease', () => {
|
|
1317
|
+
const camera = createCamera();
|
|
1318
|
+
camera.flyTo({center: [200, 0], duration: 100});
|
|
1319
|
+
camera.flyTo({center: [100, 0], duration: 0});
|
|
1320
|
+
expect(fixedLngLat(camera.getCenter())).toEqual({lng: 100, lat: 0});
|
|
1321
|
+
});
|
|
1322
|
+
|
|
1323
|
+
test('can be called from within a moveend event handler', () => new Promise<void>(done => {
|
|
1324
|
+
const camera = createCamera();
|
|
1325
|
+
const stub = jest.spyOn(browser, 'now');
|
|
1326
|
+
stub.mockImplementation(() => 0);
|
|
1327
|
+
|
|
1328
|
+
camera.flyTo({center: [100, 0], duration: 10});
|
|
1329
|
+
camera.once('moveend', () => {
|
|
1330
|
+
camera.flyTo({center: [200, 0], duration: 10});
|
|
1331
|
+
camera.once('moveend', () => {
|
|
1332
|
+
camera.flyTo({center: [300, 0], duration: 10});
|
|
1333
|
+
camera.once('moveend', () => {
|
|
1334
|
+
done();
|
|
1335
|
+
});
|
|
1336
|
+
});
|
|
1337
|
+
});
|
|
1338
|
+
|
|
1339
|
+
setTimeout(() => {
|
|
1340
|
+
stub.mockImplementation(() => 10);
|
|
1341
|
+
camera.simulateFrame();
|
|
1342
|
+
|
|
1343
|
+
setTimeout(() => {
|
|
1344
|
+
stub.mockImplementation(() => 20);
|
|
1345
|
+
camera.simulateFrame();
|
|
1346
|
+
|
|
1347
|
+
setTimeout(() => {
|
|
1348
|
+
stub.mockImplementation(() => 30);
|
|
1349
|
+
camera.simulateFrame();
|
|
1350
|
+
}, 0);
|
|
1351
|
+
}, 0);
|
|
1352
|
+
}, 0);
|
|
1353
|
+
}));
|
|
1354
|
+
|
|
1355
|
+
test('ascends', () => new Promise<void>(done => {
|
|
1356
|
+
const camera = createCamera();
|
|
1357
|
+
camera.setZoom(18);
|
|
1358
|
+
let ascended;
|
|
1359
|
+
|
|
1360
|
+
camera.on('zoom', () => {
|
|
1361
|
+
if (camera.getZoom() < 18) {
|
|
1362
|
+
ascended = true;
|
|
1363
|
+
}
|
|
1364
|
+
});
|
|
1365
|
+
|
|
1366
|
+
camera.on('moveend', () => {
|
|
1367
|
+
expect(ascended).toBeTruthy();
|
|
1368
|
+
done();
|
|
1369
|
+
});
|
|
1370
|
+
|
|
1371
|
+
const stub = jest.spyOn(browser, 'now');
|
|
1372
|
+
stub.mockImplementation(() => 0);
|
|
1373
|
+
|
|
1374
|
+
camera.flyTo({center: [100, 0], zoom: 18, duration: 10});
|
|
1375
|
+
|
|
1376
|
+
setTimeout(() => {
|
|
1377
|
+
stub.mockImplementation(() => 1);
|
|
1378
|
+
camera.simulateFrame();
|
|
1379
|
+
|
|
1380
|
+
setTimeout(() => {
|
|
1381
|
+
stub.mockImplementation(() => 10);
|
|
1382
|
+
camera.simulateFrame();
|
|
1383
|
+
}, 0);
|
|
1384
|
+
}, 0);
|
|
1385
|
+
}));
|
|
1386
|
+
|
|
1387
|
+
test('pans eastward across the prime meridian', () => new Promise<void>(done => {
|
|
1388
|
+
const camera = createCamera();
|
|
1389
|
+
const stub = jest.spyOn(browser, 'now');
|
|
1390
|
+
|
|
1391
|
+
camera.setCenter([-10, 0]);
|
|
1392
|
+
let crossedPrimeMeridian;
|
|
1393
|
+
|
|
1394
|
+
camera.on('move', () => {
|
|
1395
|
+
if (Math.abs(camera.getCenter().lng) < 10) {
|
|
1396
|
+
crossedPrimeMeridian = true;
|
|
1397
|
+
}
|
|
1398
|
+
});
|
|
1399
|
+
|
|
1400
|
+
camera.on('moveend', () => {
|
|
1401
|
+
expect(crossedPrimeMeridian).toBeTruthy();
|
|
1402
|
+
done();
|
|
1403
|
+
});
|
|
1404
|
+
|
|
1405
|
+
stub.mockImplementation(() => 0);
|
|
1406
|
+
camera.flyTo({center: [10, 0], duration: 20});
|
|
1407
|
+
|
|
1408
|
+
setTimeout(() => {
|
|
1409
|
+
stub.mockImplementation(() => 1);
|
|
1410
|
+
camera.simulateFrame();
|
|
1411
|
+
|
|
1412
|
+
setTimeout(() => {
|
|
1413
|
+
stub.mockImplementation(() => 20);
|
|
1414
|
+
camera.simulateFrame();
|
|
1415
|
+
}, 0);
|
|
1416
|
+
}, 0);
|
|
1417
|
+
}));
|
|
1418
|
+
|
|
1419
|
+
test('pans westward across the prime meridian', () => new Promise<void>(done => {
|
|
1420
|
+
const camera = createCamera();
|
|
1421
|
+
const stub = jest.spyOn(browser, 'now');
|
|
1422
|
+
|
|
1423
|
+
camera.setCenter([10, 0]);
|
|
1424
|
+
let crossedPrimeMeridian;
|
|
1425
|
+
|
|
1426
|
+
camera.on('move', () => {
|
|
1427
|
+
if (Math.abs(camera.getCenter().lng) < 10) {
|
|
1428
|
+
crossedPrimeMeridian = true;
|
|
1429
|
+
}
|
|
1430
|
+
});
|
|
1431
|
+
|
|
1432
|
+
camera.on('moveend', () => {
|
|
1433
|
+
expect(crossedPrimeMeridian).toBeTruthy();
|
|
1434
|
+
done();
|
|
1435
|
+
});
|
|
1436
|
+
|
|
1437
|
+
stub.mockImplementation(() => 0);
|
|
1438
|
+
camera.flyTo({center: [-10, 0], duration: 20});
|
|
1439
|
+
|
|
1440
|
+
setTimeout(() => {
|
|
1441
|
+
stub.mockImplementation(() => 1);
|
|
1442
|
+
camera.simulateFrame();
|
|
1443
|
+
|
|
1444
|
+
setTimeout(() => {
|
|
1445
|
+
stub.mockImplementation(() => 20);
|
|
1446
|
+
camera.simulateFrame();
|
|
1447
|
+
}, 0);
|
|
1448
|
+
}, 0);
|
|
1449
|
+
}));
|
|
1450
|
+
|
|
1451
|
+
test('pans eastward across the antimeridian', () => new Promise<void>(done => {
|
|
1452
|
+
const camera = createCamera();
|
|
1453
|
+
const stub = jest.spyOn(browser, 'now');
|
|
1454
|
+
|
|
1455
|
+
camera.setCenter([170, 0]);
|
|
1456
|
+
let crossedAntimeridian;
|
|
1457
|
+
|
|
1458
|
+
camera.on('move', () => {
|
|
1459
|
+
if (camera.getCenter().lng > 170) {
|
|
1460
|
+
crossedAntimeridian = true;
|
|
1461
|
+
}
|
|
1462
|
+
});
|
|
1463
|
+
|
|
1464
|
+
camera.on('moveend', () => {
|
|
1465
|
+
expect(crossedAntimeridian).toBeTruthy();
|
|
1466
|
+
done();
|
|
1467
|
+
});
|
|
1468
|
+
|
|
1469
|
+
stub.mockImplementation(() => 0);
|
|
1470
|
+
camera.flyTo({center: [-170, 0], duration: 20});
|
|
1471
|
+
|
|
1472
|
+
setTimeout(() => {
|
|
1473
|
+
stub.mockImplementation(() => 1);
|
|
1474
|
+
camera.simulateFrame();
|
|
1475
|
+
|
|
1476
|
+
setTimeout(() => {
|
|
1477
|
+
stub.mockImplementation(() => 20);
|
|
1478
|
+
camera.simulateFrame();
|
|
1479
|
+
}, 0);
|
|
1480
|
+
}, 0);
|
|
1481
|
+
}));
|
|
1482
|
+
|
|
1483
|
+
test('pans westward across the antimeridian', () => new Promise<void>(done => {
|
|
1484
|
+
const camera = createCamera();
|
|
1485
|
+
const stub = jest.spyOn(browser, 'now');
|
|
1486
|
+
|
|
1487
|
+
camera.setCenter([-170, 0]);
|
|
1488
|
+
let crossedAntimeridian;
|
|
1489
|
+
|
|
1490
|
+
camera.on('move', () => {
|
|
1491
|
+
if (camera.getCenter().lng < -170) {
|
|
1492
|
+
crossedAntimeridian = true;
|
|
1493
|
+
}
|
|
1494
|
+
});
|
|
1495
|
+
|
|
1496
|
+
camera.on('moveend', () => {
|
|
1497
|
+
expect(crossedAntimeridian).toBeTruthy();
|
|
1498
|
+
done();
|
|
1499
|
+
});
|
|
1500
|
+
|
|
1501
|
+
stub.mockImplementation(() => 0);
|
|
1502
|
+
camera.flyTo({center: [170, 0], duration: 10});
|
|
1503
|
+
|
|
1504
|
+
setTimeout(() => {
|
|
1505
|
+
stub.mockImplementation(() => 1);
|
|
1506
|
+
camera.simulateFrame();
|
|
1507
|
+
|
|
1508
|
+
setTimeout(() => {
|
|
1509
|
+
stub.mockImplementation(() => 10);
|
|
1510
|
+
camera.simulateFrame();
|
|
1511
|
+
}, 0);
|
|
1512
|
+
}, 0);
|
|
1513
|
+
}));
|
|
1514
|
+
|
|
1515
|
+
test('does not pan eastward across the antimeridian if no world copies', () => new Promise<void>(done => {
|
|
1516
|
+
const camera = createCamera({renderWorldCopies: false});
|
|
1517
|
+
const stub = jest.spyOn(browser, 'now');
|
|
1518
|
+
|
|
1519
|
+
camera.setCenter([170, 0]);
|
|
1520
|
+
let crossedAntimeridian;
|
|
1521
|
+
|
|
1522
|
+
camera.on('move', () => {
|
|
1523
|
+
if (camera.getCenter().lng > 170) {
|
|
1524
|
+
crossedAntimeridian = true;
|
|
1525
|
+
}
|
|
1526
|
+
});
|
|
1527
|
+
|
|
1528
|
+
camera.on('moveend', () => {
|
|
1529
|
+
expect(crossedAntimeridian).toBeFalsy();
|
|
1530
|
+
done();
|
|
1531
|
+
});
|
|
1532
|
+
|
|
1533
|
+
stub.mockImplementation(() => 0);
|
|
1534
|
+
camera.flyTo({center: [-170, 0], duration: 10});
|
|
1535
|
+
|
|
1536
|
+
setTimeout(() => {
|
|
1537
|
+
stub.mockImplementation(() => 1);
|
|
1538
|
+
camera.simulateFrame();
|
|
1539
|
+
|
|
1540
|
+
setTimeout(() => {
|
|
1541
|
+
stub.mockImplementation(() => 10);
|
|
1542
|
+
camera.simulateFrame();
|
|
1543
|
+
}, 0);
|
|
1544
|
+
}, 0);
|
|
1545
|
+
}));
|
|
1546
|
+
|
|
1547
|
+
test('does not pan westward across the antimeridian if no world copies', () => new Promise<void>(done => {
|
|
1548
|
+
const camera = createCamera({renderWorldCopies: false});
|
|
1549
|
+
const stub = jest.spyOn(browser, 'now');
|
|
1550
|
+
|
|
1551
|
+
camera.setCenter([-170, 0]);
|
|
1552
|
+
let crossedAntimeridian;
|
|
1553
|
+
|
|
1554
|
+
camera.on('move', () => {
|
|
1555
|
+
if (fixedLngLat(camera.getCenter(), 10).lng < -170) {
|
|
1556
|
+
crossedAntimeridian = true;
|
|
1557
|
+
}
|
|
1558
|
+
});
|
|
1559
|
+
|
|
1560
|
+
camera.on('moveend', () => {
|
|
1561
|
+
expect(crossedAntimeridian).toBeFalsy();
|
|
1562
|
+
done();
|
|
1563
|
+
});
|
|
1564
|
+
|
|
1565
|
+
stub.mockImplementation(() => 0);
|
|
1566
|
+
camera.flyTo({center: [170, 0], duration: 10});
|
|
1567
|
+
|
|
1568
|
+
setTimeout(() => {
|
|
1569
|
+
stub.mockImplementation(() => 1);
|
|
1570
|
+
camera.simulateFrame();
|
|
1571
|
+
|
|
1572
|
+
setTimeout(() => {
|
|
1573
|
+
stub.mockImplementation(() => 10);
|
|
1574
|
+
camera.simulateFrame();
|
|
1575
|
+
}, 0);
|
|
1576
|
+
}, 0);
|
|
1577
|
+
}));
|
|
1578
|
+
|
|
1579
|
+
test('jumps back to world 0 when crossing the antimeridian', () => new Promise<void>(done => {
|
|
1580
|
+
const camera = createCamera();
|
|
1581
|
+
const stub = jest.spyOn(browser, 'now');
|
|
1582
|
+
|
|
1583
|
+
camera.setCenter([-170, 0]);
|
|
1584
|
+
|
|
1585
|
+
let leftWorld0 = false;
|
|
1586
|
+
|
|
1587
|
+
camera.on('move', () => {
|
|
1588
|
+
leftWorld0 = leftWorld0 || (camera.getCenter().lng < -180);
|
|
1589
|
+
});
|
|
1590
|
+
|
|
1591
|
+
camera.on('moveend', () => {
|
|
1592
|
+
expect(leftWorld0).toBeFalsy();
|
|
1593
|
+
done();
|
|
1594
|
+
});
|
|
1595
|
+
|
|
1596
|
+
stub.mockImplementation(() => 0);
|
|
1597
|
+
camera.flyTo({center: [170, 0], duration: 10});
|
|
1598
|
+
|
|
1599
|
+
setTimeout(() => {
|
|
1600
|
+
stub.mockImplementation(() => 1);
|
|
1601
|
+
camera.simulateFrame();
|
|
1602
|
+
|
|
1603
|
+
setTimeout(() => {
|
|
1604
|
+
stub.mockImplementation(() => 10);
|
|
1605
|
+
camera.simulateFrame();
|
|
1606
|
+
}, 0);
|
|
1607
|
+
}, 0);
|
|
1608
|
+
}));
|
|
1609
|
+
|
|
1610
|
+
test('peaks at the specified zoom level', () => new Promise<void>(done => {
|
|
1611
|
+
const camera = createCamera({zoom: 20});
|
|
1612
|
+
const stub = jest.spyOn(browser, 'now');
|
|
1613
|
+
|
|
1614
|
+
const minZoom = 1;
|
|
1615
|
+
let zoomed = false;
|
|
1616
|
+
|
|
1617
|
+
camera.on('zoom', () => {
|
|
1618
|
+
const zoom = camera.getZoom();
|
|
1619
|
+
if (zoom < 1) {
|
|
1620
|
+
throw new Error(`${zoom} should be >= ${minZoom} during flyTo`);
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1623
|
+
if (camera.getZoom() < (minZoom + 1)) {
|
|
1624
|
+
zoomed = true;
|
|
1625
|
+
}
|
|
1626
|
+
});
|
|
1627
|
+
|
|
1628
|
+
camera.on('moveend', () => {
|
|
1629
|
+
expect(zoomed).toBeTruthy();
|
|
1630
|
+
done();
|
|
1631
|
+
});
|
|
1632
|
+
|
|
1633
|
+
stub.mockImplementation(() => 0);
|
|
1634
|
+
camera.flyTo({center: [1, 0], zoom: 20, minZoom, duration: 10});
|
|
1635
|
+
|
|
1636
|
+
setTimeout(() => {
|
|
1637
|
+
stub.mockImplementation(() => 3);
|
|
1638
|
+
camera.simulateFrame();
|
|
1639
|
+
|
|
1640
|
+
setTimeout(() => {
|
|
1641
|
+
stub.mockImplementation(() => 10);
|
|
1642
|
+
camera.simulateFrame();
|
|
1643
|
+
}, 0);
|
|
1644
|
+
}, 0);
|
|
1645
|
+
}));
|
|
1646
|
+
|
|
1647
|
+
test('respects transform\'s maxZoom', () => new Promise<void>(done => {
|
|
1648
|
+
const transform = new Transform(2, 10, 0, 60, false);
|
|
1649
|
+
transform.resize(512, 512);
|
|
1650
|
+
|
|
1651
|
+
const camera = attachSimulateFrame(new CameraMock(transform, {} as any));
|
|
1652
|
+
camera._update = () => {};
|
|
1653
|
+
|
|
1654
|
+
camera.on('moveend', () => {
|
|
1655
|
+
expect(camera.getZoom()).toBeCloseTo(10);
|
|
1656
|
+
const {lng, lat} = camera.getCenter();
|
|
1657
|
+
expect(lng).toBeCloseTo(12);
|
|
1658
|
+
expect(lat).toBeCloseTo(34);
|
|
1659
|
+
done();
|
|
1660
|
+
});
|
|
1661
|
+
|
|
1662
|
+
const stub = jest.spyOn(browser, 'now');
|
|
1663
|
+
stub.mockImplementation(() => 0);
|
|
1664
|
+
camera.flyTo({center: [12, 34], zoom: 30, duration: 10});
|
|
1665
|
+
|
|
1666
|
+
setTimeout(() => {
|
|
1667
|
+
stub.mockImplementation(() => 10);
|
|
1668
|
+
camera.simulateFrame();
|
|
1669
|
+
}, 0);
|
|
1670
|
+
}));
|
|
1671
|
+
|
|
1672
|
+
test('respects transform\'s minZoom', () => new Promise<void>(done => {
|
|
1673
|
+
const transform = new Transform(2, 10, 0, 60, false);
|
|
1674
|
+
transform.resize(512, 512);
|
|
1675
|
+
|
|
1676
|
+
const camera = attachSimulateFrame(new CameraMock(transform, {} as any));
|
|
1677
|
+
camera._update = () => {};
|
|
1678
|
+
|
|
1679
|
+
camera.on('moveend', () => {
|
|
1680
|
+
expect(camera.getZoom()).toBeCloseTo(2);
|
|
1681
|
+
const {lng, lat} = camera.getCenter();
|
|
1682
|
+
expect(lng).toBeCloseTo(12);
|
|
1683
|
+
expect(lat).toBeCloseTo(34);
|
|
1684
|
+
done();
|
|
1685
|
+
});
|
|
1686
|
+
|
|
1687
|
+
const stub = jest.spyOn(browser, 'now');
|
|
1688
|
+
stub.mockImplementation(() => 0);
|
|
1689
|
+
camera.flyTo({center: [12, 34], zoom: 1, duration: 10});
|
|
1690
|
+
|
|
1691
|
+
setTimeout(() => {
|
|
1692
|
+
stub.mockImplementation(() => 10);
|
|
1693
|
+
camera.simulateFrame();
|
|
1694
|
+
}, 0);
|
|
1695
|
+
}));
|
|
1696
|
+
|
|
1697
|
+
test('resets duration to 0 if it exceeds maxDuration', () => new Promise<void>(done => {
|
|
1698
|
+
let startTime, endTime, timeDiff;
|
|
1699
|
+
const camera = createCamera({center: [37.63454, 55.75868], zoom: 18});
|
|
1700
|
+
|
|
1701
|
+
camera
|
|
1702
|
+
.on('movestart', () => { startTime = new Date(); })
|
|
1703
|
+
.on('moveend', () => {
|
|
1704
|
+
endTime = new Date();
|
|
1705
|
+
timeDiff = endTime - startTime;
|
|
1706
|
+
expect(timeDiff).toBeLessThan(30);
|
|
1707
|
+
done();
|
|
1708
|
+
});
|
|
1709
|
+
|
|
1710
|
+
camera.flyTo({center: [-122.3998631, 37.7884307], maxDuration: 100});
|
|
1711
|
+
}));
|
|
1712
|
+
|
|
1713
|
+
test('flys instantly when prefers-reduce-motion:reduce is set', () => new Promise<void>(done => {
|
|
1714
|
+
const camera = createCamera();
|
|
1715
|
+
Object.defineProperty(browser, 'prefersReducedMotion', {value: true});
|
|
1716
|
+
assertTransitionTime(done, camera, 0, 10);
|
|
1717
|
+
camera.flyTo({center: [100, 0], bearing: 90, animate: true});
|
|
1718
|
+
}));
|
|
1719
|
+
|
|
1720
|
+
test('check elevation events freezeElevation=false', async () => {
|
|
1721
|
+
const camera = createCamera();
|
|
1722
|
+
const stub = jest.spyOn(browser, 'now');
|
|
1723
|
+
|
|
1724
|
+
const terrainCallbacks = {prepare: 0, update: 0, finalize: 0} as any;
|
|
1725
|
+
camera.terrain = {} as Terrain;
|
|
1726
|
+
camera._prepareElevation = () => { terrainCallbacks.prepare++; };
|
|
1727
|
+
camera._updateElevation = () => { terrainCallbacks.update++; };
|
|
1728
|
+
camera._finalizeElevation = () => { terrainCallbacks.finalize++; };
|
|
1729
|
+
camera.setCenter([-10, 0]);
|
|
1730
|
+
const moveEnded = camera.once('moveend');
|
|
1731
|
+
|
|
1732
|
+
stub.mockImplementation(() => 0);
|
|
1733
|
+
camera.flyTo({center: [10, 0], duration: 20, freezeElevation: false});
|
|
1734
|
+
stub.mockImplementation(() => 1);
|
|
1735
|
+
camera.simulateFrame();
|
|
1736
|
+
stub.mockImplementation(() => 20);
|
|
1737
|
+
camera.simulateFrame();
|
|
1738
|
+
await moveEnded;
|
|
1739
|
+
expect(terrainCallbacks.prepare).toBe(1);
|
|
1740
|
+
expect(terrainCallbacks.update).toBe(2);
|
|
1741
|
+
expect(terrainCallbacks.finalize).toBe(0);
|
|
1742
|
+
});
|
|
1743
|
+
|
|
1744
|
+
test('check elevation events freezeElevation=true', async() => {
|
|
1745
|
+
const camera = createCamera();
|
|
1746
|
+
const stub = jest.spyOn(browser, 'now');
|
|
1747
|
+
|
|
1748
|
+
const terrainCallbacks = {prepare: 0, update: 0, finalize: 0} as any;
|
|
1749
|
+
camera.terrain = {} as Terrain;
|
|
1750
|
+
camera._prepareElevation = () => { terrainCallbacks.prepare++; };
|
|
1751
|
+
camera._updateElevation = () => { terrainCallbacks.update++; };
|
|
1752
|
+
camera._finalizeElevation = () => { terrainCallbacks.finalize++; };
|
|
1753
|
+
camera.setCenter([-10, 0]);
|
|
1754
|
+
const moveEnded = camera.once('moveend');
|
|
1755
|
+
|
|
1756
|
+
stub.mockImplementation(() => 0);
|
|
1757
|
+
camera.flyTo({center: [10, 0], duration: 20, freezeElevation: true});
|
|
1758
|
+
stub.mockImplementation(() => 1);
|
|
1759
|
+
camera.simulateFrame();
|
|
1760
|
+
stub.mockImplementation(() => 20);
|
|
1761
|
+
camera.simulateFrame();
|
|
1762
|
+
await moveEnded;
|
|
1763
|
+
expect(terrainCallbacks.prepare).toBe(1);
|
|
1764
|
+
expect(terrainCallbacks.update).toBe(0);
|
|
1765
|
+
expect(terrainCallbacks.finalize).toBe(1);
|
|
1766
|
+
});
|
|
1767
|
+
|
|
1768
|
+
test('check elevation callbacks', () => {
|
|
1769
|
+
const camera = createCamera();
|
|
1770
|
+
camera.terrain = {
|
|
1771
|
+
getElevationForLngLatZoom: () => 100,
|
|
1772
|
+
getMinTileElevationForLngLatZoom: () => 200
|
|
1773
|
+
};
|
|
1774
|
+
camera.transform = {
|
|
1775
|
+
elevation: 0,
|
|
1776
|
+
recalculateZoom: () => true
|
|
1777
|
+
};
|
|
1778
|
+
|
|
1779
|
+
camera._prepareElevation([10, 0]);
|
|
1780
|
+
// expect(camera._elevationCenter).toBe([10, 0]);
|
|
1781
|
+
expect(camera._elevationStart).toBe(0);
|
|
1782
|
+
expect(camera._elevationTarget).toBe(100);
|
|
1783
|
+
expect(camera._elevationFreeze).toBeTruthy();
|
|
1784
|
+
|
|
1785
|
+
camera.terrain.getElevationForLngLatZoom = () => 200;
|
|
1786
|
+
camera._updateElevation(0.5);
|
|
1787
|
+
expect(camera._elevationStart).toBe(-100);
|
|
1788
|
+
expect(camera._elevationTarget).toBe(200);
|
|
1789
|
+
|
|
1790
|
+
camera._finalizeElevation();
|
|
1791
|
+
expect(camera._elevationFreeze).toBeFalsy();
|
|
1792
|
+
});
|
|
1793
|
+
});
|
|
1794
|
+
|
|
1795
|
+
describe('#isEasing', () => {
|
|
1796
|
+
test('returns false when not easing', () => {
|
|
1797
|
+
const camera = createCamera();
|
|
1798
|
+
expect(!camera.isEasing()).toBeTruthy();
|
|
1799
|
+
});
|
|
1800
|
+
|
|
1801
|
+
test('returns true when panning', () => {
|
|
1802
|
+
const camera = createCamera();
|
|
1803
|
+
camera.panTo([100, 0], {duration: 1});
|
|
1804
|
+
expect(camera.isEasing()).toBeTruthy();
|
|
1805
|
+
});
|
|
1806
|
+
|
|
1807
|
+
test('returns false when done panning', () => new Promise<void>(done => {
|
|
1808
|
+
const camera = createCamera();
|
|
1809
|
+
camera.on('moveend', () => {
|
|
1810
|
+
expect(!camera.isEasing()).toBeTruthy();
|
|
1811
|
+
done();
|
|
1812
|
+
});
|
|
1813
|
+
const stub = jest.spyOn(browser, 'now');
|
|
1814
|
+
stub.mockImplementation(() => 0);
|
|
1815
|
+
camera.panTo([100, 0], {duration: 1});
|
|
1816
|
+
setTimeout(() => {
|
|
1817
|
+
stub.mockImplementation(() => 1);
|
|
1818
|
+
camera.simulateFrame();
|
|
1819
|
+
}, 0);
|
|
1820
|
+
}));
|
|
1821
|
+
|
|
1822
|
+
test('returns true when zooming', () => {
|
|
1823
|
+
const camera = createCamera();
|
|
1824
|
+
camera.zoomTo(3.2, {duration: 1});
|
|
1825
|
+
|
|
1826
|
+
expect(camera.isEasing()).toBeTruthy();
|
|
1827
|
+
});
|
|
1828
|
+
|
|
1829
|
+
test('returns false when done zooming', () => new Promise<void>(done => {
|
|
1830
|
+
const camera = createCamera();
|
|
1831
|
+
camera.on('moveend', () => {
|
|
1832
|
+
expect(!camera.isEasing()).toBeTruthy();
|
|
1833
|
+
done();
|
|
1834
|
+
});
|
|
1835
|
+
const stub = jest.spyOn(browser, 'now');
|
|
1836
|
+
stub.mockImplementation(() => 0);
|
|
1837
|
+
camera.zoomTo(3.2, {duration: 1});
|
|
1838
|
+
setTimeout(() => {
|
|
1839
|
+
stub.mockImplementation(() => 1);
|
|
1840
|
+
camera.simulateFrame();
|
|
1841
|
+
}, 0);
|
|
1842
|
+
}));
|
|
1843
|
+
|
|
1844
|
+
test('returns true when rotating', () => {
|
|
1845
|
+
const camera = createCamera();
|
|
1846
|
+
camera.rotateTo(90, {duration: 1});
|
|
1847
|
+
expect(camera.isEasing()).toBeTruthy();
|
|
1848
|
+
});
|
|
1849
|
+
|
|
1850
|
+
test('returns false when done rotating', () => new Promise<void>(done => {
|
|
1851
|
+
const camera = createCamera();
|
|
1852
|
+
camera.on('moveend', () => {
|
|
1853
|
+
expect(!camera.isEasing()).toBeTruthy();
|
|
1854
|
+
done();
|
|
1855
|
+
});
|
|
1856
|
+
const stub = jest.spyOn(browser, 'now');
|
|
1857
|
+
stub.mockImplementation(() => 0);
|
|
1858
|
+
camera.rotateTo(90, {duration: 1});
|
|
1859
|
+
setTimeout(() => {
|
|
1860
|
+
stub.mockImplementation(() => 1);
|
|
1861
|
+
camera.simulateFrame();
|
|
1862
|
+
}, 0);
|
|
1863
|
+
}));
|
|
1864
|
+
});
|
|
1865
|
+
|
|
1866
|
+
describe('#stop', () => {
|
|
1867
|
+
test('resets camera._zooming', () => {
|
|
1868
|
+
const camera = createCamera();
|
|
1869
|
+
camera.zoomTo(3.2);
|
|
1870
|
+
camera.stop();
|
|
1871
|
+
expect(!camera._zooming).toBeTruthy();
|
|
1872
|
+
});
|
|
1873
|
+
|
|
1874
|
+
test('resets camera._rotating', () => {
|
|
1875
|
+
const camera = createCamera();
|
|
1876
|
+
camera.rotateTo(90);
|
|
1877
|
+
camera.stop();
|
|
1878
|
+
expect(!camera._rotating).toBeTruthy();
|
|
1879
|
+
});
|
|
1880
|
+
|
|
1881
|
+
test('emits moveend if panning, preserving eventData', () => new Promise<void>(done => {
|
|
1882
|
+
const camera = createCamera();
|
|
1883
|
+
const eventData = {data: 'ok'};
|
|
1884
|
+
|
|
1885
|
+
camera.on('moveend', (d) => {
|
|
1886
|
+
expect(d.data).toBe('ok');
|
|
1887
|
+
done();
|
|
1888
|
+
});
|
|
1889
|
+
|
|
1890
|
+
camera.panTo([100, 0], {}, eventData);
|
|
1891
|
+
camera.stop();
|
|
1892
|
+
}));
|
|
1893
|
+
|
|
1894
|
+
test('emits moveend if zooming, preserving eventData', () => new Promise<void>(done => {
|
|
1895
|
+
const camera = createCamera();
|
|
1896
|
+
const eventData = {data: 'ok'};
|
|
1897
|
+
|
|
1898
|
+
camera.on('moveend', (d) => {
|
|
1899
|
+
expect(d.data).toBe('ok');
|
|
1900
|
+
done();
|
|
1901
|
+
});
|
|
1902
|
+
|
|
1903
|
+
camera.zoomTo(3.2, {}, eventData);
|
|
1904
|
+
camera.stop();
|
|
1905
|
+
}));
|
|
1906
|
+
|
|
1907
|
+
test('emits moveend if rotating, preserving eventData', () => new Promise<void>(done => {
|
|
1908
|
+
const camera = createCamera();
|
|
1909
|
+
const eventData = {data: 'ok'};
|
|
1910
|
+
|
|
1911
|
+
camera.on('moveend', (d) => {
|
|
1912
|
+
expect(d.data).toBe('ok');
|
|
1913
|
+
done();
|
|
1914
|
+
});
|
|
1915
|
+
|
|
1916
|
+
camera.rotateTo(90, {}, eventData);
|
|
1917
|
+
camera.stop();
|
|
1918
|
+
}));
|
|
1919
|
+
|
|
1920
|
+
test('does not emit moveend if not moving', () => new Promise<void>(done => {
|
|
1921
|
+
const camera = createCamera();
|
|
1922
|
+
const eventData = {data: 'ok'};
|
|
1923
|
+
|
|
1924
|
+
camera.on('moveend', (d) => {
|
|
1925
|
+
expect(d.data).toBe('ok');
|
|
1926
|
+
camera.stop();
|
|
1927
|
+
done(); // Fails with ".end() called twice" if we get here a second time.
|
|
1928
|
+
});
|
|
1929
|
+
|
|
1930
|
+
const stub = jest.spyOn(browser, 'now');
|
|
1931
|
+
stub.mockImplementation(() => 0);
|
|
1932
|
+
camera.panTo([100, 0], {duration: 1}, eventData);
|
|
1933
|
+
|
|
1934
|
+
setTimeout(() => {
|
|
1935
|
+
stub.mockImplementation(() => 1);
|
|
1936
|
+
camera.simulateFrame();
|
|
1937
|
+
}, 0);
|
|
1938
|
+
}));
|
|
1939
|
+
});
|
|
1940
|
+
|
|
1941
|
+
describe('#cameraForBounds', () => {
|
|
1942
|
+
test('no options passed', () => {
|
|
1943
|
+
const camera = createCamera();
|
|
1944
|
+
const bb = [[-133, 16], [-68, 50]];
|
|
1945
|
+
const transform = camera.cameraForBounds(bb);
|
|
1946
|
+
|
|
1947
|
+
expect(fixedLngLat(transform.center, 4)).toEqual({lng: -100.5, lat: 34.7171});
|
|
1948
|
+
expect(fixedNum(transform.zoom, 3)).toBe(2.469);
|
|
1949
|
+
});
|
|
1950
|
+
|
|
1951
|
+
test('bearing positive number', () => {
|
|
1952
|
+
const camera = createCamera();
|
|
1953
|
+
const bb = [[-133, 16], [-68, 50]];
|
|
1954
|
+
const transform = camera.cameraForBounds(bb, {bearing: 175});
|
|
1955
|
+
|
|
1956
|
+
expect(fixedLngLat(transform.center, 4)).toEqual({lng: -100.5, lat: 34.7171});
|
|
1957
|
+
expect(fixedNum(transform.zoom, 3)).toBe(2.396);
|
|
1958
|
+
expect(transform.bearing).toBe(175);
|
|
1959
|
+
});
|
|
1960
|
+
|
|
1961
|
+
test('bearing negative number', () => {
|
|
1962
|
+
const camera = createCamera();
|
|
1963
|
+
const bb = [[-133, 16], [-68, 50]];
|
|
1964
|
+
const transform = camera.cameraForBounds(bb, {bearing: -30});
|
|
1965
|
+
|
|
1966
|
+
expect(fixedLngLat(transform.center, 4)).toEqual({lng: -100.5, lat: 34.7171});
|
|
1967
|
+
expect(fixedNum(transform.zoom, 3)).toBe(2.222);
|
|
1968
|
+
expect(transform.bearing).toBe(-30);
|
|
1969
|
+
});
|
|
1970
|
+
|
|
1971
|
+
test('padding number', () => {
|
|
1972
|
+
const camera = createCamera();
|
|
1973
|
+
const bb = [[-133, 16], [-68, 50]];
|
|
1974
|
+
const transform = camera.cameraForBounds(bb, {padding: 15});
|
|
1975
|
+
|
|
1976
|
+
expect(fixedLngLat(transform.center, 4)).toEqual({lng: -100.5, lat: 34.7171});
|
|
1977
|
+
expect(fixedNum(transform.zoom, 3)).toBe(2.382);
|
|
1978
|
+
});
|
|
1979
|
+
|
|
1980
|
+
test('padding object', () => {
|
|
1981
|
+
const camera = createCamera();
|
|
1982
|
+
const bb = [[-133, 16], [-68, 50]];
|
|
1983
|
+
const transform = camera.cameraForBounds(bb, {padding: {top: 15, right: 15, bottom: 15, left: 15}, duration: 0});
|
|
1984
|
+
|
|
1985
|
+
expect(fixedLngLat(transform.center, 4)).toEqual({lng: -100.5, lat: 34.7171});
|
|
1986
|
+
});
|
|
1987
|
+
|
|
1988
|
+
test('asymmetrical padding', () => {
|
|
1989
|
+
const camera = createCamera();
|
|
1990
|
+
const bb = [[-133, 16], [-68, 50]];
|
|
1991
|
+
const transform = camera.cameraForBounds(bb, {padding: {top: 10, right: 75, bottom: 50, left: 25}, duration: 0});
|
|
1992
|
+
|
|
1993
|
+
expect(fixedLngLat(transform.center, 4)).toEqual({lng: -96.5558, lat: 32.0833});
|
|
1994
|
+
});
|
|
1995
|
+
|
|
1996
|
+
test('bearing and asymmetrical padding', () => {
|
|
1997
|
+
const camera = createCamera();
|
|
1998
|
+
const bb = [[-133, 16], [-68, 50]];
|
|
1999
|
+
const transform = camera.cameraForBounds(bb, {bearing: 90, padding: {top: 10, right: 75, bottom: 50, left: 25}, duration: 0});
|
|
2000
|
+
|
|
2001
|
+
expect(fixedLngLat(transform.center, 4)).toEqual({lng: -103.3761, lat: 31.7099});
|
|
2002
|
+
});
|
|
2003
|
+
|
|
2004
|
+
test('offset', () => {
|
|
2005
|
+
const camera = createCamera();
|
|
2006
|
+
const bb = [[-133, 16], [-68, 50]];
|
|
2007
|
+
const transform = camera.cameraForBounds(bb, {offset: [0, 100]});
|
|
2008
|
+
|
|
2009
|
+
expect(fixedLngLat(transform.center, 4)).toEqual({lng: -100.5, lat: 44.4717});
|
|
2010
|
+
});
|
|
2011
|
+
|
|
2012
|
+
test('offset and padding', () => {
|
|
2013
|
+
const camera = createCamera();
|
|
2014
|
+
const bb = [[-133, 16], [-68, 50]];
|
|
2015
|
+
const transform = camera.cameraForBounds(bb, {padding: {top: 10, right: 75, bottom: 50, left: 25}, offset: [0, 100]});
|
|
2016
|
+
|
|
2017
|
+
expect(fixedLngLat(transform.center, 4)).toEqual({lng: -96.5558, lat: 44.4189});
|
|
2018
|
+
});
|
|
2019
|
+
|
|
2020
|
+
test('bearing, asymmetrical padding, and offset', () => {
|
|
2021
|
+
const camera = createCamera();
|
|
2022
|
+
const bb = [[-133, 16], [-68, 50]];
|
|
2023
|
+
const transform = camera.cameraForBounds(bb, {bearing: 90, padding: {top: 10, right: 75, bottom: 50, left: 25}, offset: [0, 100], duration: 0});
|
|
2024
|
+
|
|
2025
|
+
expect(fixedLngLat(transform.center, 4)).toEqual({lng: -103.3761, lat: 43.0929});
|
|
2026
|
+
});
|
|
2027
|
+
|
|
2028
|
+
test('asymmetrical transform using LngLatBounds instance', () => {
|
|
2029
|
+
const transform = new Transform(2, 10, 0, 60, false);
|
|
2030
|
+
transform.resize(2048, 512);
|
|
2031
|
+
|
|
2032
|
+
const camera = attachSimulateFrame(new CameraMock(transform, {} as any));
|
|
2033
|
+
camera._update = () => {};
|
|
2034
|
+
|
|
2035
|
+
const bb = new LngLatBounds();
|
|
2036
|
+
bb.extend([-66.9326, 49.5904]);
|
|
2037
|
+
bb.extend([-125.0011, 24.9493]);
|
|
2038
|
+
|
|
2039
|
+
const rotatedTransform = camera.cameraForBounds(bb, {bearing: 45});
|
|
2040
|
+
|
|
2041
|
+
expect(fixedLngLat(rotatedTransform.center, 4)).toEqual({lng: -95.9669, lat: 38.3048});
|
|
2042
|
+
expect(fixedNum(rotatedTransform.zoom, 3)).toBe(2.507);
|
|
2043
|
+
expect(rotatedTransform.bearing).toBe(45);
|
|
2044
|
+
});
|
|
2045
|
+
});
|
|
2046
|
+
|
|
2047
|
+
describe('#fitBounds', () => {
|
|
2048
|
+
test('no padding passed', () => {
|
|
2049
|
+
const camera = createCamera();
|
|
2050
|
+
const bb = [[-133, 16], [-68, 50]];
|
|
2051
|
+
camera.fitBounds(bb, {duration: 0});
|
|
2052
|
+
|
|
2053
|
+
expect(fixedLngLat(camera.getCenter(), 4)).toEqual({lng: -100.5, lat: 34.7171});
|
|
2054
|
+
expect(fixedNum(camera.getZoom(), 3)).toBe(2.469);
|
|
2055
|
+
});
|
|
2056
|
+
|
|
2057
|
+
test('padding number', () => {
|
|
2058
|
+
const camera = createCamera();
|
|
2059
|
+
const bb = [[-133, 16], [-68, 50]];
|
|
2060
|
+
camera.fitBounds(bb, {padding: 15, duration: 0});
|
|
2061
|
+
|
|
2062
|
+
expect(fixedLngLat(camera.getCenter(), 4)).toEqual({lng: -100.5, lat: 34.7171});
|
|
2063
|
+
expect(fixedNum(camera.getZoom(), 3)).toBe(2.382);
|
|
2064
|
+
});
|
|
2065
|
+
|
|
2066
|
+
test('padding object', () => {
|
|
2067
|
+
const camera = createCamera();
|
|
2068
|
+
const bb = [[-133, 16], [-68, 50]];
|
|
2069
|
+
camera.fitBounds(bb, {padding: {top: 10, right: 75, bottom: 50, left: 25}, duration: 0});
|
|
2070
|
+
|
|
2071
|
+
expect(fixedLngLat(camera.getCenter(), 4)).toEqual({lng: -96.5558, lat: 32.0833});
|
|
2072
|
+
});
|
|
2073
|
+
|
|
2074
|
+
test('padding does not get propagated to transform.padding', () => {
|
|
2075
|
+
const camera = createCamera();
|
|
2076
|
+
const bb = [[-133, 16], [-68, 50]];
|
|
2077
|
+
camera.fitBounds(bb, {padding: {top: 10, right: 75, bottom: 50, left: 25}, duration: 0});
|
|
2078
|
+
const padding = camera.transform.padding;
|
|
2079
|
+
|
|
2080
|
+
expect(padding).toEqual({
|
|
2081
|
+
left: 0,
|
|
2082
|
+
right: 0,
|
|
2083
|
+
top: 0,
|
|
2084
|
+
bottom: 0
|
|
2085
|
+
});
|
|
2086
|
+
});
|
|
2087
|
+
|
|
2088
|
+
test('fiji (crossing antimeridian)', () => {
|
|
2089
|
+
const camera = createCamera();
|
|
2090
|
+
const bb = [[175.813127, -20.157768], [-178.340903, -15.449124]];
|
|
2091
|
+
camera.fitBounds(bb, {duration: 0});
|
|
2092
|
+
|
|
2093
|
+
expect(fixedLngLat(camera.getCenter(), 4)).toEqual({lng: 178.7361, lat: -17.819});
|
|
2094
|
+
expect(fixedNum(camera.getZoom(), 3)).toBe(5.944);
|
|
2095
|
+
});
|
|
2096
|
+
|
|
2097
|
+
test('not crossing antimeridian', () => {
|
|
2098
|
+
const camera = createCamera();
|
|
2099
|
+
const bb = [[-10, -10], [10, 10]];
|
|
2100
|
+
camera.fitBounds(bb, {duration: 0});
|
|
2101
|
+
|
|
2102
|
+
expect(fixedLngLat(camera.getCenter(), 4)).toEqual({lng: 0, lat: 0});
|
|
2103
|
+
expect(fixedNum(camera.getZoom(), 3)).toBe(4.163);
|
|
2104
|
+
});
|
|
2105
|
+
|
|
2106
|
+
});
|
|
2107
|
+
|
|
2108
|
+
describe('#fitScreenCoordinates', () => {
|
|
2109
|
+
test('bearing 225', () => {
|
|
2110
|
+
const camera = createCamera();
|
|
2111
|
+
const p0 = [128, 128];
|
|
2112
|
+
const p1 = [256, 256];
|
|
2113
|
+
const bearing = 225;
|
|
2114
|
+
camera.fitScreenCoordinates(p0, p1, bearing, {duration: 0});
|
|
2115
|
+
|
|
2116
|
+
expect(fixedLngLat(camera.getCenter(), 4)).toEqual({lng: -45, lat: 40.9799});
|
|
2117
|
+
expect(fixedNum(camera.getZoom(), 3)).toBe(1.5);
|
|
2118
|
+
expect(camera.getBearing()).toBe(-135);
|
|
2119
|
+
});
|
|
2120
|
+
|
|
2121
|
+
test('bearing 0', () => {
|
|
2122
|
+
const camera = createCamera();
|
|
2123
|
+
const p0 = [128, 128];
|
|
2124
|
+
const p1 = [256, 256];
|
|
2125
|
+
const bearing = 0;
|
|
2126
|
+
camera.fitScreenCoordinates(p0, p1, bearing, {duration: 0});
|
|
2127
|
+
|
|
2128
|
+
expect(fixedLngLat(camera.getCenter(), 4)).toEqual({lng: -45, lat: 40.9799});
|
|
2129
|
+
expect(fixedNum(camera.getZoom(), 3)).toBe(2);
|
|
2130
|
+
expect(camera.getBearing()).toBeCloseTo(0);
|
|
2131
|
+
});
|
|
2132
|
+
|
|
2133
|
+
test('inverted points', () => {
|
|
2134
|
+
const camera = createCamera();
|
|
2135
|
+
const p1 = [128, 128];
|
|
2136
|
+
const p0 = [256, 256];
|
|
2137
|
+
const bearing = 0;
|
|
2138
|
+
camera.fitScreenCoordinates(p0, p1, bearing, {duration: 0});
|
|
2139
|
+
|
|
2140
|
+
expect(fixedLngLat(camera.getCenter(), 4)).toEqual({lng: -45, lat: 40.9799});
|
|
2141
|
+
expect(fixedNum(camera.getZoom(), 3)).toBe(2);
|
|
2142
|
+
expect(camera.getBearing()).toBeCloseTo(0);
|
|
2143
|
+
});
|
|
2144
|
+
});
|
|
2145
|
+
|
|
2146
|
+
describe('queryTerrainElevation', () => {
|
|
2147
|
+
let camera: Camera;
|
|
2148
|
+
|
|
2149
|
+
beforeEach(() => {
|
|
2150
|
+
camera = createCamera();
|
|
2151
|
+
});
|
|
2152
|
+
|
|
2153
|
+
test('should return null if terrain is not set', () => {
|
|
2154
|
+
camera.terrain = null;
|
|
2155
|
+
const result = camera.queryTerrainElevation([0, 0]);
|
|
2156
|
+
expect(result).toBeNull();
|
|
2157
|
+
});
|
|
2158
|
+
|
|
2159
|
+
test('should return the correct elevation', () => {
|
|
2160
|
+
// Set up mock transform and terrain objects
|
|
2161
|
+
const transform = new Transform(0, 22, 0, 60, true);
|
|
2162
|
+
transform.elevation = 50;
|
|
2163
|
+
const terrain = {
|
|
2164
|
+
getElevationForLngLatZoom: jest.fn().mockReturnValue(200)
|
|
2165
|
+
} as any as Terrain;
|
|
2166
|
+
|
|
2167
|
+
// Set up camera with mock transform and terrain
|
|
2168
|
+
camera.transform = transform;
|
|
2169
|
+
camera.terrain = terrain;
|
|
2170
|
+
|
|
2171
|
+
// Call queryTerrainElevation with mock lngLat
|
|
2172
|
+
const lngLatLike: LngLatLike = [1, 2];
|
|
2173
|
+
const expectedElevation = 150; // 200 - 50 = 150
|
|
2174
|
+
const result = camera.queryTerrainElevation(lngLatLike);
|
|
2175
|
+
|
|
2176
|
+
// Check that transform.getElevation was called with the correct arguments
|
|
2177
|
+
expect(terrain.getElevationForLngLatZoom).toHaveBeenCalledWith(
|
|
2178
|
+
expect.objectContaining({
|
|
2179
|
+
lng: lngLatLike[0],
|
|
2180
|
+
lat: lngLatLike[1],
|
|
2181
|
+
}),
|
|
2182
|
+
transform.tileZoom
|
|
2183
|
+
);
|
|
2184
|
+
|
|
2185
|
+
// Check that the correct elevation value was returned
|
|
2186
|
+
expect(result).toEqual(expectedElevation);
|
|
2187
|
+
});
|
|
2188
|
+
});
|
|
2189
|
+
|
|
2190
|
+
describe('#transformCameraUpdate', () => {
|
|
2191
|
+
|
|
2192
|
+
test('invoke transformCameraUpdate callback during jumpTo', () => new Promise<void>(done => {
|
|
2193
|
+
const camera = createCamera();
|
|
2194
|
+
|
|
2195
|
+
let callbackCount = 0;
|
|
2196
|
+
let eventCount = 0;
|
|
2197
|
+
|
|
2198
|
+
camera.transformCameraUpdate = () => {
|
|
2199
|
+
callbackCount++;
|
|
2200
|
+
return {};
|
|
2201
|
+
};
|
|
2202
|
+
|
|
2203
|
+
camera
|
|
2204
|
+
.on('move', () => {
|
|
2205
|
+
eventCount++;
|
|
2206
|
+
expect(eventCount).toBe(callbackCount);
|
|
2207
|
+
})
|
|
2208
|
+
.on('moveend', () => {
|
|
2209
|
+
done();
|
|
2210
|
+
});
|
|
2211
|
+
|
|
2212
|
+
camera.jumpTo({center: [100, 0]});
|
|
2213
|
+
}));
|
|
2214
|
+
|
|
2215
|
+
test('invoke transformCameraUpdate callback during easeTo', () => new Promise<void>(done => {
|
|
2216
|
+
expect.assertions(2);
|
|
2217
|
+
const camera = createCamera();
|
|
2218
|
+
const stub = jest.spyOn(browser, 'now');
|
|
2219
|
+
stub.mockImplementation(() => 0);
|
|
2220
|
+
|
|
2221
|
+
let callbackCount = 0;
|
|
2222
|
+
let eventCount = 0;
|
|
2223
|
+
|
|
2224
|
+
camera.transformCameraUpdate = () => {
|
|
2225
|
+
callbackCount++;
|
|
2226
|
+
return {};
|
|
2227
|
+
};
|
|
2228
|
+
|
|
2229
|
+
camera
|
|
2230
|
+
.on('move', () => {
|
|
2231
|
+
eventCount++;
|
|
2232
|
+
expect(eventCount).toBe(callbackCount);
|
|
2233
|
+
})
|
|
2234
|
+
.on('moveend', () => {
|
|
2235
|
+
done();
|
|
2236
|
+
});
|
|
2237
|
+
|
|
2238
|
+
camera.easeTo({center: [100, 0], duration: 10});
|
|
2239
|
+
|
|
2240
|
+
setTimeout(() => {
|
|
2241
|
+
stub.mockImplementation(() => 1);
|
|
2242
|
+
camera.simulateFrame();
|
|
2243
|
+
|
|
2244
|
+
setTimeout(() => {
|
|
2245
|
+
stub.mockImplementation(() => 10);
|
|
2246
|
+
camera.simulateFrame();
|
|
2247
|
+
}, 0);
|
|
2248
|
+
}, 0);
|
|
2249
|
+
}));
|
|
2250
|
+
|
|
2251
|
+
test('invoke transformCameraUpdate callback during flyTo', () => new Promise<void>(done => {
|
|
2252
|
+
expect.assertions(2);
|
|
2253
|
+
const camera = createCamera();
|
|
2254
|
+
const stub = jest.spyOn(browser, 'now');
|
|
2255
|
+
stub.mockImplementation(() => 0);
|
|
2256
|
+
|
|
2257
|
+
let callbackCount = 0;
|
|
2258
|
+
let eventCount = 0;
|
|
2259
|
+
|
|
2260
|
+
camera.transformCameraUpdate = () => {
|
|
2261
|
+
callbackCount++;
|
|
2262
|
+
return {};
|
|
2263
|
+
};
|
|
2264
|
+
|
|
2265
|
+
camera
|
|
2266
|
+
.on('move', () => {
|
|
2267
|
+
eventCount++;
|
|
2268
|
+
expect(eventCount).toBe(callbackCount);
|
|
2269
|
+
})
|
|
2270
|
+
.on('moveend', () => {
|
|
2271
|
+
done();
|
|
2272
|
+
});
|
|
2273
|
+
|
|
2274
|
+
camera.flyTo({center: [100, 0], duration: 10});
|
|
2275
|
+
|
|
2276
|
+
setTimeout(() => {
|
|
2277
|
+
stub.mockImplementation(() => 1);
|
|
2278
|
+
camera.simulateFrame();
|
|
2279
|
+
|
|
2280
|
+
setTimeout(() => {
|
|
2281
|
+
stub.mockImplementation(() => 10);
|
|
2282
|
+
camera.simulateFrame();
|
|
2283
|
+
}, 0);
|
|
2284
|
+
}, 0);
|
|
2285
|
+
}));
|
|
2286
|
+
|
|
2287
|
+
test('transformCameraUpdate overrides proposed camera settings', () => {
|
|
2288
|
+
const camera = createCamera();
|
|
2289
|
+
|
|
2290
|
+
camera.transformCameraUpdate = ({center, zoom}) => {
|
|
2291
|
+
return {
|
|
2292
|
+
center: LngLat.convert([center.lng, center.lat + 10]),
|
|
2293
|
+
zoom: Math.round(zoom)
|
|
2294
|
+
};
|
|
2295
|
+
};
|
|
2296
|
+
|
|
2297
|
+
camera.flyTo({center: [100, 0], zoom: 3.2, animate: false});
|
|
2298
|
+
expect(fixedLngLat(camera.getCenter())).toEqual({lng: 100, lat: 10});
|
|
2299
|
+
expect(fixedNum(camera.getZoom())).toBe(3);
|
|
2300
|
+
});
|
|
2301
|
+
});
|