This example uses OpenLayers v10.9.0. The latest is v.
Edit

#### PMTiles Image Tiles

pmtiles 2 raster 6 imagetiles 1

#####

Displaying image tiles from a PMTiles archive.

This example shows image tiles from a PMTiles source. A PMTiles archive can contain tiled data in a variety of formats. In this example, the PMTiles archive contains image-encoded tiles. The PMTiles JavaScript API is used to issue range requests for tile data given tile z, x, y coordinates. The `ImageTile` source is configured with a `loader` that returns a promise for a loaded image. The loader in this example converts the PMTiles response data into a data URL and then uses the browser's built-in image decoder to turn the data URL into an image.

##### main.js

    import Map from 'ol/Map.js';
    import View from 'ol/View.js';
    import Layer from 'ol/layer/WebGLTile.js';
    import {useGeographic} from 'ol/proj.js';
    import Source from 'ol/source/ImageTile.js';
    import {PMTiles} from 'pmtiles';

    useGeographic();

    const tiles = new PMTiles(
      'https://pmtiles.io/stamen_toner(raster)CC-BY+ODbL_z3.pmtiles',
    );

    /**
     * @param {string} src The image source URL.
     * @return {Promise<HTMLImageElement>} Resolves with the loaded image.
     */
    function loadImage(src) {
      return new Promise((resolve, reject) => {
        const img = new Image();
        img.addEventListener('load', () => resolve(img));
        img.addEventListener('error', () => reject(new Error('load failed')));
        img.src = src;
      });
    }

    const source = new Source({
      async loader(z, x, y, {signal}) {
        const response = await tiles.getZxy(z, x, y, signal);
        const blob = new Blob([response.data]);
        const src = URL.createObjectURL(blob);
        const image = await loadImage(src);
        URL.revokeObjectURL(src);
        return image;
      },
      attributions:
        'Map tiles by <a href="http://stamen.com">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/4.0">CC BY 4.0</a>. Data by <a href="http://openstreetmap.org">OpenStreetMap</a>, under <a href="http://www.openstreetmap.org/copyright">ODbL</a>.',
    });

    const map = new Map({
      layers: [new Layer({source})],
      target: 'map',
      view: new View({
        center: [0, 0],
        zoom: 2,
        maxZoom: 4,
      }),
    });

##### index.html

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8">
        <title>PMTiles Image Tiles</title>
        <link rel="stylesheet" href="node_modules/ol/ol.css">
        <style>
          .map {
            width: 100%;
            height: 400px;
          }
        </style>
      </head>
      <body>
        <div id="map" class="map"></div>

        <script type="module" src="main.js"></script>
      </body>
    </html>

##### package.json

    {
      "name": "pmtiles-image",
      "dependencies": {
        "ol": "10.9.0",
        "pmtiles": "^4.0.1"
      },
      "devDependencies": {
        "vite": "^3.2.3"
      },
      "scripts": {
        "start": "vite",
        "build": "vite build"
      }
    }