feat: 线图层支持渐变颜色(line/arc/arc3d/great_circle)

This commit is contained in:
2912401452 2021-06-08 20:31:59 +08:00
parent 17a9b06470
commit 3d37240596
21 changed files with 346 additions and 28 deletions

View File

@ -5,11 +5,13 @@ export enum lineStyleType {
export interface ILineLayerStyleOptions {
opacity: number;
lineType?: keyof typeof lineStyleType;
dashArray?: [number, number];
lineType?: keyof typeof lineStyleType; // 可选参数、线类型(all - dash/solid)
dashArray?: [number, number]; // 可选参数、虚线间隔
segmentNumber: number;
forward?: boolean;
lineTexture?: boolean;
iconStep?: number;
textureBlend?: string; // 可选参数、供给纹理贴图使用
forward?: boolean; // 可选参数、是否反向(arcLine)
lineTexture?: boolean; // 可选参数、是否开启纹理贴图功能(all)
iconStep?: number; // 可选参数、纹理贴图步长(all)
textureBlend?: string; // 可选参数、供给纹理贴图使用(all)
sourceColor?: string; // 可选参数、设置渐变色的起始颜色(all)
targetColor?: string; // 可选参数、设置渐变色的终点颜色(all)
}

View File

@ -14,6 +14,7 @@ import { ILineLayerStyleOptions, lineStyleType } from '../../core/interface';
import { LineArcTriangulation } from '../../core/triangulation';
import line_arc_frag from '../shaders/line_arc_frag.glsl';
import line_arc2d_vert from '../shaders/line_arc_vert.glsl';
import { rgb2arr } from '@antv/l7-utils'
const lineStyleObj: { [key: string]: number } = {
solid: 0.0,
dash: 1.0,
@ -23,6 +24,8 @@ export default class ArcModel extends BaseModel {
public getUninforms(): IModelUniform {
const {
opacity,
sourceColor,
targetColor,
textureBlend = 'normal',
lineType = 'solid',
dashArray = [10, 5],
@ -35,6 +38,16 @@ export default class ArcModel extends BaseModel {
dashArray.push(0, 0);
}
// 转化渐变色
let useLinearColor = 0 // 默认不生效
let sourceColorArr = [0, 0, 0, 0]
let targetColorArr = [0, 0, 0, 0]
if(sourceColor && targetColor) {
sourceColorArr = rgb2arr(sourceColor)
targetColorArr = rgb2arr(targetColor)
useLinearColor = 1
}
if (this.rendererService.getDirty()) {
this.texture.bind();
}
@ -48,10 +61,16 @@ export default class ArcModel extends BaseModel {
u_blur: 0.9,
u_lineDir: forward ? 1 : -1,
// 纹理支持参数
u_texture: this.texture, // 贴图
u_line_texture: lineTexture ? 1.0 : 0.0, // 传入线的标识
u_icon_step: iconStep,
u_textSize: [1024, this.iconService.canvasHeight || 128],
// 渐变色支持参数
u_linearColor: useLinearColor,
u_sourceColor: sourceColorArr,
u_targetColor: targetColorArr
};
}

View File

@ -13,6 +13,7 @@ import { ILineLayerStyleOptions, lineStyleType } from '../../core/interface';
import { LineArcTriangulation } from '../../core/triangulation';
import line_arc_frag from '../shaders/line_arc_3d_frag.glsl';
import line_arc_vert from '../shaders/line_arc_3d_vert.glsl';
import { rgb2arr } from '@antv/l7-utils'
const lineStyleObj: { [key: string]: number } = {
solid: 0.0,
dash: 1.0,
@ -22,6 +23,8 @@ export default class Arc3DModel extends BaseModel {
public getUninforms(): IModelUniform {
const {
opacity,
sourceColor,
targetColor,
textureBlend = 'normal',
lineType = 'solid',
dashArray = [10, 5],
@ -33,6 +36,16 @@ export default class Arc3DModel extends BaseModel {
dashArray.push(0, 0);
}
// 转化渐变色
let useLinearColor = 0 // 默认不生效
let sourceColorArr = [0, 0, 0, 0]
let targetColorArr = [0, 0, 0, 0]
if(sourceColor && targetColor) {
sourceColorArr = rgb2arr(sourceColor)
targetColorArr = rgb2arr(targetColor)
useLinearColor = 1
}
if (this.rendererService.getDirty()) {
this.texture.bind();
}
@ -44,10 +57,16 @@ export default class Arc3DModel extends BaseModel {
u_line_type: lineStyleObj[lineType as string] || 0.0,
u_dash_array: dashArray,
// 纹理支持参数
u_texture: this.texture, // 贴图
u_line_texture: lineTexture ? 1.0 : 0.0, // 传入线的标识
u_icon_step: iconStep,
u_textSize: [1024, this.iconService.canvasHeight || 128],
// 渐变色支持参数
u_linearColor: useLinearColor,
u_sourceColor: sourceColorArr,
u_targetColor: targetColorArr
};
}

View File

@ -15,6 +15,7 @@ import { LineArcTriangulation } from '../../core/triangulation';
// import line_arc_frag from '../shaders/line_arc_frag.glsl';
import line_arc_frag from '../shaders/line_arc_great_circle_frag.glsl';
import line_arc2d_vert from '../shaders/line_arc_great_circle_vert.glsl';
import { rgb2arr } from '@antv/l7-utils'
const lineStyleObj: { [key: string]: number } = {
solid: 0.0,
dash: 1.0,
@ -25,6 +26,8 @@ export default class GreatCircleModel extends BaseModel {
public getUninforms(): IModelUniform {
const {
opacity,
sourceColor,
targetColor,
textureBlend = 'normal',
lineType = 'solid',
dashArray = [10, 5],
@ -39,6 +42,17 @@ export default class GreatCircleModel extends BaseModel {
if (this.rendererService.getDirty()) {
this.texture.bind();
}
// 转化渐变色
let useLinearColor = 0 // 默认不生效
let sourceColorArr = [0, 0, 0, 0]
let targetColorArr = [0, 0, 0, 0]
if(sourceColor && targetColor) {
sourceColorArr = rgb2arr(sourceColor)
targetColorArr = rgb2arr(targetColor)
useLinearColor = 1
}
return {
u_opacity: opacity === undefined ? 1 : opacity,
u_textureBlend: textureBlend === 'normal' ? 0.0 : 1.0,
@ -46,10 +60,16 @@ export default class GreatCircleModel extends BaseModel {
u_line_type: lineStyleObj[lineType as string] || 0.0,
u_dash_array: dashArray,
// 纹理支持参数
u_texture: this.texture, // 贴图
u_line_texture: lineTexture ? 1.0 : 0.0, // 传入线的标识
u_icon_step: iconStep,
u_textSize: [1024, this.iconService.canvasHeight || 128],
// 渐变色支持参数
u_linearColor: useLinearColor,
u_sourceColor: sourceColorArr,
u_targetColor: targetColorArr
};
}
public getAnimateUniforms(): IModelUniform {

View File

@ -15,6 +15,7 @@ import { ILineLayerStyleOptions, lineStyleType } from '../../core/interface';
import { LineTriangulation } from '../../core/triangulation';
import line_frag from '../shaders/line_frag.glsl';
import line_vert from '../shaders/line_vert.glsl';
import { rgb2arr } from '@antv/l7-utils'
const lineStyleObj: { [key: string]: number } = {
solid: 0.0,
dash: 1.0,
@ -24,6 +25,8 @@ export default class LineModel extends BaseModel {
public getUninforms(): IModelUniform {
const {
opacity,
sourceColor,
targetColor,
textureBlend = 'normal',
lineType = 'solid',
dashArray = [10, 5, 0, 0],
@ -38,16 +41,32 @@ export default class LineModel extends BaseModel {
this.texture.bind();
}
// 转化渐变色
let useLinearColor = 0 // 默认不生效
let sourceColorArr = [0, 0, 0, 0]
let targetColorArr = [0, 0, 0, 0]
if(sourceColor && targetColor) {
sourceColorArr = rgb2arr(sourceColor)
targetColorArr = rgb2arr(targetColor)
useLinearColor = 1
}
return {
u_opacity: opacity === undefined ? 1 : opacity,
u_textureBlend: textureBlend === 'normal' ? 0.0 : 1.0,
u_line_type: lineStyleObj[lineType],
u_dash_array: dashArray,
// 纹理支持参数
u_texture: this.texture, // 贴图
u_line_texture: lineTexture ? 1.0 : 0.0, // 传入线的标识
u_icon_step: iconStep,
u_textSize: [1024, this.iconService.canvasHeight || 128],
// 渐变色支持参数
u_linearColor: useLinearColor,
u_sourceColor: sourceColorArr,
u_targetColor: targetColorArr
};
}
public getAnimateUniforms(): IModelUniform {

View File

@ -26,11 +26,22 @@ varying vec2 v_iconMapUV;
uniform float u_time;
uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ];
uniform float u_linearColor: 0;
uniform vec4 u_sourceColor;
uniform vec4 u_targetColor;
#pragma include "picking"
void main() {
float animateSpeed = 0.0; // 运动速度
// gl_FragColor = v_color;
if(u_linearColor == 1.0) { // 使用渐变颜色
gl_FragColor = mix(u_sourceColor, u_targetColor, v_segmentIndex/segmentNumber);
} else { // 使用 color 方法传入的颜色
gl_FragColor = v_color;
}
// float blur = 1.- smoothstep(u_blur, 1., length(v_normal.xy));
// float blur = smoothstep(1.0, u_blur, length(v_normal.xy));
gl_FragColor.a *= u_opacity;

View File

@ -106,8 +106,8 @@ void main() {
v_normal = getNormal((next.xy - curr.xy) * indexDir, a_Position.y);
if(LineTexture == u_line_texture && u_line_type != LineTypeDash) { // 开启贴图模式
v_segmentIndex = a_Position.x;
if(LineTexture == u_line_texture && u_line_type != LineTypeDash) { // 开启贴图模式
v_arcDistrance = length(source - target);
v_pixelLen = project_pixel(u_icon_step);

View File

@ -27,12 +27,23 @@ varying float v_a;
varying vec2 v_offset;
varying vec2 v_iconMapUV;
uniform float u_linearColor: 0;
uniform vec4 u_sourceColor;
uniform vec4 u_targetColor;
#pragma include "picking"
void main() {
float animateSpeed = 0.0; // 运动速度
if(u_linearColor == 1.0) { // 使用渐变颜色
gl_FragColor = mix(u_sourceColor, u_targetColor, v_segmentIndex/segmentNumber);
} else { // 使用 color 方法传入的颜色
gl_FragColor = v_color;
}
// gl_FragColor = v_color;
// float blur = 1.- smoothstep(u_blur, 1., length(v_normal.xy));
// float blur = smoothstep(1.0, u_blur, length(v_normal.xy));
gl_FragColor.a *= u_opacity;

View File

@ -26,11 +26,22 @@ varying vec2 v_offset;
varying float v_a;
varying vec2 v_iconMapUV;
uniform float u_linearColor: 0;
uniform vec4 u_sourceColor;
uniform vec4 u_targetColor;
#pragma include "picking"
void main() {
float animateSpeed = 0.0;
// gl_FragColor = v_color;
if(u_linearColor == 1.0) { // 使用渐变颜色
gl_FragColor = mix(u_sourceColor, u_targetColor, v_segmentIndex/segmentNumber);
} else { // 使用 color 方法传入的颜色
gl_FragColor = v_color;
}
// float blur = 1.- smoothstep(u_blur, 1., length(v_normal.xy));
// float blur = smoothstep(1.0, u_blur, length(v_normal.xy));
gl_FragColor.a *= u_opacity;

View File

@ -156,8 +156,8 @@ void main() {
// vec4 project_pos = project_position(vec4(curr.xy, 0, 1.0));
// gl_Position = project_common_position_to_clipspace(vec4(curr.xy + offset, curr.z, 1.0));
if(LineTexture == u_line_texture) { // 开启贴图模式
v_segmentIndex = a_Position.x;
if(LineTexture == u_line_texture) { // 开启贴图模式
v_arcDistrance = length(source - target);
v_pixelLen = project_pixel(u_icon_step)/8.0;

View File

@ -118,9 +118,9 @@ void main() {
vec2 offset = project_pixel(getExtrusionOffset((next.xy - curr.xy) * indexDir, a_Position.y));
v_segmentIndex = a_Position.x + 1.0;
if(LineTexture == u_line_texture) { // 开启贴图模式
v_segmentIndex = a_Position.x + 1.0;
v_arcDistrance = length(source - target);
v_iconMapUV = a_iconMapUV;
v_pixelLen = project_pixel(u_icon_step);

View File

@ -28,6 +28,10 @@ varying float v_pixelLen;
varying vec2 v_iconMapUV;
varying float v_strokeWidth;
uniform float u_linearColor: 0;
uniform vec4 u_sourceColor;
uniform vec4 u_targetColor;
#pragma include "picking"
uniform float u_time;
@ -35,7 +39,14 @@ uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ]; // 控制运动
// [animate, duration, interval, trailLength],
void main() {
float animateSpeed = 0.0; // 运动速度
// gl_FragColor = v_color;
if(u_linearColor == 1.0) { // 使用渐变颜色
gl_FragColor = mix(u_sourceColor, u_targetColor, v_distance_ratio);
} else { // 使用 color 方法传入的颜色
gl_FragColor = v_color;
}
// anti-alias
// float blur = 1.0 - smoothstep(u_blur, 1., length(v_normal.xy));
gl_FragColor.a *= u_opacity; // 全局透明度

View File

@ -36,6 +36,7 @@ varying float v_size;
varying float v_a;
varying float v_pixelLen;
varying vec2 v_iconMapUV;
uniform float u_linearColor: 0;
// varying float v_strokeWidth;
void main() {
@ -49,7 +50,7 @@ void main() {
// v_distance_ratio = 0.01;
v_dash_array = pow(2.0, 20.0 - u_Zoom) * u_dash_array / a_Total_Distance;
}
if(u_aimate.x == Animate) {
if(u_aimate.x == Animate || u_linearColor == 1.0) {
v_distance_ratio = a_Distance / a_Total_Distance;
}
v_normal = vec2(reverse_offset_normal(a_Normal) * sign(a_Miter));

View File

@ -127,6 +127,7 @@ export default class DataMappingPlugin implements ILayerPlugin {
// TODO: 支持每个属性配置 postprocess
if (attribute.name === 'color') {
// console.log('attribute', attribute)
values = values.map((c: unknown) => {
return rgb2arr(c as string);
});

View File

@ -61,10 +61,12 @@ export default class Amap2demo_arcLine3DTex extends React.Component {
// opacity: 0,
opacity: 0.8,
// opacity: 0.2,
lineType: 'dash',
dashArray: [5, 5],
textureBlend: 'replace',
// lineType: 'dash',
// dashArray: [5, 5],
// textureBlend: 'replace',
// textureBlend: 'normal',
sourceColor: "#f00",
targetColor: "#0f0"
});
// .animate({
// duration: 50,

View File

@ -0,0 +1,96 @@
// @ts-ignore
import { LineLayer, Scene } from '@antv/l7';
import { GaodeMap, GaodeMapV1 } from '@antv/l7-maps';
import * as React from 'react';
export default class Amap2demo_arcLineLinear extends React.Component {
// @ts-ignore
private scene: Scene;
public componentWillUnmount() {
this.scene.destroy();
}
public async componentDidMount() {
const scene = new Scene({
id: 'map',
// map: new GaodeMapV1({
map: new GaodeMap({
pitch: 40,
center: [107.77791556935472, 35.443286920228644],
zoom: 2.9142882493605033,
viewMode: '3D',
style: 'dark',
}),
});
this.scene = scene;
scene.on('loaded', () => {
scene.addImage(
'02',
'https://gw.alipayobjects.com/zos/bmw-prod/0ca1668e-38c2-4010-8568-b57cb33839b9.svg',
);
let data = [
{
lng1: 75.76171875,
lat1: 36.31512514748051,
lng2: 46.23046874999999,
lat2: 52.802761415419674,
},
];
// @ts-ignore
const layer = new LineLayer({
blend: 'normal',
})
.source(data, {
parser: {
type: 'json',
x: 'lng1',
y: 'lat1',
x1: 'lng2',
y1: 'lat2',
},
})
.size(20)
.shape('arc')
.color('#f00')
.style({
// forward: false,
lineTexture: true, // 开启线的贴图功能
iconStep: 30, // 设置贴图纹理的间距
// opacity: 0.5,
// opacity: 0.2,
// lineType: 'dash',
// dashArray: [5, 5],
// textureBlend: 'replace',
// textureBlend: 'normal',
sourceColor: "#f00",
targetColor: "#0f0"
})
// .animate({
// duration: 50,
// interval: 0.3,
// trailLength: 0.1,
// });
scene.addLayer(layer);
});
}
public render() {
return (
<>
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
</>
);
}
}

View File

@ -67,11 +67,11 @@ export default class Amap2demo_arcLineTex extends React.Component {
// textureBlend: 'replace',
// textureBlend: 'normal',
})
.animate({
duration: 50,
interval: 0.3,
trailLength: 0.1,
});
// .animate({
// duration: 50,
// interval: 0.3,
// trailLength: 0.1,
// });
scene.addLayer(layer);
});
}

View File

@ -63,15 +63,17 @@ export default class Amap2demo_arcLine_greatCircle extends React.Component {
.color('#ff0000')
.texture('02')
.style({
// opacity: 0.0,
opacity: 0.6,
// textureBlend: 'replace',
// textureBlend: 'normal',
blur: 0.99,
// lineTexture: true, // 开启线的贴图功能
lineTexture: true, // 开启线的贴图功能
iconStep: 5, // 设置贴图纹理的间距
// lineType: 'dash',
// dashArray: [5, 5],
sourceColor: "#f00",
targetColor: "#0f0"
});
// .animate({
// duration: 5,

View File

@ -0,0 +1,89 @@
// @ts-ignore
import { LineLayer, Scene } from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import * as React from 'react';
export default class Amap2demo_lineLinear extends React.Component {
// @ts-ignore
private scene: Scene;
public componentWillUnmount() {
this.scene.destroy();
}
public async componentDidMount() {
const scene = new Scene({
id: 'map',
map: new GaodeMap({
center: [120.19382669582967, 30.258134],
pitch: 0,
zoom: 16,
viewMode: '3D',
}),
});
this.scene = scene;
scene.on('loaded', () => {
fetch(
'https://gw.alipayobjects.com/os/basement_prod/40ef2173-df66-4154-a8c0-785e93a5f18e.json',
)
.then((res) => res.json())
.then((data) => {
scene.addImage(
'00',
'https://gw.alipayobjects.com/zos/basement_prod/604b5e7f-309e-40db-b95b-4fac746c5153.svg',
);
scene.addImage(
'01',
'https://gw.alipayobjects.com/zos/basement_prod/30580bc9-506f-4438-8c1a-744e082054ec.svg',
);
scene.addImage(
'02',
'https://gw.alipayobjects.com/zos/bmw-prod/ce83fc30-701f-415b-9750-4b146f4b3dd6.svg',
);
// @ts-ignore
const layer = new LineLayer({})
.source(data)
.size(5)
.shape('line')
.texture('01')
.color('#25d8b7')
// .animate({
// interval: 1, // 间隔
// duration: 1, // 持续时间,延时
// trailLength: 2, // 流线长度
// })
.style({
opacity: 0.5,
// opacity: 0,
// lineTexture: true, // 开启线的贴图功能
// iconStep: 50, // 设置贴图纹理的间距
// lineType: 'dash',
// dashArray: [5, 5],
// textureBlend: 'replace',
// textureBlend: 'normal',
sourceColor: "#f00",
targetColor: "#0f0"
});
scene.addLayer(layer);
});
});
}
public render() {
return (
<>
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
</>
);
}
}

View File

@ -22,8 +22,10 @@ import Amap2demo_lineHeight from "./components/amap2demo_lineHeight"
import Amap2demo_lineDash from "./components/amap2demo_lineDash"
import Amap2demo_arcLineDir from "./components/amap2demo_arcLineDir"
import Amap2demo_arcLineTex from './components/amap2demo_arcLineTex';
import Amap2demo_arcLineLinear from './components/amap2demo_arcLineLinear';
import Amap2demo_arcLine3DTex from './components/amap2demo_arcLine3DTex';
import Amap2demo_lineStreet from './components/amap2demo_lineStreet';
import Amap2demo_lineLinear from './components/amap2demo_lineLinear';
import Amap2demo_road from './components/amap2demo_road';
import Amap2demo_road2 from './components/amap2demo_road2';
@ -74,10 +76,12 @@ storiesOf('地图方法', module)
.add('高德地图2.0 line_arcDir', () => <Amap2demo_arcLineDir />)
.add('高德地图2.0 line_arcTex', () => <Amap2demo_arcLineTex />)
.add('高德地图2.0 line_arcLinear', () => <Amap2demo_arcLineLinear />)
.add('高德地图2.0 line_arc3DTex', () => <Amap2demo_arcLine3DTex />)
.add('高德地图2.0 line_winds', () => <Amap2demo_winds />)
.add('高德地图2.0 line_Street', () => <Amap2demo_lineStreet />)
.add('高德地图2.0 line_Linear', () => <Amap2demo_lineLinear />)
.add('高德地图2.0 road', () => <Amap2demo_road />)
.add('高德地图2.0 road2', () => <Amap2demo_road2 />)