mapbox-gl
Version:
A WebGL interactive maps library
86 lines (69 loc) • 2.93 kB
JavaScript
;
const Bucket = require('../bucket');
const createElementArrayType = require('../element_array_type');
const loadGeometry = require('../load_geometry');
const EXTENT = require('../extent');
const circleInterface = {
layoutAttributes: [
{name: 'a_pos', components: 2, type: 'Int16'}
],
elementArrayType: createElementArrayType(),
paintAttributes: [
{property: 'circle-color', type: 'Uint8'},
{property: 'circle-radius', type: 'Uint16', multiplier: 10},
{property: 'circle-blur', type: 'Uint16', multiplier: 10},
{property: 'circle-opacity', type: 'Uint8', multiplier: 255},
{property: 'circle-stroke-color', type: 'Uint8'},
{property: 'circle-stroke-width', type: 'Uint16', multiplier: 10},
{property: 'circle-stroke-opacity', type: 'Uint8', multiplier: 255}
]
};
function addCircleVertex(layoutVertexArray, x, y, extrudeX, extrudeY) {
layoutVertexArray.emplaceBack(
(x * 2) + ((extrudeX + 1) / 2),
(y * 2) + ((extrudeY + 1) / 2));
}
/**
* Circles are represented by two triangles.
*
* Each corner has a pos that is the center of the circle and an extrusion
* vector that is where it points.
* @private
*/
class CircleBucket extends Bucket {
constructor(options) {
super(options, circleInterface);
}
addFeature(feature) {
const arrays = this.arrays;
for (const ring of loadGeometry(feature)) {
for (const point of ring) {
const x = point.x;
const y = point.y;
// Do not include points that are outside the tile boundaries.
if (x < 0 || x >= EXTENT || y < 0 || y >= EXTENT) continue;
// this geometry will be of the Point type, and we'll derive
// two triangles from it.
//
// ┌─────────┐
// │ 3 2 │
// │ │
// │ 0 1 │
// └─────────┘
const segment = arrays.prepareSegment(4);
const index = segment.vertexLength;
addCircleVertex(arrays.layoutVertexArray, x, y, -1, -1);
addCircleVertex(arrays.layoutVertexArray, x, y, 1, -1);
addCircleVertex(arrays.layoutVertexArray, x, y, 1, 1);
addCircleVertex(arrays.layoutVertexArray, x, y, -1, 1);
arrays.elementArray.emplaceBack(index, index + 1, index + 2);
arrays.elementArray.emplaceBack(index, index + 3, index + 2);
segment.vertexLength += 4;
segment.primitiveLength += 2;
}
}
arrays.populatePaintArrays(feature.properties);
}
}
CircleBucket.programInterface = circleInterface;
module.exports = CircleBucket;