UNPKG

@thumbmarkjs/thumbmarkjs

Version:

![GitHub package.json dynamic](https://img.shields.io/github/package-json/version/ilkkapeltola/thumbmarkjs) ![NPM Version](https://img.shields.io/npm/v/@thumbmarkjs/thumbmarkjs) ![NPM Downloads](https://img.shields.io/npm/dm/%40thumbmarkjs%2Fthumbmarkjs

84 lines (68 loc) 2.56 kB
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; }