@thumbmarkjs/thumbmarkjs 0.20.2 → 0.20.3
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/package.json +1 -1
- package/src/components/canvas/canvas.ts +74 -71
package/package.json
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
import { componentInterface, includeComponent } from '../../factory'
|
|
2
|
-
import { hash } from '../../utils/hash'
|
|
1
|
+
import { componentInterface, includeComponent } from '../../factory';
|
|
3
2
|
import { getCommonPixels } from '../../utils/commonPixels';
|
|
3
|
+
import { hash } from '../../utils/hash';
|
|
4
4
|
import { getBrowser } from '../system/browser';
|
|
5
5
|
|
|
6
|
-
const
|
|
6
|
+
const browser = getBrowser();
|
|
7
|
+
const name = browser.name.toLowerCase();
|
|
8
|
+
const ver = browser.version.split('.')[0] || '0';
|
|
9
|
+
const majorVer = parseInt(ver, 10);
|
|
10
|
+
|
|
11
|
+
const _RUNS = name !== 'samsungbrowser' ? 1 : 3;
|
|
7
12
|
|
|
8
13
|
/**
|
|
9
14
|
* A simple canvas finger printing function
|
|
10
|
-
*
|
|
15
|
+
*
|
|
11
16
|
* @returns a CanvasInfo JSON object
|
|
12
17
|
*/
|
|
13
18
|
|
|
@@ -15,76 +20,74 @@ const _WIDTH = 280;
|
|
|
15
20
|
const _HEIGHT = 20;
|
|
16
21
|
|
|
17
22
|
export default function generateCanvasFingerprint(): Promise<componentInterface> {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
{
|
|
33
|
-
'commonImageDataHash': hash(commonImageData.data.toString()).toString(),
|
|
34
|
-
}
|
|
35
|
-
)
|
|
23
|
+
const canvas = document.createElement('canvas');
|
|
24
|
+
const ctx = canvas.getContext('2d');
|
|
25
|
+
|
|
26
|
+
return new Promise((resolve) => {
|
|
27
|
+
/**
|
|
28
|
+
* Since some browsers fudge with the canvas pixels to prevent fingerprinting, the following
|
|
29
|
+
* creates the canvas three times and getCommonPixels picks the most common byte for each
|
|
30
|
+
* channel of each pixel.
|
|
31
|
+
*/
|
|
32
|
+
const imageDatas: ImageData[] = Array.from({ length: _RUNS }, () => generateCanvasImageData());
|
|
33
|
+
const commonImageData = getCommonPixels(imageDatas, _WIDTH, _HEIGHT);
|
|
34
|
+
|
|
35
|
+
resolve({
|
|
36
|
+
commonImageDataHash: hash(commonImageData.data.toString()).toString(),
|
|
36
37
|
});
|
|
38
|
+
});
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
function generateCanvasImageData(): ImageData {
|
|
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
|
-
|
|
42
|
+
const canvas = document.createElement('canvas');
|
|
43
|
+
const ctx = canvas.getContext('2d');
|
|
44
|
+
|
|
45
|
+
if (!ctx) {
|
|
46
|
+
return new ImageData(1, 1);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Set canvas dimensions
|
|
50
|
+
canvas.width = _WIDTH;
|
|
51
|
+
canvas.height = _HEIGHT;
|
|
52
|
+
|
|
53
|
+
// Create rainbow gradient for the background rectangle
|
|
54
|
+
const gradient = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
|
|
55
|
+
gradient.addColorStop(0, 'red');
|
|
56
|
+
gradient.addColorStop(1 / 6, 'orange');
|
|
57
|
+
gradient.addColorStop(2 / 6, 'yellow');
|
|
58
|
+
gradient.addColorStop(3 / 6, 'green');
|
|
59
|
+
gradient.addColorStop(4 / 6, 'blue');
|
|
60
|
+
gradient.addColorStop(5 / 6, 'indigo');
|
|
61
|
+
gradient.addColorStop(1, 'violet');
|
|
62
|
+
|
|
63
|
+
// Draw background rectangle with the rainbow gradient
|
|
64
|
+
ctx.fillStyle = gradient;
|
|
65
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
66
|
+
|
|
67
|
+
// Draw some random text
|
|
68
|
+
const randomText = 'Random Text WMwmil10Oo';
|
|
69
|
+
ctx.font = '23.123px Arial';
|
|
70
|
+
ctx.fillStyle = 'black';
|
|
71
|
+
ctx.fillText(randomText, -5, 15);
|
|
72
|
+
|
|
73
|
+
// Draw the same text with an offset, different color, and slight transparency
|
|
74
|
+
ctx.fillStyle = 'rgba(0, 0, 255, 0.5)';
|
|
75
|
+
ctx.fillText(randomText, -3.3, 17.7);
|
|
76
|
+
|
|
77
|
+
// Draw a line crossing the image at an arbitrary angle
|
|
78
|
+
ctx.beginPath();
|
|
79
|
+
ctx.moveTo(0, 0);
|
|
80
|
+
ctx.lineTo((canvas.width * 2) / 7, canvas.height);
|
|
81
|
+
ctx.strokeStyle = 'white';
|
|
82
|
+
ctx.lineWidth = 2;
|
|
83
|
+
ctx.stroke();
|
|
84
|
+
|
|
85
|
+
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
86
|
+
// Return data URL of the canvas
|
|
87
|
+
return imageData;
|
|
86
88
|
}
|
|
87
89
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
// In Safari from version 17 in private and normal modes canvas differs
|
|
91
|
+
if (name !== 'firefox' && !(name === 'safari' && majorVer === 17)) {
|
|
92
|
+
includeComponent('canvas', generateCanvasFingerprint);
|
|
93
|
+
}
|