Table of Contents for
OpenLayers 3.x Cookbook - Second Edition

Version ebook / Retour

Cover image for bash Cookbook, 2nd Edition OpenLayers 3.x Cookbook - Second Edition by Antonio Santiago Perez Published by Packt Publishing, 2016
  1. Cover
  2. Table of Contents
  3. OpenLayers 3.x Cookbook Second Edition
  4. OpenLayers 3.x Cookbook Second Edition
  5. Credits
  6. About the Authors
  7. About the Reviewer
  8. www.PacktPub.com
  9. Preface
  10. What you need for this book
  11. Who this book is for
  12. Sections
  13. Conventions
  14. Reader feedback
  15. Customer support
  16. 1. Web Mapping Basics
  17. Creating a simple fullscreen map
  18. Playing with the map's options
  19. Managing the map's stack layers
  20. Managing the map's controls
  21. Moving around the map view
  22. Restricting the map's extent
  23. 2. Adding Raster Layers
  24. Using Bing imagery
  25. Using OpenStreetMap imagery
  26. Adding WMS layers
  27. Changing the zoom effect
  28. Changing layer opacity
  29. Buffering the layer data to improve map navigation
  30. Creating an image layer
  31. Setting the tile size in WMS layers
  32. 3. Working with Vector Layers
  33. Adding a GML layer
  34. Adding a KML layer
  35. Creating features programmatically
  36. Exporting features as GeoJSON
  37. Reading and creating features from a WKT
  38. Using point features as markers
  39. Removing or cloning features using overlays
  40. Zooming to the extent of a layer
  41. Adding text labels to geometry points
  42. Adding features from a WFS server
  43. Using the cluster strategy
  44. Reading features directly using AJAX
  45. Creating a heat map
  46. 4. Working with Events
  47. Creating a side-by-side map comparator
  48. Implementing a work-in-progress indicator for map layers
  49. Listening for the vector layer features' events
  50. Listening for mouse or touch events
  51. Using the keyboard to pan or zoom
  52. 5. Adding Controls
  53. Adding and removing controls
  54. Working with geolocation
  55. Placing controls outside the map
  56. Drawing features across multiple vector layers
  57. Modifying features
  58. Measuring distances and areas
  59. Getting feature information from a data source
  60. Getting information from a WMS server
  61. 6. Styling Features
  62. Styling layers
  63. Styling features based on geometry type
  64. Styling based on feature attributes
  65. Styling interaction render intents
  66. Styling clustered features
  67. 7. Beyond the Basics
  68. Working with projections
  69. Creating a custom control
  70. Selecting features by dragging out a selection area
  71. Transitioning between weather forecast imagery
  72. Using the custom OpenLayers library build
  73. Drawing in freehand mode
  74. Modifying layer appearance
  75. Adding features to the vector layer by dragging and dropping them
  76. Making use of map permalinks
  77. Index

Changing the zoom effect

The panning and zoom effects are very important actions that are related to the user navigation experience. In Chapter 1, Web Mapping Basics, the Moving around the map view recipe shows you how you can control and animate the way the map can be panned, zoomed, and rotated.

In this recipe, we'll explore animations even further by demonstrating different ways that you can customize transition effects between two zoom levels on the layer.

By default, OpenLayers animates the zoom transitions. In order to customize this ourselves, OpenLayers comes with a series of different animation methods that are available from ol.animation object. For this recipe, we'll use the ol.animation.bounce and ol.animation.zoom methods to customize the zoom effects.

We will have a panel on the right so that you can choose the animation-easing algorithm, the duration and whether or not to use the bounce effect.

Here's a screenshot of what we'll end up with (the source code can be found in ch02/ch02-zoom-effect):

Changing the zoom effect

How to do it…

In this section we'll see how to change the zoom effects. Follow the steps outlined:

  1. Create an HTML file and include the required OpenLayers dependencies. In particular, create the form elements to dynamically update the effects:
    <p>Choose an animation effect:</p>
    <select id="js-zoom-effect">
      <option value="easeIn">easeIn</option>
      <option value="easeOut">easeOut</option>
      <option value="inAndOut" selected>inAndOut</option>
      <option value="linear">linear</option>
    </select>
    
    <p>Choose a speed:</p>
    <select id="js-zoom-speed">
      <option value="100">100ms</option>
      <option value="250">250ms</option>
      <option value="500">500ms</option>
      <option value="1000" selected>1000ms</option>
    </select>
    
    <p>Bounce?</p>
    <select id="js-bounce">
      <option value="true">Yes</option>
      <option value="false">No</option>
    </select>
  2. Create your custom JavaScript file and build the map instance with the Humanitarian OpenStreetMap layer:
    var map = new ol.Map({
      view: new ol.View({
        zoom: 5,
        center: [9686000, 1707000]
      }),
      target: 'js-map',
      layers: [
        new ol.layer.Tile({
          source: new ol.source.OSM({
            attributions: [
              new ol.Attribution({
                html: 'Tiles courtesy of ' +
                '<a href="http://hot.openstreetmap.org">' +
                'Humanitarian OpenStreetMap Team</a>'
              }),
              ol.source.OSM.ATTRIBUTION
            ],
            url: 'http://{a-c}.tile.openstreetmap.fr/' + 
                 'hot/{z}/{x}/{y}.png'
          })
        })
      ]
    });
  3. Cache the form DOM elements into variables, as follows:
    var easingSelect = document.getElementById('js-zoom-effect');
    var durationSelect = document.getElementById('js-zoom-speed');
    var bounceSelect = document.getElementById('js-bounce');
  4. Add an event listener to the map view for zoom changes and create the animation effects based off the current form input values:
    map.getView().on('change:resolution', function(event) {
      if (bounceSelect.value === 'true') {
        map.beforeRender(ol.animation.bounce({
          resolution: map.getView().getResolution() * 1.5,
          duration: parseInt(durationSelect.value, 10)
        }));
      } else {
        map.beforeRender(ol.animation.zoom({
          resolution: event.oldValue,
          duration: parseInt(durationSelect.value, 10),
          easing: ol.easing[easingSelect.value]
        }));
      }
    });

