In case the point is part of a cluster (i.e. it has more than one feature), I want to show the quantity of features. I used to do it like this with a VectorLayer:
const clusterSource = new Cluster({
  distance: 50,
  minDistance: 10,
  source: source,
});
const noClusterStyle = new Style({
  image: new CircleStyle({
    radius: 5,
    fill: new Fill({
      color: '#ffcc33',
    }),
  }),
});
const clusterStyle = new Style({
  text: new Text({
    fill: new Fill({
      color: '#fff',
    }),
  }),
})
const vectorLayer = new VectorLayer({
  source: clusterSource,
  style: function (feature) {
    const size = feature.get('features').length;
    if (size > 1) {
      clusterStyle.getText().setText(size.toString());
      return clusterStyle;
    }
    return noClusterStyle;
  },
});
Now I want to use a WebGLVectorLayer instead of a VectorLayer, however, its style must be a FlatStyleLike.
I tried the following:
import WebGLVectorLayer from 'ol/layer/WebGLVector';
const generateTextLabel = (featuresAmount) => {
  return (
    `<svg width="10" height="10" version="1.1" xmlns=";>
      <text x="0" y="18" fill="white" font-size="16">${featuresAmount}</text>
    </svg>`
  )
}
const flatLikeStyle = [
  {
    style: {
      'shape-fill-color': 'black',
      'shape-points': 4,
      'shape-radius': 10,
    }
  },
  {
    filter: ['>', ['get', 'features'], 1],
    style: {
      'icon-src': 'data:image/svg+xml;utf8,' + generateTextLabel(0),
    },
  },
]
const webglVectorLayer = new WebGLVectorLayer({
  source: clusterSource,
  style: flatLikeStyle
})
But I don't know how to make the filter work with the size of features. I don't know how to pass the amount of features to the generateTextLabel() function either.
In case the point is part of a cluster (i.e. it has more than one feature), I want to show the quantity of features. I used to do it like this with a VectorLayer:
const clusterSource = new Cluster({
  distance: 50,
  minDistance: 10,
  source: source,
});
const noClusterStyle = new Style({
  image: new CircleStyle({
    radius: 5,
    fill: new Fill({
      color: '#ffcc33',
    }),
  }),
});
const clusterStyle = new Style({
  text: new Text({
    fill: new Fill({
      color: '#fff',
    }),
  }),
})
const vectorLayer = new VectorLayer({
  source: clusterSource,
  style: function (feature) {
    const size = feature.get('features').length;
    if (size > 1) {
      clusterStyle.getText().setText(size.toString());
      return clusterStyle;
    }
    return noClusterStyle;
  },
});
Now I want to use a WebGLVectorLayer instead of a VectorLayer, however, its style must be a FlatStyleLike.
I tried the following:
import WebGLVectorLayer from 'ol/layer/WebGLVector';
const generateTextLabel = (featuresAmount) => {
  return (
    `<svg width="10" height="10" version="1.1" xmlns="http://www.w3.org/2000/svg">
      <text x="0" y="18" fill="white" font-size="16">${featuresAmount}</text>
    </svg>`
  )
}
const flatLikeStyle = [
  {
    style: {
      'shape-fill-color': 'black',
      'shape-points': 4,
      'shape-radius': 10,
    }
  },
  {
    filter: ['>', ['get', 'features'], 1],
    style: {
      'icon-src': 'data:image/svg+xml;utf8,' + generateTextLabel(0),
    },
  },
]
const webglVectorLayer = new WebGLVectorLayer({
  source: clusterSource,
  style: flatLikeStyle
})
But I don't know how to make the filter work with the size of features. I don't know how to pass the amount of features to the generateTextLabel() function either.
To obtain the length of an array you would need to save that as a feature property when the cluster is created.  Also you cannot have more than one value for icon-src, you would need to create a sprite containing all possible values
const canvas = document.createElement('canvas');
const max = 200;
const size = 20;
canvas.width = max * size;
canvas.heigth = size;
const context = canvas.getContext('2d');
context.textAlign = 'center';
context.textBaseline = 'middle';
context.font = '10px sans-serif';
const match = [];
for (let i = 0; i < max; ++i) {
  context.fillStyle = '#3399CC';
  context.fillRect(i * size, 0, size, size);
  context.fillStyle = 'white';
  context.fillText(`${i + 1}`, i * size + size / 2, size / 2);
  match.push(i, [i * size, 0]);
}
const sprite = canvas.toDataURL();
const source = new VectorSource({
  features: features,
});
const clusterSource = new Cluster({
  distance: parseInt(distanceInput.value, 10),
  minDistance: parseInt(minDistanceInput.value, 10),
  source: source,
});
clusterSource.on('addfeature', (e) => {
  e.feature.set('size', e.feature.get('features').length);
});
const clusters = new WebGLVectorLayer({
  source: clusterSource,
  style: {
    'icon-src': sprite,
    'icon-offset': ['match', ['get', 'size'], ...match, [0, 0]],
    'icon-size': [20, 20],
  },
});
Working example https://stackblitz.com/edit/js-hfsqdrec?file=package.json,index.html,index.js

