Geowebcache + Openlayers3 with XYZ source: error by zooming the map
<p>I'm trying the do the same map as here: </p>

<p><a href="https://stackoverflow.com/questions/41012401/openlayers3-tile-grid-incorrect-with-pixelratio-3-using-geoserver-geowebcache-a">Openlayers3: tile grid incorrect with pixelratio=3 using Geoserver/Geowebcache as backend</a> </p>

<p>but using the <a href="https://en.wikipedia.org/wiki/Tile_Map_Service" rel="nofollow noreferrer">TMS</a> protocol instead of <a href="https://en.wikipedia.org/wiki/Web_Map_Service" rel="nofollow noreferrer">WMS</a>. </p>

<p>The map works good but there is a little problem by zooming in, only by changing from zoom level 4 to zoom level 5: the map seems to "jump upwards". The problem occurs with all pixel ratio. </p>

<p>This is my source code. Any help is appreciated:</p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="false" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;WMS Tiles&lt;/title&gt;
    &lt;link rel="stylesheet" href="https://openlayers.org/en/v3.19.1/css/ol.css" type="text/css"&gt;
    &lt;!-- The line below is only needed for old environments like Internet Explorer and Android 4.x --&gt;
    &lt;script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"&gt;&lt;/script&gt;
    &lt;script src="https://openlayers.org/en/v3.19.1/build/ol.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;style type="text/css"&gt;
    body { font-family: sans-serif; font-weight: bold; font-size: .8em; }
    body { border: 0px; margin: 0px; padding: 0px; }
&lt;/style&gt;
&lt;body&gt;
&lt;div id="map" class="map" style="width: 85%; height: 85%;border: 0px; padding: 0px"&gt; &lt;/div&gt;
&lt;script&gt;
    console.log("DOMContentLoaded");
    try {
        var config = {
            "bounds": {
                "left" : 475279.2689196961,
                "bottom" : 5473193.572300382,
                "right" : 476655.1750108673,
                "top" : 5474594.636365802
            }
        };

        var bounds = [config.bounds.left, config.bounds.bottom, config.bounds.right, config.bounds.top];
        var resolutions = [
            1.4,
            0.7,
            0.35,
            0.175,
            0.0875,
            0.04375,
    ];

        var tilePixelRatio = 1;
        if (ol.has.DEVICE_PIXEL_RATIO &gt; 2.5) {
            tilePixelRatio = 3;
        } else if (ol.has.DEVICE_PIXEL_RATIO &gt; 1.5) {
            tilePixelRatio = 2;
        }

        var matrixSet = 'unihd15';
        // available gridsets in backend: unihd15, unihd15_512 and unihd15_768            
        if (tilePixelRatio &gt; 1){
          matrixSet = matrixSet + '_' + (256 * tilePixelRatio).toString();
        }


        var res_length = resolutions.length;
        var matrixIds = new Array(res_length );
        for (var z = 0; z &lt; res_length ; ++z) {
            matrixIds[z] = matrixSet + ':'+ z;
        }

        console.log('matrixSet is: ' + matrixSet);
        console.log(matrixIds);
        console.log(matrixIds[0] + ' '+ resolutions[0]);
        console.log('Center: ' + ol.extent.getCenter(bounds));
        console.log('Pixel ratio: ' + window.devicePixelRatio);
        console.log('Bounds: ' + bounds);
        console.log('TopLeft: ' + ol.extent.getTopLeft(bounds));

        var projection = new ol.proj.Projection({
            code: 'EPSG:32632',
            units: 'm',
            extent: [166021.4431, 0.0000, 833978.5569, 9329005.1825]
        });

        var tileGrid = new ol.tilegrid.TileGrid({
            extent: bounds,
            resolutions: resolutions,
            origin: ol.extent.getTopLeft(bounds),
            tileSize: [256, 256]
        });

        var view = new ol.View({
            extent: bounds,
            zoom: 0,
            center: ol.extent.getCenter(bounds),
            projection: projection,
            resolutions: resolutions
        });

        var layerName = 'unihd15:unihd15_0_basemap';

        var tms_source = new ol.source.XYZ({
            projection: projection,
            tileGrid: tileGrid,
            tilePixelRatio: tilePixelRatio,
            url: 'http://ssp.deepmap.de/geo/gwc/service/tms/1.0.0/' + layerName + '@' + matrixSet + '@png/{z}/{x}/{-y}.png'
        });

        var layer = new ol.layer.Tile({
            source: tms_source,
            extent: bounds
        });

        var map = new ol.Map({
            projection: projection,
            controls: ol.control.defaults(
                {
                    rotate: false,
                    attributionOptions: {
                        collapsible: false
                    }
                }
            ),
            view: view,
            layers: [layer],
            target: 'map'
        });
        console.log("no error");
    } catch (error) {
        console.log("error");
        console.log(error);
    }
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
</div>
</div>
</p>