From cb626e6f59f4d531a2117da59a9ab5fb12e4b3ce Mon Sep 17 00:00:00 2001 From: 2912401452 <2912401452@qq.com> Date: Mon, 21 Jun 2021 11:13:18 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=A0=B7=E5=BC=8F=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=98=A0=E5=B0=84=201.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 1 + .../core/src/services/layer/ILayerService.ts | 1 - .../services/shader/ShaderModuleService.ts | 2 + .../src/shaders/styleTextureMapping_frag.glsl | 0 packages/l7/demo/circle.html | 74 ++-- packages/l7/demo/dot.html | 2 +- packages/l7/demo/heatmap.html | 261 +++++++++++++ packages/l7/demo/heatmap3d.html | 87 +++++ packages/l7/demo/image.html | 4 +- packages/l7/demo/text.html | 4 +- packages/l7/demo/text2.html | 80 ++++ packages/layers/src/core/BaseLayer.ts | 28 +- packages/layers/src/core/BaseModel.ts | 53 +++ .../plugins/RegisterStyleAttributePlugin.ts | 40 +- packages/layers/src/point/models/fill.ts | 364 ++++++++++++++---- .../layers/src/point/shaders/fill_frag.glsl | 46 +-- .../layers/src/point/shaders/fill_vert.glsl | 187 ++++++++- packages/layers/src/utils/dataMappingStyle.ts | 231 ++++++++--- packages/renderer/src/regl/ReglModel.ts | 1 - packages/utils/src/color.ts | 4 + stories/Map/components/amap2demo.tsx | 144 +++++-- 21 files changed, 1332 insertions(+), 282 deletions(-) create mode 100644 packages/core/src/shaders/styleTextureMapping_frag.glsl create mode 100644 packages/l7/demo/heatmap.html create mode 100644 packages/l7/demo/heatmap3d.html create mode 100644 packages/l7/demo/text2.html diff --git a/.vscode/settings.json b/.vscode/settings.json index 0db3279e44..595893fc4f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,4 @@ { + "liveServer.settings.port": 5501 } diff --git a/packages/core/src/services/layer/ILayerService.ts b/packages/core/src/services/layer/ILayerService.ts index 0ed0b7b5be..00c59a5706 100644 --- a/packages/core/src/services/layer/ILayerService.ts +++ b/packages/core/src/services/layer/ILayerService.ts @@ -141,7 +141,6 @@ export interface ILayer { scale(field: string | number | IScaleOptions, cfg?: IScale): ILayer; size(field: StyleAttrField, value?: StyleAttributeOption): ILayer; color(field: StyleAttrField, value?: StyleAttributeOption): ILayer; - // opacity(field: StyleAttrField, value?: StyleAttributeOption): ILayer; texture(field: StyleAttrField, value?: StyleAttributeOption): ILayer; shape(field: StyleAttrField, value?: StyleAttributeOption): ILayer; label(field: StyleAttrField, value?: StyleAttributeOption): ILayer; diff --git a/packages/core/src/services/shader/ShaderModuleService.ts b/packages/core/src/services/shader/ShaderModuleService.ts index f35163ab03..b2d9727512 100644 --- a/packages/core/src/services/shader/ShaderModuleService.ts +++ b/packages/core/src/services/shader/ShaderModuleService.ts @@ -12,6 +12,7 @@ import pickingVert from '../../shaders/picking.vert.glsl'; import project from '../../shaders/project.glsl'; import projection from '../../shaders/projection.glsl'; import sdf2d from '../../shaders/sdf_2d.glsl'; +// import styleTextureMapping_frag from '../../shaders/styleTextureMapping_frag.glsl' const precisionRegExp = /precision\s+(high|low|medium)p\s+float/; const globalDefaultprecision = @@ -33,6 +34,7 @@ export default class ShaderModuleService implements IShaderModuleService { this.registerModule('lighting', { vs: lighting, fs: '' }); this.registerModule('light', { vs: light, fs: '' }); this.registerModule('picking', { vs: pickingVert, fs: pickingFrag }); + // this.registerModule('styleTextureMapping_frag', { vs: '', fs: styleTextureMapping_frag }); } public registerModule(moduleName: string, moduleParams: IModuleParams) { diff --git a/packages/core/src/shaders/styleTextureMapping_frag.glsl b/packages/core/src/shaders/styleTextureMapping_frag.glsl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/l7/demo/circle.html b/packages/l7/demo/circle.html index 711578b928..70eacb0edc 100644 --- a/packages/l7/demo/circle.html +++ b/packages/l7/demo/circle.html @@ -30,10 +30,16 @@ + + + + + + diff --git a/packages/l7/demo/heatmap3d.html b/packages/l7/demo/heatmap3d.html new file mode 100644 index 0000000000..b98d749e31 --- /dev/null +++ b/packages/l7/demo/heatmap3d.html @@ -0,0 +1,87 @@ + + + + + L7 IE + + + + +
+ + + + + + + + diff --git a/packages/l7/demo/image.html b/packages/l7/demo/image.html index 2f7cf40075..ebc1db0330 100644 --- a/packages/l7/demo/image.html +++ b/packages/l7/demo/image.html @@ -33,8 +33,8 @@ console.log(L7); const scene = new L7.Scene({ id: "map", - map: new L7.Mapbox({ - style: "blank", // 样式URL + map: new L7.GaodeMap({ + style: "dark", // 样式URL center: [108.6167, 19.1000], pitch: 0, zoom: 6 diff --git a/packages/l7/demo/text.html b/packages/l7/demo/text.html index 9f650012bb..4a2588ea13 100644 --- a/packages/l7/demo/text.html +++ b/packages/l7/demo/text.html @@ -27,12 +27,12 @@ - + + + + + + + diff --git a/packages/layers/src/core/BaseLayer.ts b/packages/layers/src/core/BaseLayer.ts index 34e353fe7e..5614eb799e 100644 --- a/packages/layers/src/core/BaseLayer.ts +++ b/packages/layers/src/core/BaseLayer.ts @@ -52,10 +52,7 @@ 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 { handleStyleDataMapping } from '../utils/dataMappingStyle'; import baseLayerSchema from './schema'; /** * 分配 layer id @@ -210,21 +207,10 @@ export default class BaseLayer extends EventEmitter }; } else { const sceneId = this.container.get(TYPES.SceneID); + // @ts-ignore - if (configToUpdate.opacity) { - // @ts-ignore - handleStyleOpacity('opacity', this, configToUpdate.opacity); - } - // @ts-ignore - if (configToUpdate.strokeOpacity) { - // @ts-ignore - handleStyleStrokeOpacity( - 'strokeOpacity', - this, - // @ts-ignore - configToUpdate.strokeOpacity, - ); - } + handleStyleDataMapping(configToUpdate, this); // 处理 style 中进行数据映射的属性字段 + this.configService.setLayerConfig(sceneId, this.id, { ...this.configService.getLayerConfig(this.id), ...this.needUpdateConfig, @@ -1024,6 +1010,12 @@ export default class BaseLayer extends EventEmitter valuesOrCallback?: unknown[], defaultValues?: unknown[], ) { + // console.log({ + // values: isFunction(valuesOrCallback) + // ? undefined + // : valuesOrCallback || defaultValues, + // callback: isFunction(valuesOrCallback) ? valuesOrCallback : undefined, + // }) return { values: isFunction(valuesOrCallback) ? undefined diff --git a/packages/layers/src/core/BaseModel.ts b/packages/layers/src/core/BaseModel.ts index 0ef4a7c8dc..025cd08567 100644 --- a/packages/layers/src/core/BaseModel.ts +++ b/packages/layers/src/core/BaseModel.ts @@ -18,15 +18,41 @@ import { IRendererService, IShaderModuleService, IStyleAttributeService, + ITexture2D, + ITexture2DInitializationOptions, lazyInject, Triangulation, TYPES, } from '@antv/l7-core'; import { BlendTypes } from '../utils/blend'; +import { getSize } from '../utils/dataMappingStyle'; + +interface IDataLayout { + widthCount: number; + heightCount: number; + widthStep: number; + widthStart: number; + heightStep: number; + heightStart: number; +} export default class BaseModel implements ILayerModel { public triangulation: Triangulation; + // style texture data mapping + public createTexture2D: ( + options: ITexture2DInitializationOptions, + ) => ITexture2D; + public dataLayout: IDataLayout = { + // 默认值 + widthCount: 1024, + heightCount: 1, + widthStep: 1 / 1024, + widthStart: 1 / 2048, + heightStep: 1, + heightStart: 0.5, + }; + protected layer: ILayer; @lazyInject(TYPES.IGlobalConfigService) @@ -49,6 +75,12 @@ export default class BaseModel protected cameraService: ICameraService; protected layerService: ILayerService; + protected opacityTexture: ITexture2D; + protected strokeOpacityTexture: ITexture2D; + protected strokeTexture: ITexture2D; + protected strokeWidthTexture: ITexture2D; + // style texture data mapping + constructor(layer: ILayer) { this.layer = layer; this.rendererService = layer @@ -75,7 +107,28 @@ export default class BaseModel this.registerBuiltinAttributes(); // 开启动画 this.startModelAnimate(); + + const { createTexture2D } = this.rendererService; + this.createTexture2D = createTexture2D; + // 根据数据长度构建样式数据映射到纹理上时需要到布局数值 为纹理贴图映射样式数据做准备工作 + this.initEncodeDataLayout(this.layer.getEncodedData().length); } + + /** + * 根据数据长度构建样式数据映射到纹理上时需要到布局数值 + * @param dataLength + */ + public initEncodeDataLayout(dataLength: number) { + 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; + } + public getBlend(): IBlendOptions { const { blend = 'normal' } = this.layer.getLayerConfig(); return BlendTypes[BlendType[blend]] as IBlendOptions; diff --git a/packages/layers/src/plugins/RegisterStyleAttributePlugin.ts b/packages/layers/src/plugins/RegisterStyleAttributePlugin.ts index 7eadb5e9c3..bbf7096987 100644 --- a/packages/layers/src/plugins/RegisterStyleAttributePlugin.ts +++ b/packages/layers/src/plugins/RegisterStyleAttributePlugin.ts @@ -91,25 +91,25 @@ export default class RegisterStyleAttributePlugin implements ILayerPlugin { }, }, }); - styleAttributeService.registerStyleAttribute({ - name: 'strokeOpacity', - type: AttributeType.Attribute, - descriptor: { - name: 'a_stroke_opacity', - 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) => { - const { strokeOpacity } = feature; - // console.log('feature', feature) - // console.log('strokeOpacity', strokeOpacity) - return !isNumber(strokeOpacity) ? [1.0] : [strokeOpacity]; - }, - }, - }); + // styleAttributeService.registerStyleAttribute({ + // name: 'strokeOpacity', + // type: AttributeType.Attribute, + // descriptor: { + // name: 'a_stroke_opacity', + // 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) => { + // const { strokeOpacity } = feature; + // // console.log('feature', feature) + // // console.log('strokeOpacity', strokeOpacity) + // return !isNumber(strokeOpacity) ? [1.0] : [strokeOpacity]; + // }, + // }, + // }); } } diff --git a/packages/layers/src/point/models/fill.ts b/packages/layers/src/point/models/fill.ts index 85294ea5fb..73ede0660f 100644 --- a/packages/layers/src/point/models/fill.ts +++ b/packages/layers/src/point/models/fill.ts @@ -10,18 +10,18 @@ import { IModelUniform, ITexture2D, } from '@antv/l7-core'; -import { rgb2arr } from '@antv/l7-utils'; +import { isColor, rgb2arr } from '@antv/l7-utils'; import BaseModel from '../../core/BaseModel'; import { PointFillTriangulation } from '../../core/triangulation'; import pointFillFrag from '../shaders/fill_frag.glsl'; import pointFillVert from '../shaders/fill_vert.glsl'; -import { isNumber } from 'lodash'; +import { isArray, isNumber, isString } from 'lodash'; import { getSize, getUvPosition, - initDefaultTextureData, - initTextureData, + initTextureFloatData, + initTextureVec4Data, } from '../../utils/dataMappingStyle'; interface IPointLayerStyleOptions { opacity: any; @@ -31,65 +31,279 @@ interface IPointLayerStyleOptions { offsets: [number, number]; } -interface IDataLayout { - widthCount: number; - heightCount: number; - widthStep: number; - widthStart: number; - heightStep: number; - heightStart: number; -} - // 用于判断 opacity 的值是否发生该改变 -let curretnOpacity: any = ''; -let curretnStrokeOpacity: any = ''; +const curretnOpacity: any = ''; +const curretnStrokeOpacity: any = ''; +const currentStrokeColor: any = ''; +const currentStrokeWidth: any = ''; +let testTexture = true; + +const cellPropertiesLayout = [ + { attr: 'opacity', flag: true, count: 1 }, + { attr: 'strokeOpacity', flag: true, count: 1 }, + { attr: 'strokeWidth', flag: true, count: 1 }, + { attr: 'stroke', flag: true, count: 4 }, +]; + +const WIDTH = 1024; // 数据纹理的固定长度 +// let WIDTH = 10 +let calHeight = 1; +/** + * 根据映射的数据字段往推入数据 + * @param d + * @param cellData + * @param cellPropertiesLayouts + */ +function patchData(d: number[], cellData: any, cellPropertiesLayouts: any) { + for (const layout of cellPropertiesLayouts) { + const { attr, count } = layout; + if (!cellData) { + if (attr === 'stroke') { + d.push(-1, -1, -1, -1); + } else if (attr === 'offsets') { + d.push(-1, -1); + } else { + d.push(-1); + } + } else { + const value = cellData[attr]; + + if (value) { + // 数据中存在该属性 + if (attr === 'stroke') { + d.push(...rgb2arr(value)); + } else if (attr === 'offsets') { + // d.push(...value) + d.push(-value[0], value[1]); + } else { + d.push(value); + } + } else { + // 若不存在时则补位 + patchMod(d, count); + } + } + } +} +/** + * 补空位 + * @param d + * @param count + */ +function patchMod(d: number[], count: number) { + for (let i = 0; i < count; i++) { + d.push(-1); + } +} +/** + * 计算推入数据纹理的数据 + * @param cellLength + * @param encodeData + * @param cellPropertiesLayouts + * @returns + */ +function calDataFrame( + cellLength: number, + encodeData: any, + cellPropertiesLayouts: any, +): any { + if (cellLength > WIDTH) { + // console.log('failed'); + return false; + } + + const encodeDatalength = encodeData.length; + // WIDTH 行数固定 + const rowCount = Math.ceil((encodeDatalength * cellLength) / WIDTH); // 有多少行 + + const totalLength = rowCount * WIDTH; + const d: number[] = []; + for (let i = 0; i < encodeDatalength; i++) { + // 根据 encodeData 数据推入数据 + const cellData = encodeData[i]; + patchData(d, cellData, cellPropertiesLayouts); + } + for (let i = d.length; i < totalLength; i++) { + // 每行不足的部分用 -1 补足(数据纹理时 width * height 的矩形数据集合) + d.push(-1); + } + // console.log(d, rowCount) + return { data: d, width: WIDTH, height: rowCount }; +} +// 判断当前使用的 style 中的变量属性是否需要进行数据映射 +let hasOpacity = 0; +let hasStrokeOpacity = 0; +let hasStrokeWidth = 0; +let hasStroke = 0; +let hasOffsets = 0; export default class FillModel extends BaseModel { - public dataLayout: IDataLayout = { - // 默认值 - widthCount: 1024, - heightCount: 1, - widthStep: 1 / 1024, - widthStart: 1 / 2048, - heightStep: 1, - heightStart: 0.5, - }; + protected testDataTexture: ITexture2D; - protected opacityTexture: ITexture2D; + /** + * 判断 offsets 是否是常量 + * @param offsets + * @returns + */ + public isOffsetStatic(offsets: any) { + if ( + isArray(offsets) && + offsets.length === 2 && + isNumber(offsets[0]) && + isNumber(offsets[1]) + ) { + return true; + } else { + return false; + } + } + + public isColorStatic(stroke: any) { + if ( + isArray(stroke) && + stroke.length === 4 && + isNumber(stroke[0]) && + isNumber(stroke[1]) && + isNumber(stroke[2]) && + isNumber(stroke[3]) + ) { + return true; + } else { + return false; + } + } public getUninforms(): IModelUniform { const { - opacity, - stroke = 'rgb(0,0,0,0)', - strokeWidth = 1, + opacity = 1, strokeOpacity = 1, + strokeWidth = 2, + stroke = [0, 0, 0, 0], offsets = [0, 0], } = this.layer.getLayerConfig() as IPointLayerStyleOptions; - if (curretnOpacity !== JSON.stringify(opacity)) { - const { createTexture2D } = this.rendererService; - // 从 encodeData 数据的 opacity 字段上取值,并将值按照排布写入到纹理中 - this.opacityTexture = initTextureData( - this.dataLayout.heightCount, - createTexture2D, - this.layer.getEncodedData(), - 'opacity', - ); + if (testTexture) { + const cellProperties = []; // cell 的布局 + let cellLength = 0; // cell 的长度 - curretnOpacity = JSON.stringify(opacity); - } + if (!isNumber(opacity) && opacity !== undefined) { + // 数据映射 + cellProperties.push({ attr: 'opacity', flag: true, count: 1 }); + hasOpacity = 1; + cellLength += 1; + } else { + // 常量 + hasOpacity = 0; + } - if (curretnStrokeOpacity !== JSON.stringify(strokeOpacity)) { - curretnStrokeOpacity = JSON.stringify(strokeOpacity); + if (!isNumber(strokeOpacity) && strokeOpacity !== undefined) { + // 数据映射 + cellProperties.push({ attr: 'strokeOpacity', flag: true, count: 1 }); + hasStrokeOpacity = 1; + cellLength += 1; + } else { + // 常量 + hasStrokeOpacity = 0; + } + + if (!isNumber(strokeWidth) && strokeWidth !== undefined) { + // 数据映射 + cellProperties.push({ attr: 'strokeWidth', flag: true, count: 1 }); + hasStrokeWidth = 1; + cellLength += 1; + } else { + // 常量 + hasStrokeWidth = 0; + } + // console.log('stroke', stroke); + // if((!isString(stroke) || !isColor(stroke)) && stroke !== undefined) { // 数据映射 + if (!this.isColorStatic(stroke)) { + // 数据映射 + cellProperties.push({ attr: 'stroke', flag: true, count: 4 }); + cellLength += 4; + hasStroke = 1; + } else { + // 常量 + hasStroke = 0; + } + + if (!this.isOffsetStatic(offsets)) { + cellProperties.push({ attr: 'offsets', flag: true, count: 2 }); + cellLength += 2; + hasOffsets = 1; + } else { + hasOffsets = 0; + } + + // console.log('cellProperties', cellProperties); + // console.log('cellLength', cellLength); + // console.log('hasStrokeOpacity', hasStrokeOpacity) + // console.log('hasStrokeWidth', hasStrokeWidth) + + const encodeData = this.layer.getEncodedData(); + // console.log('encodeData', encodeData) + // let {data, width, height } = calDataFrame(cellLength, encodeData, cellPropertiesLayout) + if (cellLength > 0) { + const { data, width, height } = calDataFrame( + cellLength, + encodeData, + cellProperties, + ); + calHeight = height; + + this.testDataTexture = this.createTexture2D({ + flipY: true, + data, + format: gl.LUMINANCE, + type: gl.FLOAT, + width, + height, + }); + } else { + this.testDataTexture = this.createTexture2D({ + flipY: true, + data: [1], + format: gl.LUMINANCE, + type: gl.FLOAT, + width: 1, + height: 1, + }); + } + + // console.log('strokeOpacity', strokeOpacity, isNumber(strokeOpacity)? strokeOpacity : 1.0) + testTexture = false; } return { - u_opacity_texture: this.opacityTexture, - u_opacity: opacity ? -1.0 : 1.0, - u_stroke_width: strokeWidth, - u_stroke_color: rgb2arr(stroke), + u_testTexture: this.testDataTexture, // 数据纹理 - 有数据映射的时候纹理中带数据,若没有任何数据映射时纹理是 [1] + u_cellTypeLayout: [ + // 传递样式数据映射信息 - 当前纹理大小以及有哪些字段需要映射 + calHeight, + WIDTH, + 0.0, + 0.0, // rowCount columnCount - 几行几列 + hasOpacity, + hasStrokeOpacity, + hasStrokeWidth, + hasStroke, // opacity strokeOpacity strokeWidth stroke + hasOffsets, + 0.0, + 0.0, + 0.0, // offsets + 0.0, + 0.0, + 0.0, + 0.0, + ], + + u_opacity: isNumber(opacity) ? opacity : 1.0, u_stroke_opacity: isNumber(strokeOpacity) ? strokeOpacity : 1.0, - u_offsets: [-offsets[0], offsets[1]], + u_stroke_width: isNumber(strokeWidth) ? strokeWidth : 0.0, + u_stroke_color: + isString(stroke) && isColor(stroke) ? rgb2arr(stroke) : [0, 0, 0, 0], + u_offsets: this.isOffsetStatic(offsets) + ? [-offsets[0], offsets[1]] + : [0, 0], }; } public getAnimateUniforms(): IModelUniform { @@ -112,22 +326,40 @@ export default class FillModel extends BaseModel { ); } - public initEncodeDataLayout(dataLength: number) { - 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; - } - public initModels(): IModel[] { - this.initEncodeDataLayout(this.layer.getEncodedData().length); + // if(cellLength < 1) { + // console.log('err') + // } + // let encodeData = this.layer.getEncodedData() + // dataFrameArr = [] + + // let mod = WIDTH%cellLength + // let rowCellCount = (WIDTH-mod)/cellLength + // let encodeDatalength = encodeData.length + // let heightCount = Math.ceil(encodeDatalength * cellLength / (WIDTH - mod)) + + // let heightStep = 1/heightCount + // let heightStart = heightStep/2 + // let widthStart = (1/WIDTH)/2 + // let widthStep = (1/WIDTH) * (cellLength - 1.0) + + // for(let i = 0; i < heightCount; i++) { // 行 + // for(let j = 0; j < rowCellCount; j++) { + + // let startU = widthStart + widthStep * j + // let startV = 1 - (heightStart + heightStep * i) + // let endU = startU + widthStep + // let endV = startV + + // dataFrameArr.push({ startU, startV, endU, endV }) + + // } + // } + // console.log('dataFrameArr', dataFrameArr) return this.buildModels(); } + public buildModels(): IModel[] { return [ this.layer.buildLayerModel({ @@ -195,32 +427,26 @@ export default class FillModel extends BaseModel { }, }); - // point feature id + // vertex id 用于作为数据纹理取值的唯一编号 this.styleAttributeService.registerStyleAttribute({ - name: 'featureId', + name: 'vertexId', type: AttributeType.Attribute, descriptor: { - name: 'a_featureId', + name: 'a_vertexId', buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, data: [], type: gl.FLOAT, }, - size: 2, + size: 1, update: ( feature: IEncodeFeature, featureIdx: number, vertex: number[], attributeIdx: number, ) => { - return getUvPosition( - this.dataLayout.widthStep, - this.dataLayout.widthStart, - this.dataLayout.heightStep, - this.dataLayout.heightStart, - featureIdx, - ); + return [featureIdx]; }, }, }); diff --git a/packages/layers/src/point/shaders/fill_frag.glsl b/packages/layers/src/point/shaders/fill_frag.glsl index 9c81d88913..2ca23d81a7 100644 --- a/packages/layers/src/point/shaders/fill_frag.glsl +++ b/packages/layers/src/point/shaders/fill_frag.glsl @@ -1,14 +1,9 @@ #define Animate 0.0 uniform float u_blur : 0; -uniform float u_opacity : 1; -uniform float u_stroke_width : 1; -uniform vec4 u_stroke_color : [0, 0, 0, 0]; -uniform float u_stroke_opacity : 1; -varying float v_stroke_opacity; +// uniform float u_stroke_width : 1; -uniform sampler2D u_opacity_texture; -varying vec2 v_featureId; +varying mat4 styleMappingMat; // 传递从片元中传递的映射数据 varying vec4 v_data; varying vec4 v_color; @@ -19,23 +14,27 @@ uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ]; #pragma include "sdf_2d" #pragma include "picking" + void main() { int shape = int(floor(v_data.w + 0.5)); - // 处理透明度 - // float opacity = texture2D(u_opacity_texture, v_featureId).a?texture2D(u_opacity_texture, v_featureId).a:1.0; - float opacity = u_opacity; - if(u_opacity < 0.0) { - opacity = texture2D(u_opacity_texture, v_featureId).a; - } - float stroke_opacity = u_stroke_opacity; - if(v_stroke_opacity > 0.0) { - stroke_opacity = v_stroke_opacity; - } + + vec4 textrueStroke = vec4( + styleMappingMat[1][0], + styleMappingMat[1][1], + styleMappingMat[1][2], + styleMappingMat[1][3] + ); + + float opacity = styleMappingMat[0][0]; + float stroke_opacity = styleMappingMat[0][1]; + float strokeWidth = styleMappingMat[0][2]; + vec4 strokeColor = textrueStroke == vec4(0) ? v_color : textrueStroke; lowp float antialiasblur = v_data.z; float antialiased_blur = -max(u_blur, antialiasblur); - float r = v_radius / (v_radius + u_stroke_width); + // float r = v_radius / (v_radius + u_stroke_width); + float r = v_radius / (v_radius + strokeWidth); float outer_df; float inner_df; @@ -70,18 +69,20 @@ void main() { } float opacity_t = smoothstep(0.0, antialiased_blur, outer_df); - float color_t = u_stroke_width < 0.01 ? 0.0 : smoothstep( + // float color_t = u_stroke_width < 0.01 ? 0.0 : smoothstep( + // antialiased_blur, + // 0.0, + // inner_df + // ); + float color_t = strokeWidth < 0.01 ? 0.0 : smoothstep( antialiased_blur, 0.0, inner_df ); - vec4 strokeColor = u_stroke_color == vec4(0) ? v_color : u_stroke_color; float PI = 3.14159; float N_RINGS = 3.0; float FREQ = 1.0; - // gl_FragColor = v_color * color_t; - // gl_FragColor = mix(vec4(v_color.rgb, v_color.a * u_opacity), strokeColor * u_stroke_opacity, color_t); gl_FragColor = mix(vec4(v_color.rgb, v_color.a * opacity), strokeColor * stroke_opacity, color_t); @@ -94,5 +95,4 @@ void main() { gl_FragColor = filterColor(gl_FragColor); - } diff --git a/packages/layers/src/point/shaders/fill_vert.glsl b/packages/layers/src/point/shaders/fill_vert.glsl index 147dd756c6..20f94b24e7 100644 --- a/packages/layers/src/point/shaders/fill_vert.glsl +++ b/packages/layers/src/point/shaders/fill_vert.glsl @@ -2,36 +2,200 @@ attribute vec4 a_Color; attribute vec3 a_Position; attribute vec2 a_Extrude; attribute float a_Size; -attribute float a_stroke_opacity; attribute float a_Shape; -attribute vec2 a_featureId; -varying vec2 v_featureId; +attribute float a_vertexId; +uniform mat4 u_cellTypeLayout; +uniform sampler2D u_testTexture; +varying mat4 styleMappingMat; uniform mat4 u_ModelMatrix; uniform mat4 u_Mvp; -uniform float u_stroke_width : 2; -uniform vec2 u_offsets; - varying vec4 v_data; varying vec4 v_color; varying float v_radius; -varying float v_stroke_opacity; + +uniform float u_opacity : 1; +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]; +uniform vec2 u_offsets; + #pragma include "projection" #pragma include "picking" + +/* + currentRow 当前行 + currentColumn 当前列 + columnCount 有多少列 + nextStep 需要计算当前 cell 后的第几个 cell (当前 cell 则 nextStep = 0) +*/ +vec2 nextPos(float currentRow, float currentColumn, float columnCount, float nextStep) { + float nextColumn = currentColumn; + float nextRow = currentRow; + if(currentColumn + nextStep <= columnCount){ + nextColumn = currentColumn + nextStep; + } else { + nextColumn = mod(currentColumn + nextStep, columnCount); // 不会出现跨两行 + nextRow = currentRow + 1.0; + } + return vec2(nextColumn, nextRow); +} + +// 根据坐标位置先是计算 uv ,然后根据 uv 从数据纹理中取值 +float pos2value(vec2 pos, float columnWidth, float rowHeight) { + float u = (pos.r - 1.0) * columnWidth + columnWidth/2.0; + float v = 1.0 - ((pos.g - 1.0) * rowHeight + rowHeight/2.0); + return texture2D(u_testTexture, vec2(u, v)).r; +} + +bool hasOpacity() { // 判断 cell 中是否存在 opacity 的数据 + return u_cellTypeLayout[1][0] > 0.0; +} + +bool hasStrokeOpacity() { // 判断 cell 中是否存在 strokeOpacity 的数据 + return u_cellTypeLayout[1][1] > 0.0; +} + +bool hasStrokeWidth() { // 判断 cell 中是否存在 strokeWidth 的数据 + return u_cellTypeLayout[1][2] > 0.0; +} + +bool hasStroke() { // 判断 cell 中是否存在 stroke 的数据 + return u_cellTypeLayout[1][3] > 0.0; +} + +bool hasOffsets() { // 判断 cell 中是否存在 offsets 的数据 + return u_cellTypeLayout[2][0] > 0.0; +} + +// 计算 opacity 和标志在 cell 中取值用的 offset +vec2 calOpacityAndOffset(float cellCurrentRow, float cellCurrentColumn, float columnCount, float textureOffset, float columnWidth, float rowHeight) { + if(!hasOpacity()) { // 数据纹理中不存在 opacity 的时候取默认值(用户在 style 中传入的是常量) + return vec2(u_opacity, textureOffset); + } else { + vec2 valuePos = nextPos(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset); + float textureOpacity = pos2value(valuePos, columnWidth, rowHeight); + return vec2(textureOpacity, textureOffset + 1.0); + } +} + +vec2 calStrokeOpacityAndOffset(float cellCurrentRow, float cellCurrentColumn, float columnCount, float textureOffset, float columnWidth, float rowHeight) { + if(!hasStrokeOpacity()) { + return vec2(u_stroke_opacity, textureOffset); + } else { + vec2 valuePos = nextPos(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset); + float textureStrokeOpacity = pos2value(valuePos, columnWidth, rowHeight); + return vec2(textureStrokeOpacity, textureOffset + 1.0); + } +} + +vec2 calStrokeWidthAndOffset(float cellCurrentRow, float cellCurrentColumn, float columnCount, float textureOffset, float columnWidth, float rowHeight) { + if(!hasStrokeWidth()) { + return vec2(u_stroke_width, textureOffset); + } else { + vec2 valuePos = nextPos(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset); + float textureStrokeWidth = pos2value(valuePos, columnWidth, rowHeight); + return vec2(textureStrokeWidth, textureOffset + 1.0); + } +} + +float calCellCount() { // 计算当前单个 cell 的大小 + // u_cellTypeLayout + // cal_height, WIDTH, 0.0, 0.0, // rowCount columnCount - 几行几列 + // 1.0, 1.0, 1.0, 0.0, // opacity strokeOpacity strokeWidth stroke - 1.0 表示有数据映射、0.0 表示没有 + // 1.0, 0.0, 0.0, 0.0, // offsets + // 0.0, 0.0, 0.0, 0.0 + + return u_cellTypeLayout[1][0] + // opacity + u_cellTypeLayout[1][1] + // strokeOpacity + u_cellTypeLayout[1][2] + // strokeWidth + u_cellTypeLayout[1][3] * 4.0 + // stroke + u_cellTypeLayout[2][0] * 2.0; // offsets +} + void main() { vec2 extrude = a_Extrude; float shape_type = a_Shape; float newSize = setPickingSize(a_Size); + // cal style mapping - 数据纹理映射部分的计算 + styleMappingMat = mat4( + 0.0, 0.0, 0.0, 0.0, // opacity - strokeOpacity - strokeWidth - empty + 0.0, 0.0, 0.0, 0.0, // strokeR - strokeG - strokeB - strokeA + 0.0, 0.0, 0.0, 0.0, // offsets[0] - offsets[1] + 0.0, 0.0, 0.0, 0.0 + ); + + float rowCount = u_cellTypeLayout[0][0]; // 当前的数据纹理有几行 + float columnCount = u_cellTypeLayout[0][1]; // 当看到数据纹理有几列 + float columnWidth = 1.0/columnCount; // 列宽 + float rowHeight = 1.0/rowCount; // 行高 + float cellCount = calCellCount(); // opacity - strokeOpacity - strokeWidth - stroke - offsets + float id = a_vertexId; // 第n个顶点 + float cellCurrentRow = floor(id * cellCount / columnCount) + 1.0; // 起始点在第几行 + float cellCurrentColumn = mod(id * cellCount, columnCount) + 1.0; // 起始点在第几列 + + // cell 固定顺序 opacity -> strokeOpacity -> strokeWidth -> stroke ... + // 按顺序从 cell 中取值、若没有则自动往下取值 + float textureOffset = 0.0; // 在 cell 中取值的偏移量 + + vec2 opacityAndOffset = calOpacityAndOffset(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset, columnWidth, rowHeight); + styleMappingMat[0][0] = opacityAndOffset.r; + textureOffset = opacityAndOffset.g; + + vec2 strokeOpacityAndOffset = calStrokeOpacityAndOffset(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset, columnWidth, rowHeight); + styleMappingMat[0][1] = strokeOpacityAndOffset.r; + textureOffset = strokeOpacityAndOffset.g; + + vec2 strokeWidthAndOffset = calStrokeWidthAndOffset(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset, columnWidth, rowHeight); + styleMappingMat[0][2] = strokeWidthAndOffset.r; + textureOffset = strokeWidthAndOffset.g; + + vec4 textrueStroke = vec4(-1.0, -1.0, -1.0, -1.0); + if(hasStroke()) { + vec2 valueRPos = nextPos(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset); + styleMappingMat[1][0] = pos2value(valueRPos, columnWidth, rowHeight); // R + textureOffset += 1.0; + + vec2 valueGPos = nextPos(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset); + styleMappingMat[1][1] = pos2value(valueGPos, columnWidth, rowHeight); // G + textureOffset += 1.0; + + vec2 valueBPos = nextPos(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset); + styleMappingMat[1][2] = pos2value(valueBPos, columnWidth, rowHeight); // B + textureOffset += 1.0; + + vec2 valueAPos = nextPos(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset); + styleMappingMat[1][3] = pos2value(valueAPos, columnWidth, rowHeight); // A + textureOffset += 1.0; + } else { + styleMappingMat[1][0] = u_stroke_color.r; + styleMappingMat[1][1] = u_stroke_color.g; + styleMappingMat[1][2] = u_stroke_color.b; + styleMappingMat[1][3] = u_stroke_color.a; + } + + vec2 textrueOffsets = vec2(0.0, 0.0); + if(hasOffsets()) { + vec2 valueXPos = nextPos(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset); + textrueOffsets.r = pos2value(valueXPos, columnWidth, rowHeight); // x + textureOffset += 1.0; + + vec2 valueYPos = nextPos(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset); + textrueOffsets.g = pos2value(valueYPos, columnWidth, rowHeight); // x + textureOffset += 1.0; + } else { + textrueOffsets = u_offsets; + } + + // cal style mapping + // unpack color(vec2) v_color = a_Color; - v_stroke_opacity = a_stroke_opacity; - - v_featureId = a_featureId; // radius(16-bit) v_radius = newSize; @@ -43,7 +207,8 @@ void main() { // construct point coords v_data = vec4(extrude, antialiasblur,shape_type); - vec2 offset = project_pixel(extrude * (newSize + u_stroke_width) + u_offsets); + // vec2 offset = project_pixel(extrude * (newSize + u_stroke_width) + u_offsets); + vec2 offset = project_pixel(extrude * (newSize + u_stroke_width) + textrueOffsets); vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0)); // gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, project_pixel(setPickingOrder(0.0)), 1.0)); diff --git a/packages/layers/src/utils/dataMappingStyle.ts b/packages/layers/src/utils/dataMappingStyle.ts index 4c6ba84496..7d74e081ea 100644 --- a/packages/layers/src/utils/dataMappingStyle.ts +++ b/packages/layers/src/utils/dataMappingStyle.ts @@ -1,15 +1,25 @@ import { + gl, ILayer, IStyleAttributeUpdateOptions, ITexture2D, StyleAttributeField, StyleAttributeOption, } from '@antv/l7-core'; +import { rgb2arr } from '@antv/l7-utils'; import { isArray, isFunction, isNumber, isString } from 'lodash'; /** * 该文件中的工具方法主要用于对 style 中的属性进行 数据映射 */ +interface IConfigToUpdate { + opacity?: any; + strokeOpacity?: any; + stroke?: any; + strokeWidth?: any; + offsets?: any; +} + // 画布默认的宽度 const WIDTH = 1024; @@ -19,7 +29,7 @@ const WIDTH = 1024; * @param values * @param updateOptions */ -function registerOpacityAttribute( +function registerStyleAttribute( fieldName: string, layer: ILayer, field: StyleAttributeField, @@ -29,47 +39,122 @@ function registerOpacityAttribute( layer.updateStyleAttribute(fieldName, field, values, updateOptions); } -/** - * 根据传入参数 opacity 的类型和值做相应的操作 - */ -function handleStyleOpacity(fieldName: string, layer: ILayer, opacity: any) { - if (isString(opacity)) { - // opacity = 'string' - registerOpacityAttribute(fieldName, layer, opacity, (value: any) => { - return value; - }); - } else if (isNumber(opacity)) { - // opacity = 0.4 -> opacity 传入数字 - registerOpacityAttribute(fieldName, layer, [opacity], undefined); - } else if (isArray(opacity) && opacity.length === 2) { - if (isString(opacity[0]) && isFunction(opacity[1])) { - // opacity = ['string', callback] - registerOpacityAttribute(fieldName, layer, opacity[0], opacity[1]); - } else if ( - isString(opacity[0]) && - isArray(opacity[1]) && - isNumber(opacity[1][0]) && - isNumber(opacity[1][1]) - ) { - // opacity = ['string', [start: number, end: nuber]] - registerOpacityAttribute(fieldName, layer, opacity[0], opacity[1]); - } else { - registerOpacityAttribute(fieldName, layer, [1.0], undefined); - } - } else { - registerOpacityAttribute(fieldName, layer, [1.0], undefined); +function handleStyleDataMapping(configToUpdate: IConfigToUpdate, layer: any) { + if (configToUpdate.opacity) { + // 处理 style 中 opacity 属性的数据映射 + + handleStyleFloat('opacity', layer, configToUpdate.opacity); + } + + if (configToUpdate.strokeWidth) { + // 处理 style 中 strokeWidth 属性的数据映射 + + handleStyleFloat('strokeWidth', layer, configToUpdate.strokeWidth); + } + + if (configToUpdate.strokeOpacity) { + // 处理 style 中 strokeOpacity 属性的数据映射 + + handleStyleFloat('strokeOpacity', layer, configToUpdate.strokeOpacity); + } + + if (configToUpdate.stroke) { + // 处理 style 中 stroke (strokeColor) 属性的数据映射 + handleStyleColor('stroke', layer, configToUpdate.stroke); + } + + if (configToUpdate.offsets) { + handleStyleOffsets('offsets', layer, configToUpdate.offsets); } } /** - * 根据传入参数 strokeOpacity 的类型和值做相应的操作 + * 根据传入参数 opacity 的类型和值做相应的操作 */ -function handleStyleStrokeOpacity( +function handleStyleFloat(fieldName: string, layer: ILayer, styleFloat: any) { + if (isString(styleFloat)) { + // opacity = 'string' + registerStyleAttribute(fieldName, layer, styleFloat, (value: any) => { + return value; + }); + } else if (isNumber(styleFloat)) { + // opacity = 0.4 -> opacity 传入数字 + registerStyleAttribute(fieldName, layer, [styleFloat], undefined); + } else if (isArray(styleFloat) && styleFloat.length === 2) { + if (isString(styleFloat[0]) && isFunction(styleFloat[1])) { + // opacity = ['string', callback] + registerStyleAttribute(fieldName, layer, styleFloat[0], styleFloat[1]); + } else if ( + isString(styleFloat[0]) && + isArray(styleFloat[1]) && + isNumber(styleFloat[1][0]) && + isNumber(styleFloat[1][1]) + ) { + // opacity = ['string', [start: number, end: nuber]] + registerStyleAttribute(fieldName, layer, styleFloat[0], styleFloat[1]); + } else { + registerStyleAttribute(fieldName, layer, [1.0], undefined); + } + } else { + registerStyleAttribute(fieldName, layer, [1.0], undefined); + } +} + +function handleStyleOffsets( fieldName: string, layer: ILayer, - strokeOpacity: any, + styleOffsets: any, ) { - handleStyleOpacity(fieldName, layer, strokeOpacity); + if (isString(styleOffsets)) { + // 字符串 + registerStyleAttribute(fieldName, layer, styleOffsets, (value: any) => { + return value; + }); + } else if ( + isArray(styleOffsets) && + styleOffsets.length === 2 && + isString(styleOffsets[0]) && + isFunction(styleOffsets[1]) + ) { + // callback + registerStyleAttribute(fieldName, layer, styleOffsets[0], styleOffsets[1]); + } else if ( + isArray(styleOffsets) && + styleOffsets.length === 2 && + isNumber(styleOffsets[0]) && + isNumber(styleOffsets[1]) + ) { + // normal + registerStyleAttribute(fieldName, layer, styleOffsets, undefined); + } else { + registerStyleAttribute(fieldName, layer, [0, 0], undefined); + } +} + +/** + * 根据传入参数 stroke / color 的类型和值做相应的操作 + * @param fieldName + * @param layer + * @param styleColor + */ +function handleStyleColor(fieldName: string, layer: ILayer, styleColor: any) { + if (isString(styleColor)) { + registerStyleAttribute(fieldName, layer, styleColor, undefined); + } else if (isArray(styleColor) && styleColor.length === 2) { + if (isString(styleColor[0]) && isFunction(styleColor[1])) { + registerStyleAttribute(fieldName, layer, styleColor[0], styleColor[1]); + } else if ( + isString(styleColor[0]) && + isArray(styleColor[1]) && + styleColor[1].length > 0 + ) { + registerStyleAttribute(fieldName, layer, styleColor[0], styleColor[1]); + } else { + registerStyleAttribute(fieldName, layer, '#fff', undefined); + } + } else { + registerStyleAttribute(fieldName, layer, '#fff', undefined); + } } /** @@ -113,7 +198,47 @@ function getUvPosition( /** * 1、根据输入的 field 字段从 originData 中取值 (style 样式用于数据映射的值) - * 2、根据输入的 heightCount 以及默认的 WIDTH 为纹理对象提供数据 + * 2、根据输入的 heightCount 以及默认的 WIDTH 为纹理对象提供数据 (float) + * 3、根据输入的 createTexture2D 构建纹理对象 + * 4、存储 + * @param heightCount + * @param createTexture2D + * @param originData + * @param field + * @returns + */ +function initTextureFloatData( + 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]; + d.push(v); + } else { + d.push(0); + } + } + + const texture = createTexture2D({ + flipY: true, + data: d, + format: gl.LUMINANCE, + type: gl.FLOAT, + width: WIDTH, + height: heightCount, + }); + + return texture; +} + +/** + * 1、根据输入的 field 字段从 originData 中取值 (style 样式用于数据映射的值) + * 2、根据输入的 heightCount 以及默认的 WIDTH 为纹理对象提供数据 (color) * 3、根据输入的 createTexture2D 构建纹理对象 * @param heightCount * @param createTexture2D @@ -121,7 +246,7 @@ function getUvPosition( * @param field * @returns */ -function initTextureData( +function initTextureVec4Data( heightCount: number, createTexture2D: any, originData: any, @@ -130,8 +255,8 @@ function initTextureData( 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); + const [r, g, b, a] = rgb2arr(originData[i][field]); + d.push(r * 255, g * 255, b * 255, a * 255); } else { d.push(0, 0, 0, 0); } @@ -149,32 +274,12 @@ function initTextureData( return texture; } -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) - - const texture = createTexture2D({ - flipY: true, - data: new Uint8Array(imageData.data), - width: imageData.width, - height: imageData.height, - }); - - return texture; -} - export { - handleStyleOpacity, - handleStyleStrokeOpacity, + handleStyleDataMapping, + handleStyleFloat, getSize, getUvPosition, - initTextureData, - initDefaultTextureData, + initTextureFloatData, + initTextureVec4Data, + handleStyleColor, }; diff --git a/packages/renderer/src/regl/ReglModel.ts b/packages/renderer/src/regl/ReglModel.ts index ebd17a696b..ed9e6a6b4a 100644 --- a/packages/renderer/src/regl/ReglModel.ts +++ b/packages/renderer/src/regl/ReglModel.ts @@ -124,7 +124,6 @@ export default class ReglModel implements IModel { | number[] | boolean; } = {}; - Object.keys(uniforms).forEach((uniformName: string) => { const type = typeof uniforms[uniformName]; if ( diff --git a/packages/utils/src/color.ts b/packages/utils/src/color.ts index cf31e6964b..b27bb1810e 100644 --- a/packages/utils/src/color.ts +++ b/packages/utils/src/color.ts @@ -15,6 +15,10 @@ export function rgb2arr(str: string) { return arr; } +export function isColor(str: string) { + return d3.color(str); +} + export function decodePickingColor(color: Uint8Array): number { const i1 = color && color[0]; const i2 = color && color[1]; diff --git a/stories/Map/components/amap2demo.tsx b/stories/Map/components/amap2demo.tsx index ff43816f72..570b3e1d69 100644 --- a/stories/Map/components/amap2demo.tsx +++ b/stories/Map/components/amap2demo.tsx @@ -17,7 +17,7 @@ export default class Amap2demo extends React.Component { center: [121.107846, 30.267069], pitch: 0, style: 'normal', - zoom: 20, + zoom: 2, animateEnable: false, }), }); @@ -27,63 +27,133 @@ export default class Amap2demo extends React.Component { lat: 30.267069, opacity2: 0.2, strokeOpacity2: 0.2, + strokeColor: '#000', + strokeWidth: 0.5, + // offsets2: [0, 0] + offsets2: [100, 100], }, { lng: 121.107, lat: 30.267069, opacity2: 0.4, strokeOpacity2: 0.4, + strokeColor: '#0f0', + strokeWidth: 2, + offsets2: [100, 100], }, { lng: 121.107846, lat: 30.26718, opacity2: 0.6, strokeOpacity2: 0.6, + strokeColor: '#f00', + strokeWidth: 4, + // offsets2: [200, 200] + offsets2: [100, 100], }, // { // lng: 38.54, // lat: 77.02, // opacity: 0.5 + // strokeColor: "#ff0" // }, ]; this.scene = scene; - + // https://gw-office.alipayobjects.com/bmw-prod/61c3fca0-2991-48b4-bb6d-ecc2cbd682dd.json // 100 * 100 + let hunredMhunred = + 'https://gw-office.alipayobjects.com/bmw-prod/61c3fca0-2991-48b4-bb6d-ecc2cbd682dd.json'; + // https://gw-office.alipayobjects.com/bmw-prod/ccc91465-d3ea-4eda-a178-7c1815dac32b.json // 1000 * 100 + let thousandMhundred = + 'https://gw-office.alipayobjects.com/bmw-prod/ccc91465-d3ea-4eda-a178-7c1815dac32b.json'; scene.on('loaded', () => { - const layer = new PointLayer() - .source(originData, { - parser: { - type: 'json', - x: 'lng', - y: 'lat', - }, - }) - .shape('circle') - // .shape('normal') - // .shape('fill') - .color('rgba(255, 0, 0, 0.9)') - .size(10) - .style({ - stroke: '#000', - storkeWidth: 2, - // strokeOpacity: 0.2, - // strokeOpacity: 'strokeOpacity2', - strokeOpacity: [ - 'strokeOpacity2', - (d: any) => { - return d; - }, - ], - // strokeOpacity: ['opacity2', [0.2, 0.6]], - // offsets: [100, 100], - opacity: 'opacity2', - // opacity: 0.2 - // opacity: ['opacity2', (d: any) => { - // return d - // }] - // opacity: ['opacity2', [0.2, 0.6]], - }) - .active(true); - scene.addLayer(layer); + for (let i = 0; i < 1; i++) { + fetch(thousandMhundred) + .then((res) => res.text()) + .then((data) => { + // console.log('data', data) + // lng: Math.random() * 180, // 0 ~ 180 + // lat: Math.random() * 100 - 50, // -50 ~ 50 + // customOpacity: Math.random(), + // customStroke: `rgb(${Math.random()*255}, ${Math.random()*255}, ${Math.random()*255}, 1)`, + // customStrokeOpacity: Math.random(), + // customStrokeWidth: Math.random() * 5, + let layer = new PointLayer() + .source(JSON.parse(data), { + parser: { + type: 'json', + x: 'lng', + y: 'lat', + }, + }) + .shape('circle') + .color('rgba(255, 0, 0, 1.0)') + .size(10) + .style({ + opacity: 'customOpacity', + strokeOpacity: 'customStrokeOpacity', + strokeWidth: 'customStrokeWidth', + stroke: 'customStroke', + }); + scene.addLayer(layer); + }); + // let layer = new PointLayer() + // .source(originData, { + // parser: { + // type: 'json', + // x: 'lng', + // y: 'lat', + // }, + // }) + // .shape('circle') + // // .shape('normal') + // // .shape('fill') + // // .color('rgba(255, 0, 0, 0.9)') + // .color('rgba(255, 0, 0, 1.0)') + // .size(10) + // // .offsets('123') + // .style({ + // // stroke: '#000', + // // stroke: 'rgba(0, 255, 0, 1)', + // // stroke: 'strokeColor', + // // stroke: ['strokeColor', (d: any) => { + // // return d + // // }], + // // stroke: ['strokeColor', ["#f00", "#ff0"]], + + // // strokeWidth: 4, + // // strokeWidth: "strokeWidth", + // // strokeWidth: ["strokeWidth", [1, 2]], + // // strokeWidth: ["strokeWidth", (d: any) => { + // // return d * 2 + // // }], + + // // strokeOpacity: 0.5, + // // strokeOpacity: 'strokeOpacity2', + // // strokeOpacity: 1.0, + // // strokeOpacity: [ + // // 'strokeOpacity2', + // // (d: any) => { + // // // console.log('strokeOpacity2', d) + // // return d*2; + // // }, + // // ], + // // strokeOpacity: ['opacity2', [0.2, 0.6]], + + // // offsets: [100, 100], + // // offsets: 'offsets2', + // // offsets: ['offsets2', (d: any) => d], + + // // opacity: 'opacity2', + // // opacity: 0.2 + // // opacity: 0, + // // opacity: ['opacity2', (d: any) => { + // // return d + // // }] + // // opacity: ['opacity2', [0.2, 0.6]], + // }) + // .active(true); + // scene.addLayer(layer); + } }); }