autumnplot-gl 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/110.autumnplot-gl.js +1 -1
- package/dist/110.autumnplot-gl.js.map +1 -1
- package/dist/autumnplot-gl.js +1 -1
- package/dist/autumnplot-gl.js.map +1 -1
- package/dist/marchingsquares.wasm +0 -0
- package/lib/Barbs.d.ts +2 -2
- package/lib/Barbs.js +9 -5
- package/lib/Contour.d.ts +1 -3
- package/lib/Contour.js +8 -5
- package/lib/ContourCreator.js +4 -40
- package/lib/Fill.d.ts +1 -2
- package/lib/Fill.js +18 -9
- package/lib/Hodographs.d.ts +1 -2
- package/lib/Hodographs.js +10 -8
- package/lib/Paintball.d.ts +2 -2
- package/lib/Paintball.js +8 -6
- package/lib/PlotLayer.worker.js +3 -0
- package/lib/cpp/marchingsquares.js +558 -1261
- package/lib/cpp/marchingsquares.wasm +0 -0
- package/lib/cpp/marchingsquares_embind.d.ts +4 -45
- package/package.json +1 -1
|
Binary file
|
package/lib/Barbs.d.ts
CHANGED
|
@@ -26,8 +26,8 @@ interface BarbsOptions {
|
|
|
26
26
|
declare class Barbs<ArrayType extends TypedArray, MapType extends MapLikeType> extends PlotComponent<MapType> {
|
|
27
27
|
/** The vector field */
|
|
28
28
|
private fields;
|
|
29
|
-
readonly
|
|
30
|
-
readonly
|
|
29
|
+
readonly opts: Required<BarbsOptions>;
|
|
30
|
+
private readonly color_rgb;
|
|
31
31
|
private gl_elems;
|
|
32
32
|
/**
|
|
33
33
|
* Create a field of wind barbs
|
package/lib/Barbs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PlotComponent } from "./PlotComponent";
|
|
2
2
|
import { BillboardCollection } from './BillboardCollection';
|
|
3
|
-
import {
|
|
3
|
+
import { hex2rgb, normalizeOptions } from './utils';
|
|
4
4
|
const BARB_DIMS = {
|
|
5
5
|
BB_WIDTH: 85,
|
|
6
6
|
BB_HEIGHT: 256,
|
|
@@ -97,6 +97,10 @@ function _createBarbTexture() {
|
|
|
97
97
|
return canvas;
|
|
98
98
|
}
|
|
99
99
|
let BARB_TEXTURE = null;
|
|
100
|
+
const barb_opt_defaults = {
|
|
101
|
+
color: '#000000',
|
|
102
|
+
thin_fac: 1
|
|
103
|
+
};
|
|
100
104
|
/**
|
|
101
105
|
* A class representing a field of wind barbs. The barbs are automatically thinned based on the zoom level on the map; the user only has to provide a
|
|
102
106
|
* thinning factor at zoom level 1.
|
|
@@ -114,9 +118,9 @@ class Barbs extends PlotComponent {
|
|
|
114
118
|
constructor(fields, opts) {
|
|
115
119
|
super();
|
|
116
120
|
this.fields = fields;
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
this.
|
|
121
|
+
this.opts = normalizeOptions(opts, barb_opt_defaults);
|
|
122
|
+
const color_rgb = hex2rgb(this.opts.color);
|
|
123
|
+
this.color_rgb = [color_rgb[0], color_rgb[1], color_rgb[2]];
|
|
120
124
|
this.gl_elems = null;
|
|
121
125
|
}
|
|
122
126
|
/**
|
|
@@ -142,7 +146,7 @@ class Barbs extends PlotComponent {
|
|
|
142
146
|
BARB_TEXTURE = _createBarbTexture();
|
|
143
147
|
}
|
|
144
148
|
const barb_image = { format: gl.RGBA, type: gl.UNSIGNED_BYTE, image: BARB_TEXTURE, mag_filter: gl.NEAREST };
|
|
145
|
-
const barb_billboards = new BillboardCollection(this.fields, this.thin_fac, map_max_zoom, barb_image, BARB_DIMS, this.
|
|
149
|
+
const barb_billboards = new BillboardCollection(this.fields, this.opts.thin_fac, map_max_zoom, barb_image, BARB_DIMS, this.color_rgb, 0.1);
|
|
146
150
|
await barb_billboards.setup(gl);
|
|
147
151
|
this.gl_elems = {
|
|
148
152
|
map: map, barb_billboards: barb_billboards
|
package/lib/Contour.d.ts
CHANGED
|
@@ -28,9 +28,7 @@ interface ContourOptions {
|
|
|
28
28
|
*/
|
|
29
29
|
declare class Contour<ArrayType extends TypedArray, MapType extends MapLikeType> extends PlotComponent<MapType> {
|
|
30
30
|
private field;
|
|
31
|
-
readonly
|
|
32
|
-
readonly interval: number;
|
|
33
|
-
readonly levels: number[];
|
|
31
|
+
readonly opts: Required<ContourOptions>;
|
|
34
32
|
private gl_elems;
|
|
35
33
|
private contours;
|
|
36
34
|
/**
|
package/lib/Contour.js
CHANGED
|
@@ -4,6 +4,11 @@ import { PolylineCollection } from './PolylineCollection';
|
|
|
4
4
|
import { TextCollection } from './TextCollection';
|
|
5
5
|
import { hex2rgb, normalizeOptions } from './utils';
|
|
6
6
|
import { kdTree } from 'kd-tree-javascript';
|
|
7
|
+
const contour_opt_defaults = {
|
|
8
|
+
color: '#000000',
|
|
9
|
+
interval: 1,
|
|
10
|
+
levels: undefined
|
|
11
|
+
};
|
|
7
12
|
/**
|
|
8
13
|
* A field of contoured data.
|
|
9
14
|
* @example
|
|
@@ -20,9 +25,7 @@ class Contour extends PlotComponent {
|
|
|
20
25
|
constructor(field, opts) {
|
|
21
26
|
super();
|
|
22
27
|
this.field = field;
|
|
23
|
-
this.
|
|
24
|
-
this.levels = opts.levels || [];
|
|
25
|
-
this.color = opts.color || '#000000';
|
|
28
|
+
this.opts = normalizeOptions(opts, contour_opt_defaults);
|
|
26
29
|
this.gl_elems = null;
|
|
27
30
|
this.contours = null;
|
|
28
31
|
}
|
|
@@ -39,11 +42,11 @@ class Contour extends PlotComponent {
|
|
|
39
42
|
const line_data = Object.values(contour_data).flat().map(c => {
|
|
40
43
|
return { vertices: c };
|
|
41
44
|
});
|
|
42
|
-
this.contours = await PolylineCollection.make(gl, line_data, { line_width: 2, color: this.color });
|
|
45
|
+
this.contours = await PolylineCollection.make(gl, line_data, { line_width: 2, color: this.opts.color });
|
|
43
46
|
this.gl_elems.map.triggerRepaint();
|
|
44
47
|
}
|
|
45
48
|
async getContours() {
|
|
46
|
-
return await this.field.getContours({ interval: this.interval, levels: this.levels });
|
|
49
|
+
return await this.field.getContours({ interval: this.opts.interval, levels: this.opts.levels });
|
|
47
50
|
}
|
|
48
51
|
/**
|
|
49
52
|
* @internal
|
package/lib/ContourCreator.js
CHANGED
|
@@ -12,48 +12,12 @@ async function contourCreator(data, grid, opts) {
|
|
|
12
12
|
throw "Must supply either an interval or levels to contourCreator()";
|
|
13
13
|
}
|
|
14
14
|
const interval = opts.interval === undefined ? 0 : opts.interval;
|
|
15
|
-
const levels = opts.levels === undefined ? [] : [...opts.levels];
|
|
16
15
|
const msm = await initMSModule();
|
|
17
16
|
const grid_coords = grid.getGridCoords();
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
const grid_x = new msm.FloatList();
|
|
23
|
-
grid_x.resize(grid.ni, 0);
|
|
24
|
-
grid_coords.x.forEach((v, i) => grid_x.set(i, v));
|
|
25
|
-
const grid_y = new msm.FloatList();
|
|
26
|
-
grid_y.resize(grid.nj, 0);
|
|
27
|
-
grid_coords.y.forEach((v, i) => grid_y.set(i, v));
|
|
28
|
-
if (levels.length == 0) {
|
|
29
|
-
const levels_cpp = msm.getContourLevelsFloat32(grid_data, grid.ni, grid.nj, interval);
|
|
30
|
-
for (let ilvl = 0; ilvl < levels_cpp.size(); ilvl++) {
|
|
31
|
-
levels.push(levels_cpp.get(ilvl));
|
|
32
|
-
}
|
|
33
|
-
levels_cpp.delete();
|
|
34
|
-
}
|
|
35
|
-
const contours = {};
|
|
36
|
-
levels.forEach(v => {
|
|
37
|
-
const contours_ = msm.makeContoursFloat32(grid_data, grid_x, grid_y, v);
|
|
38
|
-
contours[v] = [];
|
|
39
|
-
for (let icntr = 0; icntr < contours_.size(); icntr++) {
|
|
40
|
-
const contour = contours_.get(icntr);
|
|
41
|
-
const contour_point_list = contour.point_list;
|
|
42
|
-
contours[v].push([]);
|
|
43
|
-
for (let ipt = 0; ipt < contour_point_list.size(); ipt++) {
|
|
44
|
-
const pt = contour_point_list.get(ipt);
|
|
45
|
-
const [lon, lat] = grid.transform(pt.x, pt.y, { inverse: true });
|
|
46
|
-
contours[v][icntr].push([lon, lat]);
|
|
47
|
-
pt.delete();
|
|
48
|
-
}
|
|
49
|
-
contour_point_list.delete();
|
|
50
|
-
contour.delete();
|
|
51
|
-
}
|
|
52
|
-
contours_.delete();
|
|
53
|
-
});
|
|
54
|
-
grid_data.delete();
|
|
55
|
-
grid_x.delete();
|
|
56
|
-
grid_y.delete();
|
|
17
|
+
const getContourLevels = data instanceof Float32Array ? msm.getContourLevelsFloat32 : msm.getContourLevelsFloat16;
|
|
18
|
+
const makeContours = data instanceof Float32Array ? msm.makeContoursFloat32 : msm.makeContoursFloat16;
|
|
19
|
+
const levels = opts.levels === undefined ? getContourLevels(data, grid.ni, grid.nj, interval) : opts.levels;
|
|
20
|
+
const contours = makeContours(data, grid_coords.x, grid_coords.y, levels, (x, y) => grid.transform(x, y, { inverse: true }));
|
|
57
21
|
return contours;
|
|
58
22
|
}
|
|
59
23
|
export { contourCreator, initMSModule };
|
package/lib/Fill.d.ts
CHANGED
|
@@ -23,8 +23,7 @@ interface RasterOptions {
|
|
|
23
23
|
}
|
|
24
24
|
declare class PlotComponentFill<ArrayType extends TypedArray, MapType extends MapLikeType> extends PlotComponent<MapType> {
|
|
25
25
|
private field;
|
|
26
|
-
readonly
|
|
27
|
-
readonly opacity: number;
|
|
26
|
+
readonly opts: Required<ContourFillOptions>;
|
|
28
27
|
private readonly cmap_image;
|
|
29
28
|
private readonly index_map;
|
|
30
29
|
private gl_elems;
|
package/lib/Fill.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PlotComponent, getGLFormatTypeAlignment } from './PlotComponent';
|
|
2
|
-
import { makeIndexMap, makeTextureImage } from './Colormap';
|
|
2
|
+
import { ColorMap, makeIndexMap, makeTextureImage } from './Colormap';
|
|
3
3
|
import { WGLProgram, WGLTexture } from 'autumn-wgl';
|
|
4
|
-
import { hex2rgb } from './utils';
|
|
4
|
+
import { hex2rgb, normalizeOptions } from './utils';
|
|
5
5
|
const contourfill_vertex_shader_src = `uniform mat4 u_matrix;
|
|
6
6
|
uniform int u_offset;
|
|
7
7
|
|
|
@@ -50,14 +50,22 @@ void main() {
|
|
|
50
50
|
color.a = color.a * u_opacity;
|
|
51
51
|
gl_FragColor = color;
|
|
52
52
|
}`
|
|
53
|
+
const default_cmap = new ColorMap([0, 1], ['#000000'], { overflow_color: '#000000', underflow_color: '#000000' });
|
|
54
|
+
const contour_fill_opt_defaults = {
|
|
55
|
+
cmap: default_cmap,
|
|
56
|
+
opacity: 1,
|
|
57
|
+
};
|
|
58
|
+
const raster_opt_defaults = {
|
|
59
|
+
cmap: default_cmap,
|
|
60
|
+
opacity: 1,
|
|
61
|
+
};
|
|
53
62
|
class PlotComponentFill extends PlotComponent {
|
|
54
63
|
constructor(field, opts) {
|
|
55
64
|
super();
|
|
56
65
|
this.field = field;
|
|
57
|
-
this.
|
|
58
|
-
this.
|
|
59
|
-
this.
|
|
60
|
-
this.index_map = makeIndexMap(this.cmap);
|
|
66
|
+
this.opts = normalizeOptions(opts, contour_fill_opt_defaults);
|
|
67
|
+
this.cmap_image = makeTextureImage(this.opts.cmap);
|
|
68
|
+
this.index_map = makeIndexMap(this.opts.cmap);
|
|
61
69
|
this.gl_elems = null;
|
|
62
70
|
this.fill_texture = null;
|
|
63
71
|
this.image_mag_filter = null;
|
|
@@ -113,9 +121,10 @@ class PlotComponentFill extends PlotComponent {
|
|
|
113
121
|
const gl_elems = this.gl_elems;
|
|
114
122
|
if (matrix instanceof Float32Array)
|
|
115
123
|
matrix = [...matrix];
|
|
116
|
-
const
|
|
117
|
-
const
|
|
118
|
-
|
|
124
|
+
const cmap = this.opts.cmap;
|
|
125
|
+
const underflow_color = cmap.underflow_color === null ? [0, 0, 0, 0] : hex2rgb(cmap.underflow_color.color).concat(cmap.underflow_color.opacity);
|
|
126
|
+
const overflow_color = cmap.overflow_color === null ? [0, 0, 0, 0] : hex2rgb(cmap.overflow_color.color).concat(cmap.overflow_color.opacity);
|
|
127
|
+
gl_elems.program.use({ 'a_pos': gl_elems.vertices, 'a_tex_coord': gl_elems.texcoords }, { 'u_cmap_min': cmap.levels[0], 'u_cmap_max': cmap.levels[cmap.levels.length - 1], 'u_matrix': matrix, 'u_opacity': this.opts.opacity,
|
|
119
128
|
'u_n_index': this.index_map.length, 'u_underflow_color': underflow_color, 'u_overflow_color': overflow_color, 'u_offset': 0 }, { 'u_fill_sampler': this.fill_texture, 'u_cmap_sampler': gl_elems.cmap_texture, 'u_cmap_nonlin_sampler': gl_elems.cmap_nonlin_texture });
|
|
120
129
|
gl.enable(gl.BLEND);
|
|
121
130
|
gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
package/lib/Hodographs.d.ts
CHANGED
|
@@ -17,8 +17,7 @@ interface HodographOptions {
|
|
|
17
17
|
/** A class representing a a field of hodograph plots */
|
|
18
18
|
declare class Hodographs<MapType extends MapLikeType> extends PlotComponent<MapType> {
|
|
19
19
|
private profile_field;
|
|
20
|
-
readonly
|
|
21
|
-
readonly thin_fac: number;
|
|
20
|
+
readonly opts: Required<HodographOptions>;
|
|
22
21
|
private gl_elems;
|
|
23
22
|
private line_elems;
|
|
24
23
|
private readonly hodo_scale;
|
package/lib/Hodographs.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PlotComponent } from "./PlotComponent";
|
|
2
2
|
import { PolylineCollection } from "./PolylineCollection";
|
|
3
3
|
import { BillboardCollection } from "./BillboardCollection";
|
|
4
|
-
import { getMinZoom, hex2rgb } from './utils';
|
|
4
|
+
import { getMinZoom, hex2rgb, normalizeOptions } from './utils';
|
|
5
5
|
import { ColorMap } from "./Colormap";
|
|
6
6
|
const LINE_WIDTH = 4;
|
|
7
7
|
const BG_MAX_RING_MAG = 40;
|
|
@@ -41,6 +41,10 @@ function _createHodoBackgroundTexture() {
|
|
|
41
41
|
;
|
|
42
42
|
let HODO_BG_TEXTURE = null;
|
|
43
43
|
const HODO_CMAP = new ColorMap([0, 1, 3, 6, 9], ['#ffffcc', '#a1dab4', '#41b6c4', '#225ea8']);
|
|
44
|
+
const hodograph_opt_defaults = {
|
|
45
|
+
bgcolor: '#000000',
|
|
46
|
+
thin_fac: 1
|
|
47
|
+
};
|
|
44
48
|
/** A class representing a a field of hodograph plots */
|
|
45
49
|
class Hodographs extends PlotComponent {
|
|
46
50
|
/**
|
|
@@ -50,10 +54,8 @@ class Hodographs extends PlotComponent {
|
|
|
50
54
|
*/
|
|
51
55
|
constructor(profile_field, opts) {
|
|
52
56
|
super();
|
|
53
|
-
opts = opts || {};
|
|
54
57
|
this.profile_field = profile_field;
|
|
55
|
-
this.
|
|
56
|
-
this.thin_fac = opts.thin_fac || 1;
|
|
58
|
+
this.opts = normalizeOptions(opts, hodograph_opt_defaults);
|
|
57
59
|
this.hodo_scale = (HODO_BG_DIMS.BB_TEX_WIDTH - LINE_WIDTH / 2) / (HODO_BG_DIMS.BB_TEX_WIDTH * BG_MAX_RING_MAG);
|
|
58
60
|
this.bg_size = 140;
|
|
59
61
|
this.gl_elems = null;
|
|
@@ -72,7 +74,7 @@ class Hodographs extends PlotComponent {
|
|
|
72
74
|
this.gl_elems.bg_billboard.updateField(field.getStormMotionGrid());
|
|
73
75
|
const profiles = this.profile_field.profiles;
|
|
74
76
|
const hodo_polyline = profiles.map(prof => {
|
|
75
|
-
const zoom = getMinZoom(prof['jlat'], prof['ilon'], this.thin_fac);
|
|
77
|
+
const zoom = getMinZoom(prof['jlat'], prof['ilon'], this.opts.thin_fac);
|
|
76
78
|
return {
|
|
77
79
|
'offsets': [...prof['u']].map((u, ipt) => [u - prof['smu'], prof['v'][ipt] - prof['smv']]),
|
|
78
80
|
'vertices': [...prof['u']].map(u => [prof['lon'], prof['lat']]),
|
|
@@ -82,7 +84,7 @@ class Hodographs extends PlotComponent {
|
|
|
82
84
|
});
|
|
83
85
|
const hodo_line = await PolylineCollection.make(gl, hodo_polyline, { line_width: 2.5, cmap: HODO_CMAP, offset_scale: this.hodo_scale * this.bg_size });
|
|
84
86
|
const sm_polyline = profiles.map(prof => {
|
|
85
|
-
const zoom = getMinZoom(prof['jlat'], prof['ilon'], this.thin_fac);
|
|
87
|
+
const zoom = getMinZoom(prof['jlat'], prof['ilon'], this.opts.thin_fac);
|
|
86
88
|
const sm_mag = Math.hypot(prof['smu'], prof['smv']);
|
|
87
89
|
const sm_ang = Math.PI / 2 - Math.atan2(-prof['smv'], -prof['smu']);
|
|
88
90
|
const buffer = 2;
|
|
@@ -93,7 +95,7 @@ class Hodographs extends PlotComponent {
|
|
|
93
95
|
'zoom': zoom
|
|
94
96
|
};
|
|
95
97
|
});
|
|
96
|
-
const sm_line = await PolylineCollection.make(gl, sm_polyline, { line_width: 1.5, color: this.bgcolor, offset_scale: this.hodo_scale * this.bg_size });
|
|
98
|
+
const sm_line = await PolylineCollection.make(gl, sm_polyline, { line_width: 1.5, color: this.opts.bgcolor, offset_scale: this.hodo_scale * this.bg_size });
|
|
97
99
|
this.line_elems = {
|
|
98
100
|
hodo_line: hodo_line, sm_line: sm_line
|
|
99
101
|
};
|
|
@@ -108,7 +110,7 @@ class Hodographs extends PlotComponent {
|
|
|
108
110
|
}
|
|
109
111
|
const bg_image = { 'format': gl.RGBA, 'type': gl.UNSIGNED_BYTE, 'image': HODO_BG_TEXTURE, 'mag_filter': gl.NEAREST };
|
|
110
112
|
const max_zoom = map.getMaxZoom();
|
|
111
|
-
const bg_billboard = new BillboardCollection(this.profile_field.getStormMotionGrid(), this.thin_fac, max_zoom, bg_image, HODO_BG_DIMS, hex2rgb(this.bgcolor), this.bg_size * 0.004);
|
|
113
|
+
const bg_billboard = new BillboardCollection(this.profile_field.getStormMotionGrid(), this.opts.thin_fac, max_zoom, bg_image, HODO_BG_DIMS, hex2rgb(this.opts.bgcolor), this.bg_size * 0.004);
|
|
112
114
|
await bg_billboard.setup(gl);
|
|
113
115
|
this.gl_elems = {
|
|
114
116
|
gl: gl, map: map, bg_billboard: bg_billboard
|
package/lib/Paintball.d.ts
CHANGED
|
@@ -22,8 +22,8 @@ interface PaintballOptions {
|
|
|
22
22
|
*/
|
|
23
23
|
declare class Paintball<ArrayType extends TypedArray, MapType extends MapLikeType> extends PlotComponent<MapType> {
|
|
24
24
|
private field;
|
|
25
|
-
readonly
|
|
26
|
-
readonly
|
|
25
|
+
readonly opts: Required<PaintballOptions>;
|
|
26
|
+
private readonly color_components;
|
|
27
27
|
private gl_elems;
|
|
28
28
|
private fill_texture;
|
|
29
29
|
/**
|
package/lib/Paintball.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PlotComponent, getGLFormatTypeAlignment } from "./PlotComponent";
|
|
2
|
-
import { hex2rgba } from "./utils";
|
|
2
|
+
import { hex2rgba, normalizeOptions } from "./utils";
|
|
3
3
|
import { WGLProgram, WGLTexture } from "autumn-wgl";
|
|
4
4
|
const paintball_vertex_shader_src = `uniform mat4 u_matrix;
|
|
5
5
|
uniform int u_offset;
|
|
@@ -45,6 +45,10 @@ void main() {
|
|
|
45
45
|
color.a = color.a * u_opacity;
|
|
46
46
|
gl_FragColor = color;
|
|
47
47
|
}`
|
|
48
|
+
const paintball_opt_defaults = {
|
|
49
|
+
colors: ['#000000'],
|
|
50
|
+
opacity: 1
|
|
51
|
+
};
|
|
48
52
|
/**
|
|
49
53
|
* A class representing a paintball plot, which is a plot of objects in every member of an ensemble. Objects are usually defined by a single threshold on
|
|
50
54
|
* a field (such as simulated reflectivity greater than 40 dBZ), but could in theory be defined by any arbitrarily complicated method. In autumnplot-gl,
|
|
@@ -63,10 +67,8 @@ class Paintball extends PlotComponent {
|
|
|
63
67
|
constructor(field, opts) {
|
|
64
68
|
super();
|
|
65
69
|
this.field = field;
|
|
66
|
-
opts = opts
|
|
67
|
-
|
|
68
|
-
this.colors = colors.reverse().map(color => hex2rgba(color)).flat();
|
|
69
|
-
this.opacity = opts.opacity !== undefined ? opts.opacity : 1.;
|
|
70
|
+
this.opts = normalizeOptions(opts, paintball_opt_defaults);
|
|
71
|
+
this.color_components = [...this.opts.colors].reverse().map(color => hex2rgba(color)).flat();
|
|
70
72
|
this.gl_elems = null;
|
|
71
73
|
this.fill_texture = null;
|
|
72
74
|
}
|
|
@@ -119,7 +121,7 @@ class Paintball extends PlotComponent {
|
|
|
119
121
|
if (matrix instanceof Float32Array)
|
|
120
122
|
matrix = [...matrix];
|
|
121
123
|
// Render to framebuffer
|
|
122
|
-
gl_elems.program.use({ 'a_pos': gl_elems.vertices, 'a_tex_coord': gl_elems.texcoords }, { 'u_matrix': matrix, 'u_opacity': this.opacity, 'u_colors': this.
|
|
124
|
+
gl_elems.program.use({ 'a_pos': gl_elems.vertices, 'a_tex_coord': gl_elems.texcoords }, { 'u_matrix': matrix, 'u_opacity': this.opts.opacity, 'u_colors': this.color_components, 'u_num_colors': this.opts.colors.length, 'u_offset': 0 }, { 'u_fill_sampler': this.fill_texture });
|
|
123
125
|
gl.enable(gl.BLEND);
|
|
124
126
|
gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
|
125
127
|
gl_elems.program.draw();
|
package/lib/PlotLayer.worker.js
CHANGED
|
@@ -239,6 +239,9 @@ function makePolylinesMiter(lines) {
|
|
|
239
239
|
}
|
|
240
240
|
*/
|
|
241
241
|
function makePolylines(lines) {
|
|
242
|
+
if (lines.length == 0) {
|
|
243
|
+
return { vertices: new Float32Array([]), extrusion: new Float32Array([]) };
|
|
244
|
+
}
|
|
242
245
|
const n_points_per_vert = Object.fromEntries(Object.entries(lines[0]).map(([k, v]) => {
|
|
243
246
|
let n_verts;
|
|
244
247
|
if (typeof v === 'number') {
|