# v3.20.0

## Summary

The v3.20.0 release includes enhancements and fixes from 89 pull requests since the previous release.

Among the changes, take a look at the new `view.animate()` function.  This replaces the previous `map.beforeRender()` and `ol.animation` functions with more intuitive view animations that allow for chaining together multiple transitions and support a callback on animation end.  In addition, two or more maps that share a view will be animated together.  See the upgrade notes and the animation example for more detail.

On the subject of view transitions, scrolling with a trackpad or magic mouse now transitions the view resolution smoothly.  Instead of jumping to the next integer zoom level, trackpad or magic mouse scrolling can leave the view at a fractional zoom level.  In line with this trackpad behavior, pinch zooming on touch devices also now leaves the view at a fractional zoom level (see the upgrade notes for an option to restore the old behavior).

On the rendering front, the Canvas renderer got another overhaul.  This release brings back the strategy of rendering to a dedicated Canvas element per layer.  If you were experiencing issues with gaps between tiles on rotated views or when zooming, this change should bring rendering improvements.

Also on the rendering front, @GaborFarkas completed a nearly 5 month effort to bring line and polygon support to the WebGL renderer.  If you're interested in experimenting with WebGL for vector rendering, use `renderer: 'webgl'` in your map constructor.

See the full list of changes below.  There are some other gems down there.

## Upgrade notes

#### Use `view.animate()` instead of `map.beforeRender()` and `ol.animation` functions

The `map.beforeRender()` and `ol.animation` functions have been deprecated in favor of a new `view.animate()` function.  Use of the deprecated functions will result in a warning during development.  These functions are subject to removal in an upcoming release.

For details on the `view.animate()` method, see the API docs and the view animation example.  Upgrading should be relatively straightforward.  For example, if you wanted to have an animated pan, zoom, and rotation previously, you might have done this:

```js
var zoom = ol.animation.zoom({
  resolution: view.getResolution()
});
var pan = ol.animation.pan({
  source: view.getCenter()
});
var rotate = ol.animation.rotate({
  rotation: view.getRotation()
});

map.beforeRender(zoom, pan, rotate);

map.setZoom(1);
map.setCenter([0, 0]);
map.setRotation(Math.PI);
```

Now, the same can be accomplished with this:
```js
view.animate({
  zoom: 1,
  center: [0, 0],
  rotation: Math.PI
});
```

#### `ol.Map#forEachFeatureAtPixel` and `ol.Map#hasFeatureAtPixel` parameters have changed

If you are using the layer filter of one of these methods, please note that you now have to pass in the layer filter via an `ol.AtPixelOptions` object. If you are not using the layer filter the usage has not changed.

Old syntax:
```js
map.forEachFeatureAtPixel(pixel, callback, callbackThis, layerFilterFn, layerFilterThis);

map.hasFeatureAtPixel(pixel, layerFilterFn, layerFilterThis);
```

New syntax:
```js
map.forEachFeatureAtPixel(pixel, callback.bind(callbackThis), {
  layerFilter: layerFilterFn.bind(layerFilterThis)
});

map.hasFeatureAtPixel(pixel, {
  layerFilter: layerFilterFn.bind(layerFilterThis)
});
```

This change is due to the introduction of the `hitTolerance` parameter which can be passed in via this `ol.AtPixelOptions` object, too.

#### Use `ol.proj.getPointResolution()` instead of `projection.getPointResolution()`

The experimental `getPointResolution` method has been removed from `ol.Projection` instances.  Since the implementation of this method required an inverse transform (function for transforming projected coordinates to geographic coordinates) and `ol.Projection` instances are not constructed with forward or inverse transforms, it does not make sense that a projection instance can always calculate the point resolution.

As a substitute for the `projection.getPointResolution()` function, a `ol.proj.getPointResolution()` function has been added.  To upgrade, you will need to change things like this:
```js
projection.getPointResolution(resolution, point);
```

into this:
```js
ol.proj.getPointResolution(projection, resolution, point);
```

