fix: use 1024x700 mask canvas for better shape coverage
Previous 512x512 square mask was too small, causing most words to be excluded. Now uses 1024x700 (16:11 ratio) to match typical chart containers, with r=48% fill for maximum word area. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8fb5caef07
commit
e7d7745f74
|
|
@ -53,24 +53,24 @@ function gradientColor(ratio: number, colors: string[]): string {
|
||||||
* Create a canvas maskImage for the given shape.
|
* Create a canvas maskImage for the given shape.
|
||||||
* White = excluded, Black = where words can be placed.
|
* White = excluded, Black = where words can be placed.
|
||||||
*/
|
*/
|
||||||
function createShapeMask(shape: string, size: number): HTMLCanvasElement | null {
|
function createShapeMask(shape: string, w: number, h: number): HTMLCanvasElement | null {
|
||||||
if (typeof document === 'undefined') return null;
|
if (typeof document === 'undefined') return null;
|
||||||
|
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement('canvas');
|
||||||
canvas.width = size;
|
canvas.width = w;
|
||||||
canvas.height = size;
|
canvas.height = h;
|
||||||
const ctx = canvas.getContext('2d');
|
const ctx = canvas.getContext('2d');
|
||||||
if (!ctx) return null;
|
if (!ctx) return null;
|
||||||
|
|
||||||
// Fill white (excluded area)
|
// Fill white (excluded area)
|
||||||
ctx.fillStyle = '#fff';
|
ctx.fillStyle = '#fff';
|
||||||
ctx.fillRect(0, 0, size, size);
|
ctx.fillRect(0, 0, w, h);
|
||||||
|
|
||||||
// Draw black shape (word area)
|
// Draw black shape (word area) — fill as much as possible
|
||||||
ctx.fillStyle = '#000';
|
ctx.fillStyle = '#000';
|
||||||
const cx = size / 2;
|
const cx = w / 2;
|
||||||
const cy = size / 2;
|
const cy = h / 2;
|
||||||
const r = size * 0.45;
|
const r = Math.min(w, h) * 0.48;
|
||||||
|
|
||||||
switch (shape) {
|
switch (shape) {
|
||||||
case 'circle':
|
case 'circle':
|
||||||
|
|
@ -145,22 +145,23 @@ function createShapeMask(shape: string, size: number): HTMLCanvasElement | null
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Fallback: fill entire canvas (rectangle)
|
// Fallback: fill entire canvas (rectangle)
|
||||||
ctx.fillRect(0, 0, size, size);
|
ctx.fillRect(0, 0, w, h);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return canvas;
|
return canvas;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache mask images to avoid re-creating on every render
|
// Cache mask images keyed by "shape-WxH"
|
||||||
const maskCache = new Map<string, HTMLCanvasElement>();
|
const maskCache = new Map<string, HTMLCanvasElement>();
|
||||||
|
|
||||||
function getMask(shape: string): HTMLCanvasElement | null {
|
function getMask(shape: string, w = 1024, h = 700): HTMLCanvasElement | null {
|
||||||
if (shape === 'rectangle') return null;
|
if (shape === 'rectangle') return null;
|
||||||
const cached = maskCache.get(shape);
|
const key = `${shape}-${w}x${h}`;
|
||||||
|
const cached = maskCache.get(key);
|
||||||
if (cached) return cached;
|
if (cached) return cached;
|
||||||
const mask = createShapeMask(shape, 512);
|
const mask = createShapeMask(shape, w, h);
|
||||||
if (mask) maskCache.set(shape, mask);
|
if (mask) maskCache.set(key, mask);
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue