UNPKG

@deck.gl/experimental-layers

Version:

Experimental layers for deck.gl

193 lines (173 loc) 4.85 kB
import { Layer } from '@deck.gl/core'; import { Model, Geometry } from 'luma.gl'; import tripsVertex from './trips-layer-vertex.glsl'; import tripsFragment from './trips-layer-fragment.glsl'; const defaultProps = { trailLength: { type: 'number', value: 120, min: 0 }, currentTime: { type: 'number', value: 0, min: 0 }, getPath: { type: 'accessor', value: d => d.path }, getColor: { type: 'accessor', value: d => d.color } }; export default class TripsLayer extends Layer { initializeState() { const gl = this.context.gl; const attributeManager = this.getAttributeManager(); const model = this.getModel(gl); attributeManager.add({ indices: { size: 1, update: this.calculateIndices, isIndexed: true }, positions: { size: 3, update: this.calculatePositions }, colors: { size: 3, accessor: 'getColor', update: this.calculateColors } }); gl.getExtension('OES_element_index_uint'); this.setState({ model }); } updateState(_ref) { let props = _ref.props, dataChanged = _ref.changeFlags.dataChanged; if (dataChanged) { this.countVertices(props.data); this.state.attributeManager.invalidateAll(); } } getModel(gl) { return new Model(gl, { id: this.props.id, vs: tripsVertex, fs: tripsFragment, geometry: new Geometry({ id: this.props.id, drawMode: 'LINES' }), vertexCount: 0, isIndexed: true, // TODO-state-management: onBeforeRender can go to settings, onAfterRender, we should // move this settings of corresponding draw. onBeforeRender: () => { gl.enable(gl.BLEND); gl.enable(gl.POLYGON_OFFSET_FILL); gl.polygonOffset(2.0, 1.0); gl.blendFunc(gl.SRC_ALPHA, gl.ONE); gl.blendEquation(gl.FUNC_ADD); }, onAfterRender: () => { gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); gl.disable(gl.POLYGON_OFFSET_FILL); } }); } countVertices(data) { if (!data) { return; } const getPath = this.props.getPath; let vertexCount = 0; const pathLengths = data.reduce((acc, d) => { const l = getPath(d).length; vertexCount += l; return [...acc, l]; }, []); this.setState({ pathLengths, vertexCount }); } draw(_ref2) { let uniforms = _ref2.uniforms; const _this$props = this.props, trailLength = _this$props.trailLength, currentTime = _this$props.currentTime; this.state.model.render(Object.assign({}, uniforms, { trailLength, currentTime })); } calculateIndices(attribute) { const _this$state = this.state, pathLengths = _this$state.pathLengths, vertexCount = _this$state.vertexCount; const indicesCount = (vertexCount - pathLengths.length) * 2; const indices = new Uint32Array(indicesCount); let offset = 0; let index = 0; for (let i = 0; i < pathLengths.length; i++) { const l = pathLengths[i]; indices[index++] = offset; for (let j = 1; j < l - 1; j++) { indices[index++] = j + offset; indices[index++] = j + offset; } indices[index++] = offset + l - 1; offset += l; } attribute.value = indices; this.state.model.setVertexCount(indicesCount); } calculatePositions(attribute) { const _this$props2 = this.props, data = _this$props2.data, getPath = _this$props2.getPath; const vertexCount = this.state.vertexCount; const positions = new Float32Array(vertexCount * 3); let index = 0; for (let i = 0; i < data.length; i++) { const path = getPath(data[i]); for (let j = 0; j < path.length; j++) { const pt = path[j]; positions[index++] = pt[0]; positions[index++] = pt[1]; positions[index++] = pt[2]; } } attribute.value = positions; } calculateColors(attribute) { const _this$props3 = this.props, data = _this$props3.data, getColor = _this$props3.getColor; const _this$state2 = this.state, pathLengths = _this$state2.pathLengths, vertexCount = _this$state2.vertexCount; const colors = new Float32Array(vertexCount * 3); let index = 0; for (let i = 0; i < data.length; i++) { const color = getColor(data[i]); const l = pathLengths[i]; for (let j = 0; j < l; j++) { colors[index++] = color[0]; colors[index++] = color[1]; colors[index++] = color[2]; } } attribute.value = colors; } } TripsLayer.layerName = 'TripsLayer'; TripsLayer.defaultProps = defaultProps; //# sourceMappingURL=trips-layer.js.map