Note that if you were previously creating a projection with a `getPointResolution` function in the constructor (or calling `projection.setGetPointResolution()` after construction), this function will be used by `ol.proj.getPointResolution()`.

#### `ol.interaction.PinchZoom` no longer zooms to a whole-number zoom level after the gesture ends

The old behavior of `ol.interaction.PinchZoom` was to zoom to the next integer zoom level after the user ends the gesture.

Now the pinch zoom keeps the user selected zoom level even if it is a fractional zoom.

To get the old behavior set the new `constrainResolution` parameter to `true` like this:
```js
new ol.interaction.PinchZoom({constrainResolution: true})
```

See the new `pinch-zoom` example for a complete implementation.

## Detailed changes

 * [#6230](https://github.com/openlayers/openlayers/pull/6230) - Ignore duplicated attributions ([@tschaub](https://github.com/tschaub))
 * [#6192](https://github.com/openlayers/openlayers/pull/6192) - Modify interaction: always stop event propagation when removing vertex ([@tchandelle](https://github.com/tchandelle))
 * [#6228](https://github.com/openlayers/openlayers/pull/6228) - Rename the pinch zoom example ([@tschaub](https://github.com/tschaub))
 * [#6229](https://github.com/openlayers/openlayers/pull/6229) - Update phantomjs-prebuilt to version 2.1.14 🚀 ([@openlayers](https://github.com/openlayers))
 * [#6196](https://github.com/openlayers/openlayers/pull/6196) - KML ExtendedData Export ([@raiyni](https://github.com/raiyni))
 * [#6227](https://github.com/openlayers/openlayers/pull/6227) - Update eslint to version 3.12.0 🚀 ([@openlayers](https://github.com/openlayers))
 * [#6224](https://github.com/openlayers/openlayers/pull/6224) - Pinch zoom: allow fractional zoom ([@aAXEe](https://github.com/aAXEe))
 * [#6226](https://github.com/openlayers/openlayers/pull/6226) - Improve the headers styles in the api doc ([@tchandelle](https://github.com/tchandelle))
 * [#5995](https://github.com/openlayers/openlayers/pull/5995) - Add hit tolerance parameter to ol.Map#forEachFeatureAtPixel ([@KlausBenndorf](https://github.com/KlausBenndorf))
 * [#6220](https://github.com/openlayers/openlayers/pull/6220) - Fix ol.Collection#push return value ([@fredj](https://github.com/fredj))
 * [#6213](https://github.com/openlayers/openlayers/pull/6213) - Add preload option to olx.layer.VectorTileOptions ([@drnextgis](https://github.com/drnextgis))
 * [#6222](https://github.com/openlayers/openlayers/pull/6222) - Fix forEachLayerAtPixel and improve class hierarchy ([@ahocevar](https://github.com/ahocevar))
 * [#6075](https://github.com/openlayers/openlayers/pull/6075) - Keep the other dim from the original segment when modifying vertex ([@tchandelle](https://github.com/tchandelle))
 * [#6218](https://github.com/openlayers/openlayers/pull/6218) - Make modify interaction more robust ([@gberaudo](https://github.com/gberaudo))
 * [#6205](https://github.com/openlayers/openlayers/pull/6205) - Rework remaining modules with multiple provides ([@tschaub](https://github.com/tschaub))
 * [#6207](https://github.com/openlayers/openlayers/pull/6207) - Require all when generating exports ([@tschaub](https://github.com/tschaub))
 * [#6204](https://github.com/openlayers/openlayers/pull/6204) - Refactored proj modules ([@tschaub](https://github.com/tschaub))
 * [#6209](https://github.com/openlayers/openlayers/pull/6209) - Test array with to.eql(), not to.be.eql() ([@ahocevar](https://github.com/ahocevar))
 * [#6091](https://github.com/openlayers/openlayers/pull/6091) - Apply pixelRatio to line dash ([@tchandelle](https://github.com/tchandelle))
 * [#6082](https://github.com/openlayers/openlayers/pull/6082) - Unified canvas rendering ([@ahocevar](https://github.com/ahocevar))
 * [#6173](https://github.com/openlayers/openlayers/pull/6173) - Topolis example ([@bjornharrtell](https://github.com/bjornharrtell))
 * [#6206](https://github.com/openlayers/openlayers/pull/6206) - Stop asserting that zero duration animations take time ([@tschaub](https://github.com/tschaub))
 * [#6203](https://github.com/openlayers/openlayers/pull/6203) - Address a few missing requires ([@tschaub](https://github.com/tschaub))
 * [#6201](https://github.com/openlayers/openlayers/pull/6201) - Remove assertion in TileArcGISRest source ([@tschaub](https://github.com/tschaub))
 * [#6202](https://github.com/openlayers/openlayers/pull/6202) - Allow animation duration to be zero ([@tschaub](https://github.com/tschaub))
 * [#6198](https://github.com/openlayers/openlayers/pull/6198) - Fix sourceResolution value in view.animate ([@oterral](https://github.com/oterral))
 * [#6177](https://github.com/openlayers/openlayers/pull/6177) - Add duration and easing options to view.fit() for animations ([@tchandelle](https://github.com/tchandelle))
 * [#6078](https://github.com/openlayers/openlayers/pull/6078) - Use winding number algorithm for linearRingContainsXY ([@bjornharrtell](https://github.com/bjornharrtell))
 * [#6187](https://github.com/openlayers/openlayers/pull/6187) - Update pbf to version 3.0.5 🚀 ([@openlayers](https://github.com/openlayers))
 * [#6175](https://github.com/openlayers/openlayers/pull/6175) - Generate projection transform function only when requested ([@tchandelle](https://github.com/tchandelle))
 * [#6181](https://github.com/openlayers/openlayers/pull/6181) - Replace expired Bing key with a new one ([@ahocevar](https://github.com/ahocevar))
 * [#6164](https://github.com/openlayers/openlayers/pull/6164) - Simplify color parsing and allow more decimals ([@marcjansen](https://github.com/marcjansen))
 * [#6178](https://github.com/openlayers/openlayers/pull/6178) - Add missing goog.require ([@fredj](https://github.com/fredj))
 * [#6176](https://github.com/openlayers/openlayers/pull/6176) - Doc: easing option is optional ([@tchandelle](https://github.com/tchandelle))
 * [#6180](https://github.com/openlayers/openlayers/pull/6180) - Update eslint to version 3.11.1 🚀 ([@openlayers](https://github.com/openlayers))
 * [#6179](https://github.com/openlayers/openlayers/pull/6179) - Remove unused ol.Map.removePreRenderFunction function ([@fredj](https://github.com/fredj))
 * [#6052](https://github.com/openlayers/openlayers/pull/6052) - Remove the use of ol.format.KML.DEFAULT_IMAGE_SCALE_MULTIPLIER_ when … ([@oterral](https://github.com/oterral))
 * [#6159](https://github.com/openlayers/openlayers/pull/6159) - Remove carriage return after goog.require in examples ([@tchandelle](https://github.com/tchandelle))
 * [#6169](https://github.com/openlayers/openlayers/pull/6169) - Image rotation in WebGL was anti-clockwise ([@tchandelle](https://github.com/tchandelle))
 * [#5590](https://github.com/openlayers/openlayers/pull/5590) - Kml format: improved support for region and extendeddata ([@thhomas](https://github.com/thhomas))
 * [#5462](https://github.com/openlayers/openlayers/pull/5462) - WebGL vector support ([@GaborFarkas](https://github.com/GaborFarkas))
 * [#6168](https://github.com/openlayers/openlayers/pull/6168) - Update mocha to version 3.2.0 🚀 ([@openlayers](https://github.com/openlayers))
 * [#5589](https://github.com/openlayers/openlayers/pull/5589) - Wmts tilematrixlimits ([@thhomas](https://github.com/thhomas))
 * [#6155](https://github.com/openlayers/openlayers/pull/6155) - Set GeometryLayout correctly when reading GPX ([@romanzoller](https://github.com/romanzoller))
 * [#6161](https://github.com/openlayers/openlayers/pull/6161) - Update async to version 2.1.4 🚀 ([@openlayers](https://github.com/openlayers))
 * [#6153](https://github.com/openlayers/openlayers/pull/6153) - Remove legacy licenses folder ([@romanzoller](https://github.com/romanzoller))
 * [#6154](https://github.com/openlayers/openlayers/pull/6154) - Update mocha-phantomjs-core to version 2.1.0 🚀 ([@openlayers](https://github.com/openlayers))
 * [#6146](https://github.com/openlayers/openlayers/pull/6146) - Merge ol.style.Circle and RegularShape together ([@tchandelle](https://github.com/tchandelle))
 * [#6139](https://github.com/openlayers/openlayers/pull/6139) - Match equivalent projections from WMTS caps ([@bartvde](https://github.com/bartvde))
 * [#6138](https://github.com/openlayers/openlayers/pull/6138) - Update clean-css to version 3.4.21 🚀 ([@openlayers](https://github.com/openlayers))
 * [#6132](https://github.com/openlayers/openlayers/pull/6132) - Add getter for color property to ol.style.Icon ([@tohu12](https://github.com/tohu12))
 * [#6127](https://github.com/openlayers/openlayers/pull/6127) - Format WKT Z, M and ZM ([@omarkljung](https://github.com/omarkljung))
 * [#6136](https://github.com/openlayers/openlayers/pull/6136) - Update eslint to version 3.10.2 🚀 ([@openlayers](https://github.com/openlayers))
 * [#6133](https://github.com/openlayers/openlayers/pull/6133) - Doc clarification ol.MapBrowserEvent#pixel, ol.MapBrowserEvent#coordinate, ol.Map#getEventCoordinate ([@KlausBenndorf](https://github.com/KlausBenndorf))
 * [#6134](https://github.com/openlayers/openlayers/pull/6134) - Add setter methods for fill, image, stroke and text styles ([@dnlkoch](https://github.com/dnlkoch))
 * [#6129](https://github.com/openlayers/openlayers/pull/6129) - Update pbf to version 3.0.4 🚀 ([@openlayers](https://github.com/openlayers))
 * [#6121](https://github.com/openlayers/openlayers/pull/6121) - Hint change means view change ([@tschaub](https://github.com/tschaub))
 * [#6120](https://github.com/openlayers/openlayers/pull/6120) - Set interacting hint during trackpad scroll ([@tschaub](https://github.com/tschaub))
 * [#6128](https://github.com/openlayers/openlayers/pull/6128) - Update pbf to version 3.0.3 🚀 ([@openlayers](https://github.com/openlayers))
 * [#6124](https://github.com/openlayers/openlayers/pull/6124) - Allow up to 16 decimals for alpha channel when parsing rgba strings to colors ([@marcjansen](https://github.com/marcjansen))
 * [#6117](https://github.com/openlayers/openlayers/pull/6117) - Update handlebars to version 4.0.6 🚀 ([@openlayers](https://github.com/openlayers))
 * [#6113](https://github.com/openlayers/openlayers/pull/6113) - Smooth trackpad zooming ([@tschaub](https://github.com/tschaub))
 * [#6105](https://github.com/openlayers/openlayers/pull/6105) - Move vector tile loader functions into vector tile module ([@tschaub](https://github.com/tschaub))
 * [#6114](https://github.com/openlayers/openlayers/pull/6114) - Updated linter config and curly conditional blocks ([@tschaub](https://github.com/tschaub))
 * [#6106](https://github.com/openlayers/openlayers/pull/6106) - Add type annotations for vector tiles ([@tschaub](https://github.com/tschaub))
 * [#6107](https://github.com/openlayers/openlayers/pull/6107) - Reset hint first and notify of change when cancelling animations ([@tschaub](https://github.com/tschaub))
 * [#6112](https://github.com/openlayers/openlayers/pull/6112) - Update eslint to version 3.10.0 🚀 ([@openlayers](https://github.com/openlayers))
 * [#6110](https://github.com/openlayers/openlayers/pull/6110) - Update coveralls to version 2.11.15 🚀 ([@openlayers](https://github.com/openlayers))
 * [#6077](https://github.com/openlayers/openlayers/pull/6077) - Optionally enable hidpi support for Bing ([@bartvde](https://github.com/bartvde))
 * [#6103](https://github.com/openlayers/openlayers/pull/6103) - Properly complete multiple parallel animations ([@tschaub](https://github.com/tschaub))
 * [#6101](https://github.com/openlayers/openlayers/pull/6101) - Avoid starting new zoom animation while already animating ([@tschaub](https://github.com/tschaub))
 * [#6099](https://github.com/openlayers/openlayers/pull/6099) - Modify interaction tests : check for change events ([@tchandelle](https://github.com/tchandelle))
 * [#6069](https://github.com/openlayers/openlayers/pull/6069) - If there is no features option, all features will be translated. ([@tchandelle](https://github.com/tchandelle))
 * [#6097](https://github.com/openlayers/openlayers/pull/6097) - API index page : Fix link anchor to static members ([@tchandelle](https://github.com/tchandelle))
 * [#6095](https://github.com/openlayers/openlayers/pull/6095) - LineString Arrows example: rotate with the view ([@tchandelle](https://github.com/tchandelle))
 * [#6093](https://github.com/openlayers/openlayers/pull/6093) - Update mustache to version 2.3.0 🚀 ([@openlayers](https://github.com/openlayers))
 * [#6079](https://github.com/openlayers/openlayers/pull/6079) - Add view animation ([@tschaub](https://github.com/tschaub))
 * [#6081](https://github.com/openlayers/openlayers/pull/6081) - Update metalsmith-layouts to version 1.7.0 🚀 ([@openlayers](https://github.com/openlayers))
 * [#6074](https://github.com/openlayers/openlayers/pull/6074) - Fix typo on style name on Modify Features Test example ([@tchandelle](https://github.com/tchandelle))
 * [#6073](https://github.com/openlayers/openlayers/pull/6073) - Fix link to errors doc ([@tchandelle](https://github.com/tchandelle))
 * [#6072](https://github.com/openlayers/openlayers/pull/6072) - Update metalsmith to version 2.3.0 🚀 ([@openlayers](https://github.com/openlayers))
 * [#6068](https://github.com/openlayers/openlayers/pull/6068) - Fix GeoJSON writeGeometry tests ([@ahocevar](https://github.com/ahocevar))
 * [#6067](https://github.com/openlayers/openlayers/pull/6067) - Do not draw circle when pointer not moved ([@ahocevar](https://github.com/ahocevar))
 * [#6064](https://github.com/openlayers/openlayers/pull/6064) - Make vertex candidate selection work better on rotated views ([@ahocevar](https://github.com/ahocevar))
 * [#6054](https://github.com/openlayers/openlayers/pull/6054) - Update eslint to version 3.9.1 🚀 ([@openlayers](https://github.com/openlayers))
 * [#6058](https://github.com/openlayers/openlayers/pull/6058) - Update fs-extra to version 1.0.0 🚀 ([@openlayers](https://github.com/openlayers))
 * [#6053](https://github.com/openlayers/openlayers/pull/6053) - Update glob to version 7.1.1 🚀 ([@openlayers](https://github.com/openlayers))
 * [#6045](https://github.com/openlayers/openlayers/pull/6045) - Add an example using Mapbox Terrain-RGB tiles ([@tschaub](https://github.com/tschaub))
 * [#6042](https://github.com/openlayers/openlayers/pull/6042) - Set constants of KML format even if a default style is provided ([@oterral](https://github.com/oterral))
