mirror of https://gitee.com/antv-l7/antv-l7
feat: export BaseModel to support CustomLayer (#1274)
* chore: 修改引用 * style: lint style * feat: export BaseModel to support custom layer * style: lint style
This commit is contained in:
parent
5bf5b808d8
commit
d52765b35a
|
@ -24,7 +24,8 @@ addParameters({
|
|||
|
||||
// const req = require.context('../stories', true, /\.stories\.tsx$/);
|
||||
// const req = require.context('../stories/layerbuild', true, /\.stories\.tsx$/);
|
||||
const req = require.context('../stories/Map', true, /\.stories\.tsx$/);
|
||||
// const req = require.context('../stories/Map', true, /\.stories\.tsx$/);
|
||||
const req = require.context('../stories/template', true, /\.stories\.tsx$/);
|
||||
// const req = require.context('../stories/MapPerformance', true, /\.stories\.tsx$/);
|
||||
// const req = require.context('../stories/tile', true, /\.stories\.tsx$/);
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
"author": "xiaoiver",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@turf/helpers": "^6.1.4",
|
||||
"@antv/async-hook": "^2.1.0",
|
||||
"@antv/l7-utils": "2.9.21",
|
||||
"@babel/runtime": "^7.7.7",
|
||||
|
|
|
@ -26,9 +26,11 @@
|
|||
"author": "xiaoiver",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@antv/async-hook": "^2.1.0",
|
||||
"@antv/l7-core": "2.9.21",
|
||||
"@antv/l7-source": "2.9.21",
|
||||
"@antv/l7-utils": "2.9.21",
|
||||
"@antv/l7-maps": "2.9.21",
|
||||
"@babel/runtime": "^7.7.7",
|
||||
"@mapbox/martini": "^0.2.0",
|
||||
"@turf/helpers": "^6.1.4",
|
||||
|
|
|
@ -2,6 +2,7 @@ import { container, ILayerPlugin, TYPES } from '@antv/l7-core';
|
|||
import CanvasLayer from './canvas';
|
||||
import CityBuildingLayer from './citybuliding/building';
|
||||
import BaseLayer from './core/BaseLayer';
|
||||
import BaseModel from './core/BaseModel';
|
||||
import GeometryLayer from './Geometry'; // 逐步替换为 Geometry
|
||||
import './glsl.d';
|
||||
import HeatmapLayer from './heatmap';
|
||||
|
@ -138,6 +139,7 @@ container
|
|||
|
||||
export {
|
||||
BaseLayer,
|
||||
BaseModel,
|
||||
PointLayer,
|
||||
PolygonLayer,
|
||||
LineLayer,
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
},
|
||||
"homepage": "https://github.com/antvis/L7#readme",
|
||||
"dependencies": {
|
||||
"gl-matrix": "^3.1.0",
|
||||
"@antv/l7-utils": "2.9.21",
|
||||
"@babel/runtime": "^7.7.7",
|
||||
"@mapbox/point-geometry": "^0.1.0",
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@antv/l7-core": "2.9.21",
|
||||
"@antv/l7-utils": "2.9.21",
|
||||
"@babel/runtime": "^7.7.7",
|
||||
"inversify": "^5.0.1",
|
||||
"l7regl": "^0.0.20",
|
||||
|
|
|
@ -0,0 +1,272 @@
|
|||
import { BaseLayer, BaseModel, IModelUniform, ILayerService, IModel, ILayer, PointFillTriangulation, IStyleAttributeService, IEncodeFeature, gl, AttributeType } from '@antv/l7';
|
||||
|
||||
const pointFillFrag = `
|
||||
uniform float u_opacity : 1.0;
|
||||
uniform float u_stroke_opacity : 1;
|
||||
uniform float u_stroke_width : 2;
|
||||
uniform vec4 u_stroke_color : [0.0, 0.0, 0.0, 0.0];
|
||||
|
||||
varying vec4 v_data;
|
||||
varying vec4 v_color;
|
||||
varying float v_radius;
|
||||
|
||||
#pragma include "sdf_2d"
|
||||
#pragma include "picking"
|
||||
|
||||
void main() {
|
||||
int shape = int(floor(v_data.w + 0.5));
|
||||
|
||||
lowp float antialiasblur = v_data.z;
|
||||
float r = v_radius / (v_radius + u_stroke_width);
|
||||
|
||||
float outer_df;
|
||||
float inner_df;
|
||||
// 'circle', 'triangle', 'square', 'pentagon', 'hexagon', 'octogon', 'hexagram', 'rhombus', 'vesica'
|
||||
if (shape == 0) {
|
||||
outer_df = sdCircle(v_data.xy, 1.0);
|
||||
inner_df = sdCircle(v_data.xy, r);
|
||||
} else if (shape == 1) {
|
||||
outer_df = sdEquilateralTriangle(1.1 * v_data.xy);
|
||||
inner_df = sdEquilateralTriangle(1.1 / r * v_data.xy);
|
||||
} else if (shape == 2) {
|
||||
outer_df = sdBox(v_data.xy, vec2(1.));
|
||||
inner_df = sdBox(v_data.xy, vec2(r));
|
||||
} else if (shape == 3) {
|
||||
outer_df = sdPentagon(v_data.xy, 0.8);
|
||||
inner_df = sdPentagon(v_data.xy, r * 0.8);
|
||||
} else if (shape == 4) {
|
||||
outer_df = sdHexagon(v_data.xy, 0.8);
|
||||
inner_df = sdHexagon(v_data.xy, r * 0.8);
|
||||
} else if (shape == 5) {
|
||||
outer_df = sdOctogon(v_data.xy, 1.0);
|
||||
inner_df = sdOctogon(v_data.xy, r);
|
||||
} else if (shape == 6) {
|
||||
outer_df = sdHexagram(v_data.xy, 0.52);
|
||||
inner_df = sdHexagram(v_data.xy, r * 0.52);
|
||||
} else if (shape == 7) {
|
||||
outer_df = sdRhombus(v_data.xy, vec2(1.0));
|
||||
inner_df = sdRhombus(v_data.xy, vec2(r));
|
||||
} else if (shape == 8) {
|
||||
outer_df = sdVesica(v_data.xy, 1.1, 0.8);
|
||||
inner_df = sdVesica(v_data.xy, r * 1.1, r * 0.8);
|
||||
}
|
||||
|
||||
float opacity_t = smoothstep(0.0, antialiasblur, outer_df);
|
||||
|
||||
float color_t = u_stroke_width < 0.01 ? 0.0 : smoothstep(
|
||||
antialiasblur,
|
||||
0.0,
|
||||
inner_df
|
||||
);
|
||||
|
||||
if(u_stroke_width < 0.01) {
|
||||
gl_FragColor = vec4(v_color.rgb, v_color.a * u_opacity);
|
||||
} else {
|
||||
gl_FragColor = mix(vec4(v_color.rgb, v_color.a * u_opacity), u_stroke_color * u_stroke_opacity, color_t);
|
||||
}
|
||||
|
||||
gl_FragColor.a *= opacity_t;
|
||||
gl_FragColor = filterColor(gl_FragColor);
|
||||
}
|
||||
`
|
||||
const pointFillVert = `
|
||||
attribute vec4 a_Color;
|
||||
attribute vec3 a_Position;
|
||||
attribute vec3 a_Extrude;
|
||||
attribute float a_Size;
|
||||
attribute float a_Shape;
|
||||
|
||||
uniform mat4 u_ModelMatrix;
|
||||
uniform mat4 u_Mvp;
|
||||
|
||||
varying vec4 v_data;
|
||||
varying vec4 v_color;
|
||||
varying float v_radius;
|
||||
|
||||
uniform float u_stroke_width : 2;
|
||||
|
||||
|
||||
#pragma include "projection"
|
||||
#pragma include "picking"
|
||||
|
||||
|
||||
void main() {
|
||||
vec3 extrude = a_Extrude;
|
||||
float shape_type = a_Shape;
|
||||
|
||||
float newSize = setPickingSize(a_Size);
|
||||
|
||||
v_color = a_Color;
|
||||
|
||||
v_radius = newSize;
|
||||
|
||||
|
||||
float antialiasblur = -max(2.0 / u_DevicePixelRatio / newSize, 0.0);
|
||||
|
||||
vec2 offset = project_pixel(extrude.xy * (newSize + u_stroke_width));
|
||||
|
||||
v_data = vec4(extrude.x, extrude.y, antialiasblur, shape_type);
|
||||
|
||||
vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0));
|
||||
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||
gl_Position = u_Mvp * vec4(project_pos.xy + offset, 0.0, 1.0);
|
||||
} else {
|
||||
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0.0, 1.0));
|
||||
}
|
||||
|
||||
setPickingColor(a_PickingColor);
|
||||
}
|
||||
`
|
||||
|
||||
interface ICustomPointLayerStyleOptions {
|
||||
opacity: number;
|
||||
strokeOpacity: number;
|
||||
strokeWidth: number;
|
||||
stroke: string;
|
||||
}
|
||||
|
||||
class CustomModel extends BaseModel {
|
||||
constructor(layer: ILayer) {
|
||||
super(layer)
|
||||
}
|
||||
|
||||
public layer: ILayer
|
||||
public styleAttributeService: IStyleAttributeService
|
||||
public getUninforms(): IModelUniform {
|
||||
const { opacity, stroke = [1.0, 0.0, 0.0, 1.0], strokeOpacity = 1.0, strokeWidth = 0 } = this.layer.getLayerConfig() as ICustomPointLayerStyleOptions;
|
||||
|
||||
return {
|
||||
u_opacity: opacity,
|
||||
u_stroke_opacity: strokeOpacity,
|
||||
u_stroke_width: strokeWidth,
|
||||
u_stroke_color: stroke as number[],
|
||||
};
|
||||
}
|
||||
|
||||
public initModels(callbackModel: (models: IModel[]) => void) {
|
||||
this.buildModels(callbackModel);
|
||||
}
|
||||
|
||||
public async buildModels(callbackModel: (models: IModel[]) => void) {
|
||||
this.layer
|
||||
.buildLayerModel({
|
||||
moduleName: "customPoint",
|
||||
vertexShader: pointFillVert,
|
||||
fragmentShader: pointFillFrag,
|
||||
triangulation: PointFillTriangulation,
|
||||
depth: { enable: false },
|
||||
})
|
||||
.then((model) => {
|
||||
callbackModel([model]);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.warn(err);
|
||||
callbackModel([]);
|
||||
});
|
||||
}
|
||||
|
||||
protected registerBuiltinAttributes() {
|
||||
const shape2d = this.layer.getLayerConfig().shape2d as string[];
|
||||
|
||||
this.styleAttributeService.registerStyleAttribute({
|
||||
name: 'extrude',
|
||||
type: AttributeType.Attribute,
|
||||
descriptor: {
|
||||
name: 'a_Extrude',
|
||||
buffer: {
|
||||
// give the WebGL driver a hint that this buffer may change
|
||||
usage: gl.DYNAMIC_DRAW,
|
||||
data: [],
|
||||
type: gl.FLOAT,
|
||||
},
|
||||
size: 3,
|
||||
update: (
|
||||
feature: IEncodeFeature,
|
||||
featureIdx: number,
|
||||
vertex: number[],
|
||||
attributeIdx: number,
|
||||
) => {
|
||||
const extrude = [1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0];
|
||||
const extrudeIndex = (attributeIdx % 4) * 3;
|
||||
return [
|
||||
extrude[extrudeIndex],
|
||||
extrude[extrudeIndex + 1],
|
||||
extrude[extrudeIndex + 2],
|
||||
];
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// point layer size;
|
||||
this.styleAttributeService.registerStyleAttribute({
|
||||
name: 'size',
|
||||
type: AttributeType.Attribute,
|
||||
descriptor: {
|
||||
name: 'a_Size',
|
||||
buffer: {
|
||||
// give the WebGL driver a hint that this buffer may change
|
||||
usage: gl.DYNAMIC_DRAW,
|
||||
data: [],
|
||||
type: gl.FLOAT,
|
||||
},
|
||||
size: 1,
|
||||
update: (
|
||||
feature: IEncodeFeature,
|
||||
featureIdx: number,
|
||||
vertex: number[],
|
||||
attributeIdx: number,
|
||||
) => {
|
||||
const { size = 5 } = feature;
|
||||
return Array.isArray(size) ? [size[0]] : [size];
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// point layer size;
|
||||
this.styleAttributeService.registerStyleAttribute({
|
||||
name: 'shape',
|
||||
type: AttributeType.Attribute,
|
||||
descriptor: {
|
||||
name: 'a_Shape',
|
||||
buffer: {
|
||||
// give the WebGL driver a hint that this buffer may change
|
||||
usage: gl.DYNAMIC_DRAW,
|
||||
data: [],
|
||||
type: gl.FLOAT,
|
||||
},
|
||||
size: 1,
|
||||
update: (
|
||||
feature: IEncodeFeature,
|
||||
featureIdx: number,
|
||||
vertex: number[],
|
||||
attributeIdx: number,
|
||||
) => {
|
||||
const { shape = 2 } = feature;
|
||||
const shapeIndex = shape2d.indexOf(shape as string);
|
||||
return [shapeIndex];
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default class CustomPoint extends BaseLayer {
|
||||
public type: string = 'PointLayer';
|
||||
public layerModel: CustomModel;
|
||||
public layerService: ILayerService
|
||||
public models: any
|
||||
public rendering: boolean;
|
||||
|
||||
public buildModels() {
|
||||
this.layerModel = new CustomModel(this);
|
||||
this.layerModel.initModels((models) => {
|
||||
this.models = models;
|
||||
this.layerService.updateLayerRenderList();
|
||||
|
||||
// renderLayers
|
||||
this.rendering = true;
|
||||
this.layerService.renderLayers();
|
||||
this.rendering = false;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
import {
|
||||
LineLayer,
|
||||
Scene,
|
||||
MaskLayer,
|
||||
PolygonLayer,
|
||||
PointLayer,
|
||||
} from '@antv/l7';
|
||||
import { GaodeMap } from '@antv/l7-maps';
|
||||
import * as React from 'react';
|
||||
|
||||
import CustomPoint from './CustomPointLayer';
|
||||
|
||||
export default class Demo extends React.Component {
|
||||
private scene: Scene;
|
||||
|
||||
public componentWillUnmount() {
|
||||
this.scene.destroy();
|
||||
}
|
||||
|
||||
public async componentDidMount() {
|
||||
const scene = new Scene({
|
||||
id: 'map',
|
||||
stencil: true,
|
||||
map: new GaodeMap({
|
||||
center: [120, 30],
|
||||
pitch: 0,
|
||||
zoom: 15,
|
||||
style: 'dark',
|
||||
}),
|
||||
});
|
||||
this.scene = scene;
|
||||
let layer = new CustomPoint()
|
||||
// @ts-ignore
|
||||
.source(
|
||||
[
|
||||
{
|
||||
lng: 120,
|
||||
lat: 30,
|
||||
},
|
||||
],
|
||||
{
|
||||
parser: {
|
||||
type: 'json',
|
||||
x: 'lng',
|
||||
y: 'lat',
|
||||
},
|
||||
},
|
||||
)
|
||||
.shape('circle')
|
||||
.color('#ff0')
|
||||
.size(30)
|
||||
.style({
|
||||
opacity: 0.3,
|
||||
})
|
||||
.active(true);
|
||||
|
||||
scene.on('loaded', () => {
|
||||
scene.addLayer(layer);
|
||||
});
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
id="map"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
import { storiesOf } from '@storybook/react';
|
||||
import * as React from 'react';
|
||||
|
||||
|
||||
import Point from './components/point'
|
||||
|
||||
storiesOf('自定义模版', module)
|
||||
.add('Point', () => <Point/>)
|
Loading…
Reference in New Issue