Changes
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* Generates a simple QR-like marker pattern as an ImageBitmap.
|
||||
* This creates a deterministic black/white grid pattern that can be
|
||||
* printed and used as an image tracking target.
|
||||
*
|
||||
* The pattern is 200x200px with a distinctive finder pattern.
|
||||
*/
|
||||
export async function generateTrackingMarker(): Promise<ImageBitmap> {
|
||||
const size = 200;
|
||||
const canvas = new OffscreenCanvas(size, size);
|
||||
const ctx = canvas.getContext('2d')!;
|
||||
|
||||
// White background
|
||||
ctx.fillStyle = '#ffffff';
|
||||
ctx.fillRect(0, 0, size, size);
|
||||
|
||||
const cellSize = size / 10;
|
||||
|
||||
// Draw a distinctive pattern (simplified QR-like finder)
|
||||
ctx.fillStyle = '#000000';
|
||||
|
||||
// Outer border
|
||||
ctx.fillRect(0, 0, size, cellSize);
|
||||
ctx.fillRect(0, size - cellSize, size, cellSize);
|
||||
ctx.fillRect(0, 0, cellSize, size);
|
||||
ctx.fillRect(size - cellSize, 0, cellSize, size);
|
||||
|
||||
// Top-left finder (3x3 block)
|
||||
for (let r = 1; r <= 3; r++) {
|
||||
for (let c = 1; c <= 3; c++) {
|
||||
if (r === 2 && c === 2) {
|
||||
ctx.fillStyle = '#000000';
|
||||
} else if ((r + c) % 2 === 0) {
|
||||
ctx.fillStyle = '#000000';
|
||||
} else {
|
||||
ctx.fillStyle = '#ffffff';
|
||||
}
|
||||
ctx.fillRect(c * cellSize, r * cellSize, cellSize, cellSize);
|
||||
}
|
||||
}
|
||||
|
||||
// Bottom-right finder (3x3 block)
|
||||
ctx.fillStyle = '#000000';
|
||||
for (let r = 6; r <= 8; r++) {
|
||||
for (let c = 6; c <= 8; c++) {
|
||||
if (r === 7 && c === 7) {
|
||||
ctx.fillStyle = '#000000';
|
||||
} else if ((r + c) % 2 === 0) {
|
||||
ctx.fillStyle = '#000000';
|
||||
} else {
|
||||
ctx.fillStyle = '#ffffff';
|
||||
}
|
||||
ctx.fillRect(c * cellSize, r * cellSize, cellSize, cellSize);
|
||||
}
|
||||
}
|
||||
|
||||
// Center cross
|
||||
ctx.fillStyle = '#000000';
|
||||
ctx.fillRect(4 * cellSize, 5 * cellSize, 2 * cellSize, cellSize);
|
||||
ctx.fillRect(5 * cellSize, 4 * cellSize, cellSize, 2 * cellSize);
|
||||
|
||||
// Diagonal accents
|
||||
ctx.fillRect(2 * cellSize, 6 * cellSize, cellSize, cellSize);
|
||||
ctx.fillRect(7 * cellSize, 2 * cellSize, cellSize, cellSize);
|
||||
|
||||
const blob = await canvas.convertToBlob({ type: 'image/png' });
|
||||
return createImageBitmap(blob);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a downloadable PNG of the tracking marker for printing.
|
||||
*/
|
||||
export async function generateMarkerDownloadURL(): Promise<string> {
|
||||
const size = 400; // Larger for print quality
|
||||
const canvas = new OffscreenCanvas(size, size);
|
||||
const ctx = canvas.getContext('2d')!;
|
||||
|
||||
const bitmap = await generateTrackingMarker();
|
||||
ctx.drawImage(bitmap, 0, 0, size, size);
|
||||
|
||||
// Add label
|
||||
ctx.fillStyle = '#000000';
|
||||
ctx.font = 'bold 14px monospace';
|
||||
ctx.textAlign = 'center';
|
||||
|
||||
const blob = await canvas.convertToBlob({ type: 'image/png' });
|
||||
return URL.createObjectURL(blob);
|
||||
}
|
||||
Reference in New Issue
Block a user