@thumbmarkjs/thumbmarkjs
Version:
   • 2.56 kB
text/typescript
import { componentInterface } from '../../factory';
import { getCommonPixels } from '../../utils/commonPixels';
import { hash } from '../../utils/hash';
const _RUNS = 3;
/**
* A simple canvas finger printing function
*
* @returns a CanvasInfo JSON object
*/
const _WIDTH = 280;
const _HEIGHT = 20;
export default async function getCanvas(): Promise<componentInterface | null> {
return generateCanvasFingerprint()
}
export function generateCanvasFingerprint(): Promise<componentInterface> {
return new Promise((resolve) => {
/**
* Since some browsers fudge with the canvas pixels to prevent fingerprinting, the following
* creates the canvas three times and getCommonPixels picks the most common byte for each
* channel of each pixel.
*/
const imageDatas: ImageData[] = Array.from({ length: _RUNS }, () => generateCanvasImageData());
const commonImageData = getCommonPixels(imageDatas, _WIDTH, _HEIGHT);
resolve({
commonPixelsHash: hash(commonImageData.data.toString()).toString(),
});
});
}
function generateCanvasImageData(): ImageData {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
if (!ctx) {
return new ImageData(1, 1);
}
// Set canvas dimensions
canvas.width = _WIDTH;
canvas.height = _HEIGHT;
// Create rainbow gradient for the background rectangle
const gradient = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
gradient.addColorStop(0, 'red');
gradient.addColorStop(1 / 6, 'orange');
gradient.addColorStop(2 / 6, 'yellow');
gradient.addColorStop(3 / 6, 'green');
gradient.addColorStop(4 / 6, 'blue');
gradient.addColorStop(5 / 6, 'indigo');
gradient.addColorStop(1, 'violet');
// Draw background rectangle with the rainbow gradient
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw some random text
const randomText = 'Random Text WMwmil10Oo';
ctx.font = '23.123px Arial';
ctx.fillStyle = 'black';
ctx.fillText(randomText, -5, 15);
// Draw the same text with an offset, different color, and slight transparency
ctx.fillStyle = 'rgba(0, 0, 255, 0.5)';
ctx.fillText(randomText, -3.3, 17.7);
// Draw a line crossing the image at an arbitrary angle
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo((canvas.width * 2) / 7, canvas.height);
ctx.strokeStyle = 'white';
ctx.lineWidth = 2;
ctx.stroke();
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
// Return data URL of the canvas
return imageData;
}