gridviz 2.0.38 → 2.0.40
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/README.md +119 -119
- package/dist/gridviz.js +7945 -8887
- package/dist/gridviz.min.js +1 -1
- package/package.json +77 -78
- package/src/App.js +698 -698
- package/src/BackgroundLayer.js +182 -182
- package/src/BackgroundLayerWMS.js +131 -131
- package/src/Dataset.js +76 -76
- package/src/DatasetComponent.js +103 -103
- package/src/GeoCanvas.js +419 -419
- package/src/LabelLayer.js +190 -190
- package/src/Layer.js +92 -92
- package/src/Legend.js +86 -86
- package/src/LineLayer.js +150 -150
- package/src/Style.js +114 -114
- package/src/Tooltip.js +168 -168
- package/src/dataset/COGeo.js +24 -24
- package/src/dataset/CSVGrid.js +104 -104
- package/src/dataset/GeoTIFF.js +127 -127
- package/src/dataset/GridTile.js +41 -41
- package/src/dataset/ParquetGrid.js +122 -122
- package/src/dataset/TiledGrid.js +296 -296
- package/src/index.js +174 -177
- package/src/legend/ColorCategoryLegend.js +124 -124
- package/src/legend/ColorDiscreteLegend.js +105 -105
- package/src/legend/ColorLegend.js +125 -125
- package/src/legend/SegmentOrientationLegend.js +87 -87
- package/src/legend/SegmentWidthLegend.js +97 -97
- package/src/legend/SizeLegend.js +141 -141
- package/src/style/CompositionStyle.js +300 -300
- package/src/style/ContourStyle.js +54 -54
- package/src/style/DotDensityStyle.js +156 -156
- package/src/style/JoyPlotStyle.js +135 -135
- package/src/style/LegoStyle.js +112 -112
- package/src/style/MosaicStyle.js +107 -107
- package/src/style/NinjaStarStyle.js +124 -124
- package/src/style/PillarStyle.js +230 -230
- package/src/style/SegmentStyle.js +142 -142
- package/src/style/ShapeColorSizeStyle.js +126 -126
- package/src/style/SideCatStyle.js +172 -172
- package/src/style/SideStyle.js +218 -218
- package/src/style/SquareColorCatWGLStyle.js +120 -120
- package/src/style/SquareColorWGLStyle.js +146 -146
- package/src/style/StrokeStyle.js +131 -131
- package/src/style/TanakaStyle.js +160 -160
- package/src/style/TextStyle.js +132 -132
- package/src/utils/Utils.js +35 -35
- package/src/utils/WebGLRectangleColoring.js +106 -106
- package/src/utils/WebGLSquareColoring.js +118 -118
- package/src/utils/WebGLSquareColoringAdvanced.js +230 -230
- package/src/utils/WebGLSquareColoringCatAdvanced.js +133 -133
- package/src/utils/WebGLSquareColoringKS.js +153 -153
- package/src/utils/stretching.js +131 -131
- package/src/utils/webGLUtils.js +71 -71
- package/src/utils/zoomUtils.js +142 -142
- package/src/style/KernelSmoothingOldStyle.js +0 -221
- package/src/style/KernelSmoothingStyle.js +0 -115
- package/src/style/KernelSmoothingWGLStyle.js +0 -130
package/src/style/TextStyle.js
CHANGED
|
@@ -1,132 +1,132 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { Style } from '../Style.js'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
*
|
|
8
|
-
* @author Julien Gaffuri
|
|
9
|
-
*/
|
|
10
|
-
export class TextStyle extends Style {
|
|
11
|
-
/** @param {object} opts */
|
|
12
|
-
constructor(opts) {
|
|
13
|
-
super(opts)
|
|
14
|
-
opts = opts || {}
|
|
15
|
-
|
|
16
|
-
/** The name of the column/attribute of the tabular data where to retrieve the variable for text.
|
|
17
|
-
* @type {string} */
|
|
18
|
-
this.textCol = opts.textCol
|
|
19
|
-
|
|
20
|
-
/** A function returning the text of a cell.
|
|
21
|
-
* @type {function(number,number,import("../Style").Stat|undefined):string} */
|
|
22
|
-
this.text = opts.text || ((v, r, s, z) => 'X')
|
|
23
|
-
|
|
24
|
-
/** The name of the column/attribute of the tabular data where to retrieve the variable for color.
|
|
25
|
-
* @type {string} */
|
|
26
|
-
this.colorCol = opts.colorCol
|
|
27
|
-
|
|
28
|
-
/** A function returning the color of the cell.
|
|
29
|
-
* @type {function(number,number,import("../Style").Stat|undefined):string} */
|
|
30
|
-
this.color = opts.color || (() => '#EA6BAC')
|
|
31
|
-
|
|
32
|
-
/** The name of the column/attribute of the tabular data where to retrieve the variable for font size.
|
|
33
|
-
* @type {string} */
|
|
34
|
-
this.fontSizeCol = opts.fontSizeCol
|
|
35
|
-
|
|
36
|
-
/** A function returning the font size of a cell in geo unit.
|
|
37
|
-
* @type {function(number,number,import("../Style").Stat|undefined,number):number} */
|
|
38
|
-
this.fontSize = opts.fontSize || ((v, r, s, z) => r * 0.8)
|
|
39
|
-
|
|
40
|
-
/** The text font family.
|
|
41
|
-
* @type {string} */
|
|
42
|
-
this.fontFamily = opts.fontFamily || 'Arial'
|
|
43
|
-
|
|
44
|
-
/** The text font weight.
|
|
45
|
-
* @type {string} */
|
|
46
|
-
this.fontWeight = opts.fontWeight || 'bold'
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Draw cells as text.
|
|
51
|
-
*
|
|
52
|
-
* @param {Array.<import("../Dataset").Cell>} cells
|
|
53
|
-
* @param {number} r
|
|
54
|
-
* @param {import("../GeoCanvas").GeoCanvas} cg
|
|
55
|
-
*/
|
|
56
|
-
draw(cells, r, cg) {
|
|
57
|
-
//filter
|
|
58
|
-
if (this.filter) cells = cells.filter(this.filter)
|
|
59
|
-
|
|
60
|
-
//zoom factor
|
|
61
|
-
const zf = cg.getZf()
|
|
62
|
-
|
|
63
|
-
let statText
|
|
64
|
-
if (this.textCol) {
|
|
65
|
-
//compute text variable statistics
|
|
66
|
-
statText = Style.getStatistics(cells, (c) => c[this.textCol], true)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
let statColor
|
|
70
|
-
if (this.colorCol) {
|
|
71
|
-
//compute color variable statistics
|
|
72
|
-
statColor = Style.getStatistics(cells, (c) => c[this.colorCol], true)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
let statFontSize
|
|
76
|
-
if (this.fontSizeCol) {
|
|
77
|
-
//if size is used, sort cells by size so that the biggest are drawn first
|
|
78
|
-
cells.sort((c1, c2) => c2[this.fontSizeCol] - c1[this.fontSizeCol])
|
|
79
|
-
//and compute size variable statistics
|
|
80
|
-
statFontSize = Style.getStatistics(cells, (c) => c[this.fontSizeCol], true)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
//draw with HTML canvas
|
|
84
|
-
//in screen coordinates
|
|
85
|
-
cg.initCanvasTransform()
|
|
86
|
-
|
|
87
|
-
for (let cell of cells) {
|
|
88
|
-
//get cell text
|
|
89
|
-
const text = this.text ? this.text(cell[this.textCol], r, statText) : undefined
|
|
90
|
-
if (text == undefined || text == null || text + '' === '') continue
|
|
91
|
-
|
|
92
|
-
//color
|
|
93
|
-
const col = this.color ? this.color(cell[this.colorCol], r, statColor) : undefined
|
|
94
|
-
if (!col) continue
|
|
95
|
-
cg.ctx.fillStyle = col
|
|
96
|
-
|
|
97
|
-
//font size
|
|
98
|
-
//size - in pixel unit
|
|
99
|
-
const fontSizePix = this.fontSize(cell[this.fontSizeCol], r, statFontSize, zf) / zf
|
|
100
|
-
|
|
101
|
-
//set font
|
|
102
|
-
const fontFamily = this.fontFamily || 'Arial'
|
|
103
|
-
const fontWeight = this.fontWeight || 'bold'
|
|
104
|
-
cg.ctx.font = fontWeight + ' ' + fontSizePix + 'px ' + fontFamily
|
|
105
|
-
|
|
106
|
-
//get offset
|
|
107
|
-
const offset = this.offset(cell, r, zf)
|
|
108
|
-
|
|
109
|
-
//text position
|
|
110
|
-
cg.ctx.textAlign = 'center'
|
|
111
|
-
const tx = cg.geoToPixX(cell.x + r * 0.5 + offset.dx)
|
|
112
|
-
const ty = cg.geoToPixY(cell.y + r * 0.5 + offset.dy) + fontSizePix * 0.3 //it should be 0.5 but 0.3 seems to work better
|
|
113
|
-
|
|
114
|
-
//draw the text
|
|
115
|
-
cg.ctx.fillText(text, tx, ty)
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
//update legends
|
|
119
|
-
this.updateLegends({ style: this, r: r, zf: zf, sColor: statColor })
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Build a function [0,1]->string for characters legend
|
|
124
|
-
*
|
|
125
|
-
* @param {Array.<string>} chars
|
|
126
|
-
* @returns {function(number):string}
|
|
127
|
-
*/
|
|
128
|
-
static getCharLegendFun(chars) {
|
|
129
|
-
const nb = chars.length
|
|
130
|
-
return (t) => (t == 0 ? '' : t == 1 ? chars[nb - 1] : chars[Math.floor(t * nb)])
|
|
131
|
-
}
|
|
132
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { Style } from '../Style.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @author Julien Gaffuri
|
|
9
|
+
*/
|
|
10
|
+
export class TextStyle extends Style {
|
|
11
|
+
/** @param {object} opts */
|
|
12
|
+
constructor(opts) {
|
|
13
|
+
super(opts)
|
|
14
|
+
opts = opts || {}
|
|
15
|
+
|
|
16
|
+
/** The name of the column/attribute of the tabular data where to retrieve the variable for text.
|
|
17
|
+
* @type {string} */
|
|
18
|
+
this.textCol = opts.textCol
|
|
19
|
+
|
|
20
|
+
/** A function returning the text of a cell.
|
|
21
|
+
* @type {function(number,number,import("../Style").Stat|undefined,number):string} */
|
|
22
|
+
this.text = opts.text || ((v, r, s, z) => 'X')
|
|
23
|
+
|
|
24
|
+
/** The name of the column/attribute of the tabular data where to retrieve the variable for color.
|
|
25
|
+
* @type {string} */
|
|
26
|
+
this.colorCol = opts.colorCol
|
|
27
|
+
|
|
28
|
+
/** A function returning the color of the cell.
|
|
29
|
+
* @type {function(number,number,import("../Style").Stat|undefined,number):string} */
|
|
30
|
+
this.color = opts.color || (() => '#EA6BAC')
|
|
31
|
+
|
|
32
|
+
/** The name of the column/attribute of the tabular data where to retrieve the variable for font size.
|
|
33
|
+
* @type {string} */
|
|
34
|
+
this.fontSizeCol = opts.fontSizeCol
|
|
35
|
+
|
|
36
|
+
/** A function returning the font size of a cell in geo unit.
|
|
37
|
+
* @type {function(number,number,import("../Style").Stat|undefined,number):number} */
|
|
38
|
+
this.fontSize = opts.fontSize || ((v, r, s, z) => r * 0.8)
|
|
39
|
+
|
|
40
|
+
/** The text font family.
|
|
41
|
+
* @type {string} */
|
|
42
|
+
this.fontFamily = opts.fontFamily || 'Arial'
|
|
43
|
+
|
|
44
|
+
/** The text font weight.
|
|
45
|
+
* @type {string} */
|
|
46
|
+
this.fontWeight = opts.fontWeight || 'bold'
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Draw cells as text.
|
|
51
|
+
*
|
|
52
|
+
* @param {Array.<import("../Dataset").Cell>} cells
|
|
53
|
+
* @param {number} r
|
|
54
|
+
* @param {import("../GeoCanvas").GeoCanvas} cg
|
|
55
|
+
*/
|
|
56
|
+
draw(cells, r, cg) {
|
|
57
|
+
//filter
|
|
58
|
+
if (this.filter) cells = cells.filter(this.filter)
|
|
59
|
+
|
|
60
|
+
//zoom factor
|
|
61
|
+
const zf = cg.getZf()
|
|
62
|
+
|
|
63
|
+
let statText
|
|
64
|
+
if (this.textCol) {
|
|
65
|
+
//compute text variable statistics
|
|
66
|
+
statText = Style.getStatistics(cells, (c) => c[this.textCol], true)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let statColor
|
|
70
|
+
if (this.colorCol) {
|
|
71
|
+
//compute color variable statistics
|
|
72
|
+
statColor = Style.getStatistics(cells, (c) => c[this.colorCol], true)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let statFontSize
|
|
76
|
+
if (this.fontSizeCol) {
|
|
77
|
+
//if size is used, sort cells by size so that the biggest are drawn first
|
|
78
|
+
cells.sort((c1, c2) => c2[this.fontSizeCol] - c1[this.fontSizeCol])
|
|
79
|
+
//and compute size variable statistics
|
|
80
|
+
statFontSize = Style.getStatistics(cells, (c) => c[this.fontSizeCol], true)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
//draw with HTML canvas
|
|
84
|
+
//in screen coordinates
|
|
85
|
+
cg.initCanvasTransform()
|
|
86
|
+
|
|
87
|
+
for (let cell of cells) {
|
|
88
|
+
//get cell text
|
|
89
|
+
const text = this.text ? this.text(cell[this.textCol], r, statText, zf) : undefined
|
|
90
|
+
if (text == undefined || text == null || text + '' === '') continue
|
|
91
|
+
|
|
92
|
+
//color
|
|
93
|
+
const col = this.color ? this.color(cell[this.colorCol], r, statColor, zf) : undefined
|
|
94
|
+
if (!col) continue
|
|
95
|
+
cg.ctx.fillStyle = col
|
|
96
|
+
|
|
97
|
+
//font size
|
|
98
|
+
//size - in pixel unit
|
|
99
|
+
const fontSizePix = this.fontSize(cell[this.fontSizeCol], r, statFontSize, zf) / zf
|
|
100
|
+
|
|
101
|
+
//set font
|
|
102
|
+
const fontFamily = this.fontFamily || 'Arial'
|
|
103
|
+
const fontWeight = this.fontWeight || 'bold'
|
|
104
|
+
cg.ctx.font = fontWeight + ' ' + fontSizePix + 'px ' + fontFamily
|
|
105
|
+
|
|
106
|
+
//get offset
|
|
107
|
+
const offset = this.offset(cell, r, zf)
|
|
108
|
+
|
|
109
|
+
//text position
|
|
110
|
+
cg.ctx.textAlign = 'center'
|
|
111
|
+
const tx = cg.geoToPixX(cell.x + r * 0.5 + offset.dx)
|
|
112
|
+
const ty = cg.geoToPixY(cell.y + r * 0.5 + offset.dy) + fontSizePix * 0.3 //it should be 0.5 but 0.3 seems to work better
|
|
113
|
+
|
|
114
|
+
//draw the text
|
|
115
|
+
cg.ctx.fillText(text, tx, ty)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
//update legends
|
|
119
|
+
this.updateLegends({ style: this, r: r, zf: zf, sColor: statColor })
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Build a function [0,1]->string for characters legend
|
|
124
|
+
*
|
|
125
|
+
* @param {Array.<string>} chars
|
|
126
|
+
* @returns {function(number):string}
|
|
127
|
+
*/
|
|
128
|
+
static getCharLegendFun(chars) {
|
|
129
|
+
const nb = chars.length
|
|
130
|
+
return (t) => (t == 0 ? '' : t == 1 ? chars[nb - 1] : chars[Math.floor(t * nb)])
|
|
131
|
+
}
|
|
132
|
+
}
|
package/src/utils/Utils.js
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Get the class id from a value and class break values
|
|
6
|
-
*
|
|
7
|
-
* @param {number} v the value
|
|
8
|
-
* @param {Array.<number>} breaks the breaks
|
|
9
|
-
* @returns The class id, from 0 to breaks.length
|
|
10
|
-
*/
|
|
11
|
-
export function getClass(v, breaks) {
|
|
12
|
-
if (!breaks) return
|
|
13
|
-
if (breaks.length == 0) return 0
|
|
14
|
-
if (v <= breaks[0]) return 0
|
|
15
|
-
for (let i = 1; i < breaks.length; i++) if (breaks[i - 1] < v && v <= breaks[i]) return i
|
|
16
|
-
return breaks.length
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export let monitor = false
|
|
20
|
-
|
|
21
|
-
let previousDate
|
|
22
|
-
export function monitorDuration(message) {
|
|
23
|
-
const nowDate = Date.now()
|
|
24
|
-
|
|
25
|
-
//first call
|
|
26
|
-
if (!previousDate) {
|
|
27
|
-
previousDate = nowDate
|
|
28
|
-
console.log(previousDate, message)
|
|
29
|
-
return
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const d = nowDate - previousDate
|
|
33
|
-
previousDate = nowDate
|
|
34
|
-
console.log(d, message)
|
|
35
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Get the class id from a value and class break values
|
|
6
|
+
*
|
|
7
|
+
* @param {number} v the value
|
|
8
|
+
* @param {Array.<number>} breaks the breaks
|
|
9
|
+
* @returns The class id, from 0 to breaks.length
|
|
10
|
+
*/
|
|
11
|
+
export function getClass(v, breaks) {
|
|
12
|
+
if (!breaks) return
|
|
13
|
+
if (breaks.length == 0) return 0
|
|
14
|
+
if (v <= breaks[0]) return 0
|
|
15
|
+
for (let i = 1; i < breaks.length; i++) if (breaks[i - 1] < v && v <= breaks[i]) return i
|
|
16
|
+
return breaks.length
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export let monitor = false
|
|
20
|
+
|
|
21
|
+
let previousDate
|
|
22
|
+
export function monitorDuration(message) {
|
|
23
|
+
const nowDate = Date.now()
|
|
24
|
+
|
|
25
|
+
//first call
|
|
26
|
+
if (!previousDate) {
|
|
27
|
+
previousDate = nowDate
|
|
28
|
+
console.log(previousDate, message)
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const d = nowDate - previousDate
|
|
33
|
+
previousDate = nowDate
|
|
34
|
+
console.log(d, message)
|
|
35
|
+
}
|
|
@@ -1,106 +1,106 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { initShaderProgram, createShader } from './webGLUtils.js'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Everything to easily draw colored rectangles with webGL.
|
|
8
|
-
*/
|
|
9
|
-
export class WebGLRectangleColoring {
|
|
10
|
-
//TODO: add color alpha/opacity
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
*
|
|
14
|
-
* @param {WebGLRenderingContext} gl
|
|
15
|
-
*/
|
|
16
|
-
constructor(gl) {
|
|
17
|
-
this.gl = gl
|
|
18
|
-
|
|
19
|
-
this.program = initShaderProgram(
|
|
20
|
-
gl,
|
|
21
|
-
createShader(
|
|
22
|
-
gl,
|
|
23
|
-
gl.VERTEX_SHADER,
|
|
24
|
-
`
|
|
25
|
-
attribute vec2 pos;
|
|
26
|
-
uniform mat3 mat;
|
|
27
|
-
attribute vec3 color;
|
|
28
|
-
varying vec3 vColor;
|
|
29
|
-
void main() {
|
|
30
|
-
gl_Position = vec4(mat * vec3(pos, 1.0), 1.0);
|
|
31
|
-
vColor = color;
|
|
32
|
-
}
|
|
33
|
-
`
|
|
34
|
-
),
|
|
35
|
-
createShader(
|
|
36
|
-
gl,
|
|
37
|
-
gl.FRAGMENT_SHADER,
|
|
38
|
-
`
|
|
39
|
-
precision mediump float;
|
|
40
|
-
varying vec3 vColor;
|
|
41
|
-
void main(void) {
|
|
42
|
-
gl_FragColor = vec4(vColor, 1.0);
|
|
43
|
-
}`
|
|
44
|
-
)
|
|
45
|
-
)
|
|
46
|
-
gl.useProgram(this.program)
|
|
47
|
-
|
|
48
|
-
//buffer data
|
|
49
|
-
this.verticesBuffer = []
|
|
50
|
-
this.colorsBuffer = []
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/** Add data to vertices/color buffers for color rectangle drawing */
|
|
54
|
-
addRectangleData(x1, x2, y1, y2, cR = 0, cG = 0, cB = 1, cA = 0) {
|
|
55
|
-
//TODO cA
|
|
56
|
-
//add vertices
|
|
57
|
-
this.verticesBuffer.push(x1, y1, x2, y1, x1, y2, x2, y2)
|
|
58
|
-
|
|
59
|
-
//colors, 3 parts (RGB), one per vertice
|
|
60
|
-
this.colorsBuffer.push(cR, cG, cB, cR, cG, cB, cR, cG, cB, cR, cG, cB)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/** */
|
|
64
|
-
draw(transfoMat) {
|
|
65
|
-
const gl = this.gl
|
|
66
|
-
|
|
67
|
-
//vertice data
|
|
68
|
-
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer())
|
|
69
|
-
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.verticesBuffer), gl.STATIC_DRAW)
|
|
70
|
-
const position = gl.getAttribLocation(this.program, 'pos')
|
|
71
|
-
gl.vertexAttribPointer(
|
|
72
|
-
position,
|
|
73
|
-
2, //numComponents
|
|
74
|
-
gl.FLOAT, //type
|
|
75
|
-
false, //normalise
|
|
76
|
-
0, //stride
|
|
77
|
-
0 //offset
|
|
78
|
-
)
|
|
79
|
-
gl.enableVertexAttribArray(position)
|
|
80
|
-
|
|
81
|
-
//color data
|
|
82
|
-
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer())
|
|
83
|
-
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.colorsBuffer), gl.STATIC_DRAW)
|
|
84
|
-
var color = gl.getAttribLocation(this.program, 'color')
|
|
85
|
-
gl.vertexAttribPointer(color, 3, gl.FLOAT, false, 0, 0)
|
|
86
|
-
gl.enableVertexAttribArray(color)
|
|
87
|
-
|
|
88
|
-
//transformation
|
|
89
|
-
gl.uniformMatrix3fv(gl.getUniformLocation(this.program, 'mat'), false, new Float32Array(transfoMat))
|
|
90
|
-
|
|
91
|
-
// Enable the depth test
|
|
92
|
-
//gl.enable(gl.DEPTH_TEST);
|
|
93
|
-
// Clear the color buffer bit
|
|
94
|
-
gl.clear(gl.COLOR_BUFFER_BIT)
|
|
95
|
-
// Set the view port
|
|
96
|
-
//gl.viewport(0, 0, cg.w, cg.h);
|
|
97
|
-
|
|
98
|
-
for (let i = 0; i < this.verticesBuffer.length / 8; i++) {
|
|
99
|
-
gl.drawArrays(
|
|
100
|
-
gl.TRIANGLE_STRIP, // mode,see https://miro.medium.com/max/700/0*HQHB5lCGqlOUiysy.jpg
|
|
101
|
-
i * 4, // vertex list start
|
|
102
|
-
4 // vertex count
|
|
103
|
-
)
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { initShaderProgram, createShader } from './webGLUtils.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Everything to easily draw colored rectangles with webGL.
|
|
8
|
+
*/
|
|
9
|
+
export class WebGLRectangleColoring {
|
|
10
|
+
//TODO: add color alpha/opacity
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* @param {WebGLRenderingContext} gl
|
|
15
|
+
*/
|
|
16
|
+
constructor(gl) {
|
|
17
|
+
this.gl = gl
|
|
18
|
+
|
|
19
|
+
this.program = initShaderProgram(
|
|
20
|
+
gl,
|
|
21
|
+
createShader(
|
|
22
|
+
gl,
|
|
23
|
+
gl.VERTEX_SHADER,
|
|
24
|
+
`
|
|
25
|
+
attribute vec2 pos;
|
|
26
|
+
uniform mat3 mat;
|
|
27
|
+
attribute vec3 color;
|
|
28
|
+
varying vec3 vColor;
|
|
29
|
+
void main() {
|
|
30
|
+
gl_Position = vec4(mat * vec3(pos, 1.0), 1.0);
|
|
31
|
+
vColor = color;
|
|
32
|
+
}
|
|
33
|
+
`
|
|
34
|
+
),
|
|
35
|
+
createShader(
|
|
36
|
+
gl,
|
|
37
|
+
gl.FRAGMENT_SHADER,
|
|
38
|
+
`
|
|
39
|
+
precision mediump float;
|
|
40
|
+
varying vec3 vColor;
|
|
41
|
+
void main(void) {
|
|
42
|
+
gl_FragColor = vec4(vColor, 1.0);
|
|
43
|
+
}`
|
|
44
|
+
)
|
|
45
|
+
)
|
|
46
|
+
gl.useProgram(this.program)
|
|
47
|
+
|
|
48
|
+
//buffer data
|
|
49
|
+
this.verticesBuffer = []
|
|
50
|
+
this.colorsBuffer = []
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Add data to vertices/color buffers for color rectangle drawing */
|
|
54
|
+
addRectangleData(x1, x2, y1, y2, cR = 0, cG = 0, cB = 1, cA = 0) {
|
|
55
|
+
//TODO cA
|
|
56
|
+
//add vertices
|
|
57
|
+
this.verticesBuffer.push(x1, y1, x2, y1, x1, y2, x2, y2)
|
|
58
|
+
|
|
59
|
+
//colors, 3 parts (RGB), one per vertice
|
|
60
|
+
this.colorsBuffer.push(cR, cG, cB, cR, cG, cB, cR, cG, cB, cR, cG, cB)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** */
|
|
64
|
+
draw(transfoMat) {
|
|
65
|
+
const gl = this.gl
|
|
66
|
+
|
|
67
|
+
//vertice data
|
|
68
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer())
|
|
69
|
+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.verticesBuffer), gl.STATIC_DRAW)
|
|
70
|
+
const position = gl.getAttribLocation(this.program, 'pos')
|
|
71
|
+
gl.vertexAttribPointer(
|
|
72
|
+
position,
|
|
73
|
+
2, //numComponents
|
|
74
|
+
gl.FLOAT, //type
|
|
75
|
+
false, //normalise
|
|
76
|
+
0, //stride
|
|
77
|
+
0 //offset
|
|
78
|
+
)
|
|
79
|
+
gl.enableVertexAttribArray(position)
|
|
80
|
+
|
|
81
|
+
//color data
|
|
82
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer())
|
|
83
|
+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.colorsBuffer), gl.STATIC_DRAW)
|
|
84
|
+
var color = gl.getAttribLocation(this.program, 'color')
|
|
85
|
+
gl.vertexAttribPointer(color, 3, gl.FLOAT, false, 0, 0)
|
|
86
|
+
gl.enableVertexAttribArray(color)
|
|
87
|
+
|
|
88
|
+
//transformation
|
|
89
|
+
gl.uniformMatrix3fv(gl.getUniformLocation(this.program, 'mat'), false, new Float32Array(transfoMat))
|
|
90
|
+
|
|
91
|
+
// Enable the depth test
|
|
92
|
+
//gl.enable(gl.DEPTH_TEST);
|
|
93
|
+
// Clear the color buffer bit
|
|
94
|
+
gl.clear(gl.COLOR_BUFFER_BIT)
|
|
95
|
+
// Set the view port
|
|
96
|
+
//gl.viewport(0, 0, cg.w, cg.h);
|
|
97
|
+
|
|
98
|
+
for (let i = 0; i < this.verticesBuffer.length / 8; i++) {
|
|
99
|
+
gl.drawArrays(
|
|
100
|
+
gl.TRIANGLE_STRIP, // mode,see https://miro.medium.com/max/700/0*HQHB5lCGqlOUiysy.jpg
|
|
101
|
+
i * 4, // vertex list start
|
|
102
|
+
4 // vertex count
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|