mirror of https://gitee.com/antv-l7/antv-l7
feat: styles
This commit is contained in:
parent
56f6f8fe71
commit
ca33c7e268
|
@ -79,7 +79,6 @@ export default class LayerService implements ILayerService {
|
|||
.filter((layer) => layer.inited)
|
||||
.filter((layer) => layer.isVisible())
|
||||
.forEach((layer) => {
|
||||
|
||||
// trigger hooks
|
||||
layer.hooks.beforeRenderData.call();
|
||||
layer.hooks.beforeRender.call();
|
||||
|
|
|
@ -267,7 +267,7 @@ export default class Scene extends EventEmitter implements ISceneService {
|
|||
|
||||
// 尝试初始化未初始化的图层
|
||||
this.layerService.renderLayers();
|
||||
|
||||
|
||||
// 组件需要等待layer 初始化完成之后添加
|
||||
this.logger.debug(`scene ${this.id} render`);
|
||||
this.rendering = false;
|
||||
|
|
|
@ -52,8 +52,11 @@ import { isFunction, isObject } from 'lodash';
|
|||
import mergeJsonSchemas from 'merge-json-schemas';
|
||||
import { normalizePasses } from '../plugins/MultiPassRendererPlugin';
|
||||
import { BlendTypes } from '../utils/blend';
|
||||
import {
|
||||
handleStyleOpacity,
|
||||
handleStyleStrokeOpacity,
|
||||
} from '../utils/dataMappingStyle';
|
||||
import baseLayerSchema from './schema';
|
||||
import { handleStyleOpacity, handleStyleStrokeOpacity } from '../utils/dataMappingStyle'
|
||||
/**
|
||||
* 分配 layer id
|
||||
*/
|
||||
|
@ -208,14 +211,19 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> extends EventEmitter
|
|||
} else {
|
||||
const sceneId = this.container.get<string>(TYPES.SceneID);
|
||||
// @ts-ignore
|
||||
if(configToUpdate.opacity){
|
||||
if (configToUpdate.opacity) {
|
||||
// @ts-ignore
|
||||
handleStyleOpacity('opacity', this, configToUpdate.opacity);
|
||||
}
|
||||
// @ts-ignore
|
||||
if(configToUpdate.strokeOpacity){
|
||||
if (configToUpdate.strokeOpacity) {
|
||||
// @ts-ignore
|
||||
handleStyleStrokeOpacity('strokeOpacity', this, configToUpdate.strokeOpacity);
|
||||
handleStyleStrokeOpacity(
|
||||
'strokeOpacity',
|
||||
this,
|
||||
// @ts-ignore
|
||||
configToUpdate.strokeOpacity,
|
||||
);
|
||||
}
|
||||
this.configService.setLayerConfig(sceneId, this.id, {
|
||||
...this.configService.getLayerConfig(this.id),
|
||||
|
|
|
@ -83,7 +83,6 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
|||
// 处理文本更新
|
||||
layer.emit('remapping', null);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
private generateMaping(
|
||||
|
|
|
@ -31,7 +31,6 @@ export default class UpdateStyleAttributePlugin implements ILayerPlugin {
|
|||
// });
|
||||
|
||||
layer.hooks.beforeRender.tap('UpdateStyleAttributePlugin', () => {
|
||||
|
||||
if (layer.layerModelNeedUpdate) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
ILayerConfig,
|
||||
IModel,
|
||||
IModelUniform,
|
||||
ITexture2D
|
||||
ITexture2D,
|
||||
} from '@antv/l7-core';
|
||||
import { rgb2arr } from '@antv/l7-utils';
|
||||
import BaseModel from '../../core/BaseModel';
|
||||
|
@ -16,8 +16,13 @@ import { PointFillTriangulation } from '../../core/triangulation';
|
|||
import pointFillFrag from '../shaders/fill_frag.glsl';
|
||||
import pointFillVert from '../shaders/fill_vert.glsl';
|
||||
|
||||
import { getSize, getUvPosition, initTextureData, initDefaultTextureData } from '../../utils/dataMappingStyle'
|
||||
import { isNumber } from 'lodash';
|
||||
import {
|
||||
getSize,
|
||||
getUvPosition,
|
||||
initDefaultTextureData,
|
||||
initTextureData,
|
||||
} from '../../utils/dataMappingStyle';
|
||||
interface IPointLayerStyleOptions {
|
||||
opacity: any;
|
||||
strokeWidth: number;
|
||||
|
@ -37,21 +42,21 @@ interface IDataLayout {
|
|||
|
||||
// 用于判断 opacity 的值是否发生该改变
|
||||
let curretnOpacity: any = '';
|
||||
let curretnStrokeOpacity: any = ''
|
||||
let curretnStrokeOpacity: any = '';
|
||||
|
||||
export default class FillModel extends BaseModel {
|
||||
|
||||
protected opacityTexture: ITexture2D;
|
||||
|
||||
public dataLayout: IDataLayout = { // 默认值
|
||||
public dataLayout: IDataLayout = {
|
||||
// 默认值
|
||||
widthCount: 1024,
|
||||
heightCount: 1,
|
||||
widthStep: 1/1024,
|
||||
widthStart: 1/2048,
|
||||
widthStep: 1 / 1024,
|
||||
widthStart: 1 / 2048,
|
||||
heightStep: 1,
|
||||
heightStart: 0.5
|
||||
heightStart: 0.5,
|
||||
};
|
||||
|
||||
protected opacityTexture: ITexture2D;
|
||||
|
||||
public getUninforms(): IModelUniform {
|
||||
const {
|
||||
opacity,
|
||||
|
@ -61,18 +66,21 @@ export default class FillModel extends BaseModel {
|
|||
offsets = [0, 0],
|
||||
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||
|
||||
if ( curretnOpacity !== JSON.stringify(opacity)) {
|
||||
if (curretnOpacity !== JSON.stringify(opacity)) {
|
||||
const { createTexture2D } = this.rendererService;
|
||||
// 从 encodeData 数据的 opacity 字段上取值,并将值按照排布写入到纹理中
|
||||
this.opacityTexture = initTextureData(this.dataLayout.heightCount, createTexture2D, this.layer.getEncodedData(), 'opacity')
|
||||
|
||||
this.opacityTexture = initTextureData(
|
||||
this.dataLayout.heightCount,
|
||||
createTexture2D,
|
||||
this.layer.getEncodedData(),
|
||||
'opacity',
|
||||
);
|
||||
|
||||
curretnOpacity = JSON.stringify(opacity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(curretnStrokeOpacity !== JSON.stringify(strokeOpacity)) {
|
||||
|
||||
curretnStrokeOpacity = JSON.stringify(strokeOpacity)
|
||||
if (curretnStrokeOpacity !== JSON.stringify(strokeOpacity)) {
|
||||
curretnStrokeOpacity = JSON.stringify(strokeOpacity);
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -80,7 +88,7 @@ export default class FillModel extends BaseModel {
|
|||
u_opacity: opacity ? -1.0 : 1.0,
|
||||
u_stroke_width: strokeWidth,
|
||||
u_stroke_color: rgb2arr(stroke),
|
||||
u_stroke_opacity: isNumber(strokeOpacity)?strokeOpacity: 1.0,
|
||||
u_stroke_opacity: isNumber(strokeOpacity) ? strokeOpacity : 1.0,
|
||||
u_offsets: [-offsets[0], offsets[1]],
|
||||
};
|
||||
}
|
||||
|
@ -105,19 +113,18 @@ export default class FillModel extends BaseModel {
|
|||
}
|
||||
|
||||
public initEncodeDataLayout(dataLength: number) {
|
||||
let { width: widthCount, height: heightCount } = getSize(dataLength)
|
||||
this.dataLayout.widthCount = widthCount
|
||||
this.dataLayout.heightCount = heightCount
|
||||
const { width: widthCount, height: heightCount } = getSize(dataLength);
|
||||
this.dataLayout.widthCount = widthCount;
|
||||
this.dataLayout.heightCount = heightCount;
|
||||
|
||||
this.dataLayout.widthStep = 1/widthCount
|
||||
this.dataLayout.widthStart = this.dataLayout.widthStep/2
|
||||
this.dataLayout.heightStep = 1/heightCount
|
||||
this.dataLayout.heightStart = this.dataLayout.heightStep/2
|
||||
this.dataLayout.widthStep = 1 / widthCount;
|
||||
this.dataLayout.widthStart = this.dataLayout.widthStep / 2;
|
||||
this.dataLayout.heightStep = 1 / heightCount;
|
||||
this.dataLayout.heightStart = this.dataLayout.heightStep / 2;
|
||||
}
|
||||
|
||||
public initModels(): IModel[] {
|
||||
|
||||
this.initEncodeDataLayout(this.layer.getEncodedData().length)
|
||||
this.initEncodeDataLayout(this.layer.getEncodedData().length);
|
||||
|
||||
return this.buildModels();
|
||||
}
|
||||
|
@ -208,11 +215,12 @@ export default class FillModel extends BaseModel {
|
|||
attributeIdx: number,
|
||||
) => {
|
||||
return getUvPosition(
|
||||
this.dataLayout.widthStep,
|
||||
this.dataLayout.widthStart,
|
||||
this.dataLayout.heightStep,
|
||||
this.dataLayout.heightStart,
|
||||
featureIdx)
|
||||
this.dataLayout.widthStep,
|
||||
this.dataLayout.widthStart,
|
||||
this.dataLayout.heightStep,
|
||||
this.dataLayout.heightStart,
|
||||
featureIdx,
|
||||
);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {
|
||||
ILayer,
|
||||
ITexture2D,
|
||||
IStyleAttributeUpdateOptions,
|
||||
ITexture2D,
|
||||
StyleAttributeField,
|
||||
StyleAttributeOption,
|
||||
} from '@antv/l7-core';
|
||||
|
@ -11,7 +11,7 @@ import { isArray, isFunction, isNumber, isString } from 'lodash';
|
|||
*/
|
||||
|
||||
// 画布默认的宽度
|
||||
const WIDTH = 1024
|
||||
const WIDTH = 1024;
|
||||
|
||||
/**
|
||||
* 当 style 中使用的 opacity 不是常数的时候根据数据进行映射
|
||||
|
@ -20,11 +20,11 @@ const WIDTH = 1024
|
|||
* @param updateOptions
|
||||
*/
|
||||
function registerOpacityAttribute(
|
||||
fieldName: string,
|
||||
layer: ILayer,
|
||||
field: StyleAttributeField,
|
||||
values?: StyleAttributeOption,
|
||||
updateOptions?: Partial<IStyleAttributeUpdateOptions>,
|
||||
fieldName: string,
|
||||
layer: ILayer,
|
||||
field: StyleAttributeField,
|
||||
values?: StyleAttributeOption,
|
||||
updateOptions?: Partial<IStyleAttributeUpdateOptions>,
|
||||
) {
|
||||
layer.updateStyleAttribute(fieldName, field, values, updateOptions);
|
||||
}
|
||||
|
@ -64,98 +64,117 @@ function handleStyleOpacity(fieldName: string, layer: ILayer, opacity: any) {
|
|||
/**
|
||||
* 根据传入参数 strokeOpacity 的类型和值做相应的操作
|
||||
*/
|
||||
function handleStyleStrokeOpacity(fieldName: string, layer: ILayer, strokeOpacity: any) {
|
||||
handleStyleOpacity(fieldName, layer, strokeOpacity)
|
||||
function handleStyleStrokeOpacity(
|
||||
fieldName: string,
|
||||
layer: ILayer,
|
||||
strokeOpacity: any,
|
||||
) {
|
||||
handleStyleOpacity(fieldName, layer, strokeOpacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据输入的 feature 的长度以及默认的宽度计算画布的大小
|
||||
* @param encodeDatalength
|
||||
* @returns
|
||||
* @param encodeDatalength
|
||||
* @returns
|
||||
*/
|
||||
function getSize(encodeDatalength: number) {
|
||||
let width = WIDTH;
|
||||
let height = Math.ceil(encodeDatalength / width);
|
||||
return { width, height }
|
||||
const width = WIDTH;
|
||||
const height = Math.ceil(encodeDatalength / width);
|
||||
return { width, height };
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据输入的宽高边距信息,为需要为 index 的 feature 计算在画布上对应的 uv 值
|
||||
* @param widthStep
|
||||
* @param widthStart
|
||||
* @param heightStep
|
||||
* @param heightStart
|
||||
* @param id
|
||||
* @returns
|
||||
* @param widthStep
|
||||
* @param widthStart
|
||||
* @param heightStep
|
||||
* @param heightStart
|
||||
* @param id
|
||||
* @returns
|
||||
*/
|
||||
function getUvPosition(widthStep: number, widthStart: number, heightStep: number, heightStart: number, index: number) {
|
||||
// index 从零开始
|
||||
let row = Math.ceil((index + 1)/WIDTH); // 当前 index 所在的行
|
||||
let column = (index + 1) % WIDTH
|
||||
if(column === 0) { // 取余等于零
|
||||
column = WIDTH
|
||||
}
|
||||
let u = widthStart + (column - 1) * widthStep
|
||||
let v = 1 - (heightStart + (row - 1) * heightStep)
|
||||
return [u, v]
|
||||
function getUvPosition(
|
||||
widthStep: number,
|
||||
widthStart: number,
|
||||
heightStep: number,
|
||||
heightStart: number,
|
||||
index: number,
|
||||
) {
|
||||
// index 从零开始
|
||||
const row = Math.ceil((index + 1) / WIDTH); // 当前 index 所在的行
|
||||
let column = (index + 1) % WIDTH;
|
||||
if (column === 0) {
|
||||
// 取余等于零
|
||||
column = WIDTH;
|
||||
}
|
||||
const u = widthStart + (column - 1) * widthStep;
|
||||
const v = 1 - (heightStart + (row - 1) * heightStep);
|
||||
return [u, v];
|
||||
}
|
||||
|
||||
/**
|
||||
* 1、根据输入的 field 字段从 originData 中取值 (style 样式用于数据映射的值)
|
||||
* 2、根据输入的 heightCount 以及默认的 WIDTH 为纹理对象提供数据
|
||||
* 3、根据输入的 createTexture2D 构建纹理对象
|
||||
* @param heightCount
|
||||
* @param createTexture2D
|
||||
* @param originData
|
||||
* @param field
|
||||
* @returns
|
||||
* @param heightCount
|
||||
* @param createTexture2D
|
||||
* @param originData
|
||||
* @param field
|
||||
* @returns
|
||||
*/
|
||||
function initTextureData(heightCount: number, createTexture2D: any, originData: any, field: string): ITexture2D {
|
||||
let d = []
|
||||
for(let i = 0; i < WIDTH * heightCount; i++) {
|
||||
if(originData[i] && originData[i][field]) {
|
||||
let v = originData[i][field] * 255
|
||||
d.push( v, v, v, v )
|
||||
}else {
|
||||
d.push( 0, 0, 0, 0 )
|
||||
}
|
||||
function initTextureData(
|
||||
heightCount: number,
|
||||
createTexture2D: any,
|
||||
originData: any,
|
||||
field: string,
|
||||
): ITexture2D {
|
||||
const d = [];
|
||||
for (let i = 0; i < WIDTH * heightCount; i++) {
|
||||
if (originData[i] && originData[i][field]) {
|
||||
const v = originData[i][field] * 255;
|
||||
d.push(v, v, v, v);
|
||||
} else {
|
||||
d.push(0, 0, 0, 0);
|
||||
}
|
||||
let arr = new Uint8ClampedArray(d)
|
||||
let imageData = new ImageData(arr, WIDTH, heightCount) // (arr, width, height)
|
||||
}
|
||||
const arr = new Uint8ClampedArray(d);
|
||||
const imageData = new ImageData(arr, WIDTH, heightCount); // (arr, width, height)
|
||||
|
||||
let texture = createTexture2D({
|
||||
flipY: true,
|
||||
data: new Uint8Array(imageData.data),
|
||||
width: imageData.width,
|
||||
height: imageData.height
|
||||
});
|
||||
const texture = createTexture2D({
|
||||
flipY: true,
|
||||
data: new Uint8Array(imageData.data),
|
||||
width: imageData.width,
|
||||
height: imageData.height,
|
||||
});
|
||||
|
||||
return texture
|
||||
return texture;
|
||||
}
|
||||
|
||||
function initDefaultTextureData(heightCount: number, createTexture2D: any): ITexture2D {
|
||||
let d = []
|
||||
for(let i = 0; i < WIDTH * heightCount; i++) {
|
||||
d.push( 255, 255, 255, 255 )
|
||||
}
|
||||
let arr = new Uint8ClampedArray(d)
|
||||
let imageData = new ImageData(arr, WIDTH, heightCount) // (arr, width, height)
|
||||
function initDefaultTextureData(
|
||||
heightCount: number,
|
||||
createTexture2D: any,
|
||||
): ITexture2D {
|
||||
const d = [];
|
||||
for (let i = 0; i < WIDTH * heightCount; i++) {
|
||||
d.push(255, 255, 255, 255);
|
||||
}
|
||||
const arr = new Uint8ClampedArray(d);
|
||||
const imageData = new ImageData(arr, WIDTH, heightCount); // (arr, width, height)
|
||||
|
||||
let texture = createTexture2D({
|
||||
flipY: true,
|
||||
data: new Uint8Array(imageData.data),
|
||||
width: imageData.width,
|
||||
height: imageData.height
|
||||
});
|
||||
const texture = createTexture2D({
|
||||
flipY: true,
|
||||
data: new Uint8Array(imageData.data),
|
||||
width: imageData.width,
|
||||
height: imageData.height,
|
||||
});
|
||||
|
||||
return texture
|
||||
return texture;
|
||||
}
|
||||
|
||||
export {
|
||||
handleStyleOpacity,
|
||||
handleStyleStrokeOpacity,
|
||||
getSize,
|
||||
getUvPosition,
|
||||
initTextureData,
|
||||
initDefaultTextureData
|
||||
export {
|
||||
handleStyleOpacity,
|
||||
handleStyleStrokeOpacity,
|
||||
getSize,
|
||||
getUvPosition,
|
||||
initTextureData,
|
||||
initDefaultTextureData,
|
||||
};
|
||||
|
|
|
@ -26,19 +26,19 @@ export default class Amap2demo extends React.Component {
|
|||
lng: 121.107846,
|
||||
lat: 30.267069,
|
||||
opacity2: 0.2,
|
||||
strokeOpacity2: 0.2
|
||||
strokeOpacity2: 0.2,
|
||||
},
|
||||
{
|
||||
lng: 121.107,
|
||||
lat: 30.267069,
|
||||
opacity2: 0.4,
|
||||
strokeOpacity2: 0.4
|
||||
strokeOpacity2: 0.4,
|
||||
},
|
||||
{
|
||||
lng: 121.107846,
|
||||
lat: 30.26718,
|
||||
opacity2: 0.6,
|
||||
strokeOpacity2: 0.6
|
||||
strokeOpacity2: 0.6,
|
||||
},
|
||||
// {
|
||||
// lng: 38.54,
|
||||
|
@ -67,12 +67,15 @@ export default class Amap2demo extends React.Component {
|
|||
storkeWidth: 2,
|
||||
// strokeOpacity: 0.2,
|
||||
// strokeOpacity: 'strokeOpacity2',
|
||||
strokeOpacity: ['strokeOpacity2', (d: any) => {
|
||||
return d
|
||||
}],
|
||||
strokeOpacity: [
|
||||
'strokeOpacity2',
|
||||
(d: any) => {
|
||||
return d;
|
||||
},
|
||||
],
|
||||
// strokeOpacity: ['opacity2', [0.2, 0.6]],
|
||||
// offsets: [100, 100],
|
||||
opacity: 'opacity2'
|
||||
opacity: 'opacity2',
|
||||
// opacity: 0.2
|
||||
// opacity: ['opacity2', (d: any) => {
|
||||
// return d
|
||||
|
|
Loading…
Reference in New Issue