-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathindex.js
98 lines (91 loc) · 2.87 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
let canvas;
const OPTIONS = {
width: 100,
height: 10
};
// const ISNODE = typeof global === 'object';
let offscreenCanvas = false;
try {
const canvas = new OffscreenCanvas(1, 1);
const ctx = canvas.getContext('2d');
ctx.fillText('hello', 0, 0);
offscreenCanvas = true;
} catch (err) {
offscreenCanvas = false;
}
function getCanvas() {
if (!canvas) {
const { width, height } = OPTIONS;
if (offscreenCanvas) {
canvas = new OffscreenCanvas(width, height);
} else {
canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
}
}
return canvas;
}
export function registerCanvas(canvasInstance) {
if (canvasInstance) {
canvas = canvasInstance;
}
}
export class ColorIn {
constructor(colors, options = {}) {
if (!Array.isArray(colors)) {
console.error('colors is not array');
return;
}
if (colors.length < 2) {
console.error('colors.length should >1');
return;
}
this.colors = colors;
let min = Infinity, max = -Infinity;
for (let i = 0, len = colors.length; i < len; i++) {
const value = colors[i][0];
min = Math.min(value, min);
max = Math.max(value, max);
}
this.min = min;
this.max = max;
this.valueOffset = this.max - this.min;
this.options = Object.assign({}, OPTIONS, options);
this._initImgData();
}
getImageData() {
return this.imgData;
}
_initImgData() {
const canvas = getCanvas();
const { width, height } = this.options;
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d', { willReadFrequently: true });
ctx.clearRect(0, 0, canvas.width, canvas.height);
const gradient = ctx.createLinearGradient(0, 0, canvas.width, 0);
const { colors, valueOffset } = this;
for (let i = 0, len = colors.length; i < len; i++) {
const [stop, color] = colors[i];
const s = (stop - this.min) / valueOffset;
gradient.addColorStop(s, color);
}
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, canvas.width, canvas.height);
this.imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
}
getColor(stop) {
stop = Math.max(this.min, stop);
stop = Math.min(stop, this.max);
const s = (stop - this.min) / this.valueOffset;
let x = Math.round(s * this.imgData.width);
x = Math.min(x, this.imgData.width - 1);
const idx = x * 4;
const r = this.imgData.data[idx];
const g = this.imgData.data[idx + 1];
const b = this.imgData.data[idx + 2];
const a = this.imgData.data[idx + 3];
return [r, g, b, a];
}
}