feat: styles

This commit is contained in:
2912401452 2021-06-16 21:56:24 +08:00
parent 56f6f8fe71
commit ca33c7e268
8 changed files with 157 additions and 122 deletions

View File

@ -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();

View File

@ -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;

View File

@ -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),

View File

@ -83,7 +83,6 @@ export default class DataMappingPlugin implements ILayerPlugin {
// 处理文本更新
layer.emit('remapping', null);
}
});
}
private generateMaping(

View File

@ -31,7 +31,6 @@ export default class UpdateStyleAttributePlugin implements ILayerPlugin {
// });
layer.hooks.beforeRender.tap('UpdateStyleAttributePlugin', () => {
if (layer.layerModelNeedUpdate) {
return;
}

View File

@ -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,
);
},
},
});

View File

@ -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,
};

View File

@ -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