gridviz 2.1.9 → 2.1.11
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 +125 -125
- package/dist/gridviz.js +8036 -8024
- package/dist/gridviz.min.js +1 -1
- package/package.json +77 -77
- package/src/App.js +705 -705
- package/src/BackgroundLayer.js +182 -182
- package/src/BackgroundLayerWMS.js +131 -131
- package/src/Dataset.js +76 -76
- package/src/DatasetComponent.js +113 -101
- package/src/GeoCanvas.js +420 -420
- package/src/LabelLayer.js +190 -190
- package/src/Layer.js +103 -103
- package/src/Legend.js +86 -86
- package/src/LineLayer.js +150 -150
- package/src/Style.js +129 -129
- package/src/Tooltip.js +180 -180
- 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/LGrid.js +54 -54
- package/src/dataset/TiledGrid.js +264 -264
- package/src/index.js +71 -71
- package/src/legend/ColorCategoryLegend.js +124 -124
- package/src/legend/ColorDiscreteLegend.js +103 -103
- package/src/legend/ColorLegend.js +124 -124
- 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/IsoFenceStyle.js +262 -262
- 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 +125 -125
- 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 +216 -216
- 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/style/TimeSeriesStyle.js +250 -250
- 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
|
@@ -1,135 +1,135 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { Style } from '../Style.js'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
*
|
|
8
|
-
* @author Julien Gaffuri
|
|
9
|
-
*/
|
|
10
|
-
export class JoyPlotStyle extends Style {
|
|
11
|
-
/** @param {object} opts */
|
|
12
|
-
constructor(opts) {
|
|
13
|
-
super(opts)
|
|
14
|
-
opts = opts || {}
|
|
15
|
-
|
|
16
|
-
/** The cell column where to get the value to represent.
|
|
17
|
-
* @type {string} */
|
|
18
|
-
this.heightCol = opts.heightCol
|
|
19
|
-
|
|
20
|
-
/** A function returning the height of a cell.
|
|
21
|
-
* @type {function(number,number,import("../Style").Stat|undefined,number):number} */
|
|
22
|
-
this.height = opts.height || ((v) => Math.sqrt(v))
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* @type {function(number,{min:number, max:number},number,number):string} */
|
|
26
|
-
this.lineColor = opts.lineColor || ((y, ys, r, zf) => '#BBB')
|
|
27
|
-
/**
|
|
28
|
-
* @type {function(number,{min:number, max:number},number,number):number} */
|
|
29
|
-
this.lineWidth = opts.lineWidth || ((y, ys, r, zf) => zf)
|
|
30
|
-
/**
|
|
31
|
-
* @type {function(number,{min:number, max:number},number,number):string} */
|
|
32
|
-
this.fillColor = opts.fillColor || ((y, ys, r, zf) => '#c08c5968')
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Draw cells as squares depending on their value.
|
|
37
|
-
*
|
|
38
|
-
* @param {Array.<import("../Dataset").Cell>} cells
|
|
39
|
-
* @param {number} r
|
|
40
|
-
* @param {import("../GeoCanvas").GeoCanvas} cg
|
|
41
|
-
* */
|
|
42
|
-
draw(cells, r, cg) {
|
|
43
|
-
//filter
|
|
44
|
-
if (this.filter) cells = cells.filter(this.filter)
|
|
45
|
-
|
|
46
|
-
cg.ctx.lineJoin = 'round'
|
|
47
|
-
|
|
48
|
-
//zoom factor
|
|
49
|
-
const zf = cg.getZf()
|
|
50
|
-
|
|
51
|
-
//compute statistics
|
|
52
|
-
const stat = Style.getStatistics(cells, (c) => c[this.heightCol], true)
|
|
53
|
-
|
|
54
|
-
//index cells by y and x
|
|
55
|
-
/** @type {object} */
|
|
56
|
-
const ind = {}
|
|
57
|
-
for (const cell of cells) {
|
|
58
|
-
let row = ind[cell.y]
|
|
59
|
-
if (!row) {
|
|
60
|
-
row = {}
|
|
61
|
-
ind[cell.y] = row
|
|
62
|
-
}
|
|
63
|
-
row[cell.x] = this.height(cell[this.heightCol], r, stat, zf)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
//compute extent
|
|
67
|
-
const e = cg.extGeo
|
|
68
|
-
if (!e) return
|
|
69
|
-
const xMin = Math.floor(e.xMin / r) * r
|
|
70
|
-
const xMax = Math.floor(e.xMax / r) * r
|
|
71
|
-
const yMin = Math.floor(e.yMin / r) * r
|
|
72
|
-
const yMax = Math.floor(e.yMax / r) * r
|
|
73
|
-
|
|
74
|
-
/** @type {{min:number, max:number}} */
|
|
75
|
-
const ys = { min: yMin, max: yMax }
|
|
76
|
-
|
|
77
|
-
//draw in geo coordinates
|
|
78
|
-
cg.setCanvasTransform()
|
|
79
|
-
|
|
80
|
-
//draw lines, row by row, stating from the top
|
|
81
|
-
for (let y = yMax; y >= yMin; y -= r) {
|
|
82
|
-
//get row
|
|
83
|
-
const row = ind[y]
|
|
84
|
-
|
|
85
|
-
//no row
|
|
86
|
-
if (!row) continue
|
|
87
|
-
|
|
88
|
-
//place first point
|
|
89
|
-
cg.ctx.beginPath()
|
|
90
|
-
cg.ctx.moveTo(xMin - r / 2, y)
|
|
91
|
-
|
|
92
|
-
//store the previous height
|
|
93
|
-
/** @type {number|undefined} */
|
|
94
|
-
let hG_
|
|
95
|
-
|
|
96
|
-
//go through the line cells
|
|
97
|
-
for (let x = xMin; x <= xMax; x += r) {
|
|
98
|
-
//get column value
|
|
99
|
-
/** @type {number} */
|
|
100
|
-
let hG = row[x]
|
|
101
|
-
if (!hG) hG = 0
|
|
102
|
-
|
|
103
|
-
if (hG || hG_) {
|
|
104
|
-
//draw line only when at least one of both values is non-null
|
|
105
|
-
//TODO test bezierCurveTo
|
|
106
|
-
cg.ctx.lineTo(x + r / 2, y + hG)
|
|
107
|
-
} else {
|
|
108
|
-
//else move the point
|
|
109
|
-
cg.ctx.moveTo(x + r / 2, y)
|
|
110
|
-
}
|
|
111
|
-
//store the previous value
|
|
112
|
-
hG_ = hG
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
//last point
|
|
116
|
-
if (hG_) cg.ctx.lineTo(xMax + r / 2, y)
|
|
117
|
-
|
|
118
|
-
//draw fill
|
|
119
|
-
const fc = this.fillColor(y, ys, r, zf)
|
|
120
|
-
if (fc && fc != 'none') {
|
|
121
|
-
cg.ctx.fillStyle = fc
|
|
122
|
-
cg.ctx.fill()
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
//draw line
|
|
126
|
-
const lc = this.lineColor(y, ys, r, zf)
|
|
127
|
-
const lw = this.lineWidth(y, ys, r, zf)
|
|
128
|
-
if (lc && lc != 'none' && lw > 0) {
|
|
129
|
-
cg.ctx.strokeStyle = lc
|
|
130
|
-
cg.ctx.lineWidth = lw
|
|
131
|
-
cg.ctx.stroke()
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { Style } from '../Style.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @author Julien Gaffuri
|
|
9
|
+
*/
|
|
10
|
+
export class JoyPlotStyle extends Style {
|
|
11
|
+
/** @param {object} opts */
|
|
12
|
+
constructor(opts) {
|
|
13
|
+
super(opts)
|
|
14
|
+
opts = opts || {}
|
|
15
|
+
|
|
16
|
+
/** The cell column where to get the value to represent.
|
|
17
|
+
* @type {string} */
|
|
18
|
+
this.heightCol = opts.heightCol
|
|
19
|
+
|
|
20
|
+
/** A function returning the height of a cell.
|
|
21
|
+
* @type {function(number,number,import("../Style").Stat|undefined,number):number} */
|
|
22
|
+
this.height = opts.height || ((v) => Math.sqrt(v))
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @type {function(number,{min:number, max:number},number,number):string} */
|
|
26
|
+
this.lineColor = opts.lineColor || ((y, ys, r, zf) => '#BBB')
|
|
27
|
+
/**
|
|
28
|
+
* @type {function(number,{min:number, max:number},number,number):number} */
|
|
29
|
+
this.lineWidth = opts.lineWidth || ((y, ys, r, zf) => zf)
|
|
30
|
+
/**
|
|
31
|
+
* @type {function(number,{min:number, max:number},number,number):string} */
|
|
32
|
+
this.fillColor = opts.fillColor || ((y, ys, r, zf) => '#c08c5968')
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Draw cells as squares depending on their value.
|
|
37
|
+
*
|
|
38
|
+
* @param {Array.<import("../Dataset").Cell>} cells
|
|
39
|
+
* @param {number} r
|
|
40
|
+
* @param {import("../GeoCanvas").GeoCanvas} cg
|
|
41
|
+
* */
|
|
42
|
+
draw(cells, r, cg) {
|
|
43
|
+
//filter
|
|
44
|
+
if (this.filter) cells = cells.filter(this.filter)
|
|
45
|
+
|
|
46
|
+
cg.ctx.lineJoin = 'round'
|
|
47
|
+
|
|
48
|
+
//zoom factor
|
|
49
|
+
const zf = cg.getZf()
|
|
50
|
+
|
|
51
|
+
//compute statistics
|
|
52
|
+
const stat = Style.getStatistics(cells, (c) => c[this.heightCol], true)
|
|
53
|
+
|
|
54
|
+
//index cells by y and x
|
|
55
|
+
/** @type {object} */
|
|
56
|
+
const ind = {}
|
|
57
|
+
for (const cell of cells) {
|
|
58
|
+
let row = ind[cell.y]
|
|
59
|
+
if (!row) {
|
|
60
|
+
row = {}
|
|
61
|
+
ind[cell.y] = row
|
|
62
|
+
}
|
|
63
|
+
row[cell.x] = this.height(cell[this.heightCol], r, stat, zf)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
//compute extent
|
|
67
|
+
const e = cg.extGeo
|
|
68
|
+
if (!e) return
|
|
69
|
+
const xMin = Math.floor(e.xMin / r) * r
|
|
70
|
+
const xMax = Math.floor(e.xMax / r) * r
|
|
71
|
+
const yMin = Math.floor(e.yMin / r) * r
|
|
72
|
+
const yMax = Math.floor(e.yMax / r) * r
|
|
73
|
+
|
|
74
|
+
/** @type {{min:number, max:number}} */
|
|
75
|
+
const ys = { min: yMin, max: yMax }
|
|
76
|
+
|
|
77
|
+
//draw in geo coordinates
|
|
78
|
+
cg.setCanvasTransform()
|
|
79
|
+
|
|
80
|
+
//draw lines, row by row, stating from the top
|
|
81
|
+
for (let y = yMax; y >= yMin; y -= r) {
|
|
82
|
+
//get row
|
|
83
|
+
const row = ind[y]
|
|
84
|
+
|
|
85
|
+
//no row
|
|
86
|
+
if (!row) continue
|
|
87
|
+
|
|
88
|
+
//place first point
|
|
89
|
+
cg.ctx.beginPath()
|
|
90
|
+
cg.ctx.moveTo(xMin - r / 2, y)
|
|
91
|
+
|
|
92
|
+
//store the previous height
|
|
93
|
+
/** @type {number|undefined} */
|
|
94
|
+
let hG_
|
|
95
|
+
|
|
96
|
+
//go through the line cells
|
|
97
|
+
for (let x = xMin; x <= xMax; x += r) {
|
|
98
|
+
//get column value
|
|
99
|
+
/** @type {number} */
|
|
100
|
+
let hG = row[x]
|
|
101
|
+
if (!hG) hG = 0
|
|
102
|
+
|
|
103
|
+
if (hG || hG_) {
|
|
104
|
+
//draw line only when at least one of both values is non-null
|
|
105
|
+
//TODO test bezierCurveTo
|
|
106
|
+
cg.ctx.lineTo(x + r / 2, y + hG)
|
|
107
|
+
} else {
|
|
108
|
+
//else move the point
|
|
109
|
+
cg.ctx.moveTo(x + r / 2, y)
|
|
110
|
+
}
|
|
111
|
+
//store the previous value
|
|
112
|
+
hG_ = hG
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
//last point
|
|
116
|
+
if (hG_) cg.ctx.lineTo(xMax + r / 2, y)
|
|
117
|
+
|
|
118
|
+
//draw fill
|
|
119
|
+
const fc = this.fillColor(y, ys, r, zf)
|
|
120
|
+
if (fc && fc != 'none') {
|
|
121
|
+
cg.ctx.fillStyle = fc
|
|
122
|
+
cg.ctx.fill()
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
//draw line
|
|
126
|
+
const lc = this.lineColor(y, ys, r, zf)
|
|
127
|
+
const lw = this.lineWidth(y, ys, r, zf)
|
|
128
|
+
if (lc && lc != 'none' && lw > 0) {
|
|
129
|
+
cg.ctx.strokeStyle = lc
|
|
130
|
+
cg.ctx.lineWidth = lw
|
|
131
|
+
cg.ctx.stroke()
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
package/src/style/LegoStyle.js
CHANGED
|
@@ -1,112 +1,112 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { TanakaStyle } from './TanakaStyle.js'
|
|
5
|
-
import { StrokeStyle } from './StrokeStyle.js'
|
|
6
|
-
import { SquareColorCatWGLStyle } from './SquareColorCatWGLStyle.js'
|
|
7
|
-
import { Style } from '../Style.js'
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* @author Julien Gaffuri
|
|
11
|
-
*/
|
|
12
|
-
export class LegoStyle {
|
|
13
|
-
/**
|
|
14
|
-
* @param {string} col
|
|
15
|
-
* @param {object} opts
|
|
16
|
-
* @returns {Array.<Style>}
|
|
17
|
-
*/
|
|
18
|
-
static get(col, opts) {
|
|
19
|
-
opts = opts || {}
|
|
20
|
-
|
|
21
|
-
//the colors
|
|
22
|
-
//http://www.jennyscrayoncollection.com/2021/06/all-current-lego-colors.html
|
|
23
|
-
//https://leonawicz.github.io/legocolors/reference/figures/README-plot-1.png
|
|
24
|
-
opts.colors = opts.colors || [
|
|
25
|
-
'#00852b', //darker green
|
|
26
|
-
'#afd246', //light green
|
|
27
|
-
'#fac80a', //dark yellow
|
|
28
|
-
'#bb805a', //brown
|
|
29
|
-
'#d67923', //mostard
|
|
30
|
-
'#cb4e29', //redish
|
|
31
|
-
'#b40000', //red
|
|
32
|
-
'#720012', //dark red
|
|
33
|
-
//"purple",
|
|
34
|
-
//"#eee" //whithe
|
|
35
|
-
]
|
|
36
|
-
|
|
37
|
-
opts.colDark = opts.colDark || '#333'
|
|
38
|
-
opts.colBright = opts.colBright || '#aaa'
|
|
39
|
-
opts.widthFactor = opts.widthFactor || 0.12
|
|
40
|
-
|
|
41
|
-
//reuse tanaka as basis
|
|
42
|
-
const ts = TanakaStyle.get(col, opts)
|
|
43
|
-
//style to show limits between pieces
|
|
44
|
-
const sst = new StrokeStyle({
|
|
45
|
-
strokeColor: () => '#666',
|
|
46
|
-
strokeWidth: (v, r, s, z) => 0.2 * z,
|
|
47
|
-
filter: opts.filter,
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
return [
|
|
51
|
-
ts[0],
|
|
52
|
-
sst,
|
|
53
|
-
ts[1],
|
|
54
|
-
new LegoTopStyle({ colDark: opts.colDark, colBright: opts.colBright, filter: opts.filter }),
|
|
55
|
-
]
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* @param {function(string):string} col
|
|
60
|
-
* @param {object} opts
|
|
61
|
-
* @returns {Array.<Style>}
|
|
62
|
-
*/
|
|
63
|
-
static getCat(col, opts) {
|
|
64
|
-
opts = opts || {}
|
|
65
|
-
|
|
66
|
-
opts.colDark = opts.colDark || '#333'
|
|
67
|
-
opts.colBright = opts.colBright || '#aaa'
|
|
68
|
-
|
|
69
|
-
//
|
|
70
|
-
const s = new SquareColorCatWGLStyle({ colorCol: col, color: opts.color })
|
|
71
|
-
//style to show limits between pieces
|
|
72
|
-
const sst = new StrokeStyle({ strokeColor: () => '#666', strokeWidth: (v, r, s, z) => 0.2 * z })
|
|
73
|
-
|
|
74
|
-
return [s, sst, new LegoTopStyle({ colDark: opts.colDark, colBright: opts.colBright })]
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* A style to draw top circle of lego bricks.
|
|
80
|
-
*/
|
|
81
|
-
class LegoTopStyle extends Style {
|
|
82
|
-
/** @param {object|undefined} opts */
|
|
83
|
-
constructor(opts) {
|
|
84
|
-
super(opts)
|
|
85
|
-
opts = opts || {}
|
|
86
|
-
this.colDark = opts.colDark || '#333'
|
|
87
|
-
this.colBright = opts.colBright || '#aaa'
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
draw(cells, r, cg) {
|
|
91
|
-
//filter
|
|
92
|
-
if (this.filter) cells = cells.filter(this.filter)
|
|
93
|
-
|
|
94
|
-
cg.ctx.lineWidth = 0.6 * cg.getZf()
|
|
95
|
-
|
|
96
|
-
//dark part
|
|
97
|
-
cg.ctx.strokeStyle = this.colDark
|
|
98
|
-
for (let c of cells) {
|
|
99
|
-
cg.ctx.beginPath()
|
|
100
|
-
cg.ctx.arc(c.x + r * 0.5, c.y + r * 0.5, r * 0.55 * 0.5, Math.PI / 4, -Math.PI * (3 / 4), true)
|
|
101
|
-
cg.ctx.stroke()
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
//bright part
|
|
105
|
-
cg.ctx.strokeStyle = this.colBright
|
|
106
|
-
for (let c of cells) {
|
|
107
|
-
cg.ctx.beginPath()
|
|
108
|
-
cg.ctx.arc(c.x + r * 0.5, c.y + r * 0.5, r * 0.55 * 0.5, Math.PI / 4, -Math.PI * (3 / 4), false)
|
|
109
|
-
cg.ctx.stroke()
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { TanakaStyle } from './TanakaStyle.js'
|
|
5
|
+
import { StrokeStyle } from './StrokeStyle.js'
|
|
6
|
+
import { SquareColorCatWGLStyle } from './SquareColorCatWGLStyle.js'
|
|
7
|
+
import { Style } from '../Style.js'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @author Julien Gaffuri
|
|
11
|
+
*/
|
|
12
|
+
export class LegoStyle {
|
|
13
|
+
/**
|
|
14
|
+
* @param {string} col
|
|
15
|
+
* @param {object} opts
|
|
16
|
+
* @returns {Array.<Style>}
|
|
17
|
+
*/
|
|
18
|
+
static get(col, opts) {
|
|
19
|
+
opts = opts || {}
|
|
20
|
+
|
|
21
|
+
//the colors
|
|
22
|
+
//http://www.jennyscrayoncollection.com/2021/06/all-current-lego-colors.html
|
|
23
|
+
//https://leonawicz.github.io/legocolors/reference/figures/README-plot-1.png
|
|
24
|
+
opts.colors = opts.colors || [
|
|
25
|
+
'#00852b', //darker green
|
|
26
|
+
'#afd246', //light green
|
|
27
|
+
'#fac80a', //dark yellow
|
|
28
|
+
'#bb805a', //brown
|
|
29
|
+
'#d67923', //mostard
|
|
30
|
+
'#cb4e29', //redish
|
|
31
|
+
'#b40000', //red
|
|
32
|
+
'#720012', //dark red
|
|
33
|
+
//"purple",
|
|
34
|
+
//"#eee" //whithe
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
opts.colDark = opts.colDark || '#333'
|
|
38
|
+
opts.colBright = opts.colBright || '#aaa'
|
|
39
|
+
opts.widthFactor = opts.widthFactor || 0.12
|
|
40
|
+
|
|
41
|
+
//reuse tanaka as basis
|
|
42
|
+
const ts = TanakaStyle.get(col, opts)
|
|
43
|
+
//style to show limits between pieces
|
|
44
|
+
const sst = new StrokeStyle({
|
|
45
|
+
strokeColor: () => '#666',
|
|
46
|
+
strokeWidth: (v, r, s, z) => 0.2 * z,
|
|
47
|
+
filter: opts.filter,
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
return [
|
|
51
|
+
ts[0],
|
|
52
|
+
sst,
|
|
53
|
+
ts[1],
|
|
54
|
+
new LegoTopStyle({ colDark: opts.colDark, colBright: opts.colBright, filter: opts.filter }),
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @param {function(string):string} col
|
|
60
|
+
* @param {object} opts
|
|
61
|
+
* @returns {Array.<Style>}
|
|
62
|
+
*/
|
|
63
|
+
static getCat(col, opts) {
|
|
64
|
+
opts = opts || {}
|
|
65
|
+
|
|
66
|
+
opts.colDark = opts.colDark || '#333'
|
|
67
|
+
opts.colBright = opts.colBright || '#aaa'
|
|
68
|
+
|
|
69
|
+
//
|
|
70
|
+
const s = new SquareColorCatWGLStyle({ colorCol: col, color: opts.color })
|
|
71
|
+
//style to show limits between pieces
|
|
72
|
+
const sst = new StrokeStyle({ strokeColor: () => '#666', strokeWidth: (v, r, s, z) => 0.2 * z })
|
|
73
|
+
|
|
74
|
+
return [s, sst, new LegoTopStyle({ colDark: opts.colDark, colBright: opts.colBright })]
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* A style to draw top circle of lego bricks.
|
|
80
|
+
*/
|
|
81
|
+
class LegoTopStyle extends Style {
|
|
82
|
+
/** @param {object|undefined} opts */
|
|
83
|
+
constructor(opts) {
|
|
84
|
+
super(opts)
|
|
85
|
+
opts = opts || {}
|
|
86
|
+
this.colDark = opts.colDark || '#333'
|
|
87
|
+
this.colBright = opts.colBright || '#aaa'
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
draw(cells, r, cg) {
|
|
91
|
+
//filter
|
|
92
|
+
if (this.filter) cells = cells.filter(this.filter)
|
|
93
|
+
|
|
94
|
+
cg.ctx.lineWidth = 0.6 * cg.getZf()
|
|
95
|
+
|
|
96
|
+
//dark part
|
|
97
|
+
cg.ctx.strokeStyle = this.colDark
|
|
98
|
+
for (let c of cells) {
|
|
99
|
+
cg.ctx.beginPath()
|
|
100
|
+
cg.ctx.arc(c.x + r * 0.5, c.y + r * 0.5, r * 0.55 * 0.5, Math.PI / 4, -Math.PI * (3 / 4), true)
|
|
101
|
+
cg.ctx.stroke()
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
//bright part
|
|
105
|
+
cg.ctx.strokeStyle = this.colBright
|
|
106
|
+
for (let c of cells) {
|
|
107
|
+
cg.ctx.beginPath()
|
|
108
|
+
cg.ctx.arc(c.x + r * 0.5, c.y + r * 0.5, r * 0.55 * 0.5, Math.PI / 4, -Math.PI * (3 / 4), false)
|
|
109
|
+
cg.ctx.stroke()
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|