How it works…

The HTML form elements provide a live reflection of the animation configuration. Each form element has an ID attribute that we use to select and cache the DOM elements within JavaScript, as we'll potentially access the values of these elements many times.

Our JavaScript sets up the map and associative properties, including the OpenStreetMap Humanitarian layer. This should all look familiar to you, so without further ado, we'll examine the logic behind the zoom transitions:

map.getView().on('change:resolution', function(event) {

We subscribe to any resolution (zoom) changes on the map view and register an anonymous function as the event handler.

if (bounceSelect.value === 'true') {
    map.beforeRender(ol.animation.bounce({
      resolution: map.getView().getResolution() * 1.5,
      duration: parseInt(durationSelect.value, 10)
    }));
  }

We run a conditional check to see whether or not the value for the bounce select menu is 'true' or 'false'. If it's true, then we register a customized ol.animation.bounce method to be added onto the beforeRender queue. We pass in a desired resolution of 1.5 times the original resolution, to give it a suitable bounce effect. The duration amount is derived from the durationSelect menu value. We run the duration value through the JavaScript parseInt method to ensure it's in the right type for OpenLayers. The duration is in milliseconds.

Note

To describe the bounce effect by analogy, is to imagine a tennis ball hitting the ground from some height. As it impacts the surface, it jumps back up until it finally loses momentum and comes to rest on the surface. For example, when you zoom into the map, it's as though you become the descending ball, so you bounce your way to the final resolution. When you alter the easing value (the algorithm used), such as easeOut, it changes the spacing between the animation frames resulting in a different motion of events.

As we can see, the map instance has a beforeRender method that expects a function of type ol.PreRenderFunction. The ol.animation methods return a function of this expected type. This function type performs incremental manipulation of the view before rendering the final state of the view, which is perfect for animations.

The ol.PreRenderFunction method accepts two parameters: the map instance, and the frame state. The latter is a shared object in OpenLayers that represents the current render frame state. It provides information such as the current state of the view (center position, resolution, and so on) and current timestamp. These are metrics that animation algorithms (made up mostly of mathematical calculations to apply easing techniques) utilize to perform their visual effects. Within the function, you return true to run this function for the next frame; otherwise, you return false to dispose of it (in other words, your animation is complete).

The ol.animation.bounce variation of this function type performs incremental manipulations that produce a zooming request that 'bounces' into position.

} else {
  map.beforeRender(ol.animation.zoom({
    resolution: event.oldValue,
    duration: parseInt(durationSelect.value, 10),
    easing: ol.easing[easingSelect.value]
  }));
}

If the bounce effect has been disabled, then we add a standard zoom animation with the ol.animation.zoom method to the beforeRender map method.

For the starting point of the animation, the resolution is set to the old resolution value, which is available from the event object (event.oldValue). The duration is once again plucked straight from the duration select menu and passed into the JavaScript parseInt method for type conversion.

We can customize the easing algorithm that is used for the zoom animation effect. The easing property expects an appropriate easing function. OpenLayers comes with a selection of effects to choose from, the majority of which we made available from the easing select menu.

For example, one of the OpenLayers easing methods is ol.easing.easeIn. To dynamically use one of these easing functions from a value in the select menu, we perform an object lookup via array notation. So, to continue with this example, if you select the easeIn option from the select menu, ol.easing[easingSelect.value] becomes ol.easing['easeIn'].

There's more…

Although OpenLayers offers some easing methods out of the box, you can just as well extend the list and provide any easing algorithms yourself. You may have used some easing algorithms from other libraries that you'd like to port into OpenLayers.

The ol.animation methods all have a start property. This means that you can delay the start of the animation. The default start time is immediately.

See also

  • The Adding WMS layer recipe
  • The Changing layer opacity recipe
  • The Moving around the map view recipe