From 75715ae31dbbb009834c23af9b869bd6206006bf Mon Sep 17 00:00:00 2001 From: Gaubee Date: Sun, 4 Jan 2026 15:29:10 +0800 Subject: [PATCH 1/3] feat(wallet-card): upgrade watermark pattern from square to diamond layout - Create 2x2 tile with icons at diagonal positions (0,0) and (1,1) - When repeated, forms a diamond/brick pattern instead of square grid - Same icon size, denser pattern due to offset rows --- src/components/wallet/refraction/renderer.ts | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/components/wallet/refraction/renderer.ts b/src/components/wallet/refraction/renderer.ts index 54d52a510..0e810e482 100644 --- a/src/components/wallet/refraction/renderer.ts +++ b/src/components/wallet/refraction/renderer.ts @@ -218,9 +218,10 @@ function ensurePatternCache( } /** - * 创建水印 pattern(图标居中在 cell 内) + * 创建水印 pattern(菱形排布) + * 使用 2x2 的 tile,在对角位置放置图标,重复后形成菱形网格 * 逻辑间距固定为 WATERMARK_LOGICAL_SPACING - * @param cellPx cell 物理尺寸(用于创建 tile) + * @param cellPx 单个 cell 的物理尺寸 * @param iconPx 图标物理尺寸 */ function ensureWatermarkCache( @@ -233,19 +234,27 @@ function ensureWatermarkCache( ): PatternCache | null { if (cache && cache.key === key) return cache - const tileSize = cellPx + // 创建 2x2 cell 大小的 tile,实现菱形排布 + const tileSize = cellPx * 2 const tile = new OffscreenCanvas(tileSize, tileSize) const tctx = tile.getContext('2d') if (!tctx) return null tctx.clearRect(0, 0, tile.width, tile.height) - // 图标在 cell 内居中绘制 - const iconOffset = (tileSize - iconPx) / 2 + + // 图标在 cell 内居中的偏移量 + const iconOffset = (cellPx - iconPx) / 2 + + // 位置 1: 左上 cell 的中心 (0.5, 0.5) in cell units tctx.drawImage(image, iconOffset, iconOffset, iconPx, iconPx) + // 位置 2: 右下 cell 的中心 (1.5, 1.5) in cell units + tctx.drawImage(image, cellPx + iconOffset, cellPx + iconOffset, iconPx, iconPx) + const pattern = ctx.createPattern(tile, 'repeat') if (!pattern) return null + // 注意:tileSize 是 2x cellPx,但逻辑间距仍然基于单个 cell return { key, pattern, logicalSpacing: WATERMARK_LOGICAL_SPACING, tileSize } } From 2faf4dbe28d8c09e409bc05a1c8155af0919a343 Mon Sep 17 00:00:00 2001 From: Gaubee Date: Sun, 4 Jan 2026 15:33:40 +0800 Subject: [PATCH 2/3] fix: maintain original watermark density with diamond pattern Double the logicalSpacing (2 -> 4) for the 2x2 tile to keep the same icon density as before the diamond pattern change. --- src/components/wallet/refraction/renderer.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/wallet/refraction/renderer.ts b/src/components/wallet/refraction/renderer.ts index 0e810e482..0f4197871 100644 --- a/src/components/wallet/refraction/renderer.ts +++ b/src/components/wallet/refraction/renderer.ts @@ -254,8 +254,8 @@ function ensureWatermarkCache( const pattern = ctx.createPattern(tile, 'repeat') if (!pattern) return null - // 注意:tileSize 是 2x cellPx,但逻辑间距仍然基于单个 cell - return { key, pattern, logicalSpacing: WATERMARK_LOGICAL_SPACING, tileSize } + // 2x2 tile 需要 2x 的逻辑间距,保持与原来相同的图标密度 + return { key, pattern, logicalSpacing: WATERMARK_LOGICAL_SPACING * 2, tileSize } } function renderMaskedLayer( From e672d379ceebec6bbd7f32e2c8b50ddec5f834b1 Mon Sep 17 00:00:00 2001 From: Gaubee Date: Sun, 4 Jan 2026 15:37:09 +0800 Subject: [PATCH 3/3] fix: use logicalSpacing=3 for better density and pattern offset - Spacing 3 gives moderate density (between 2 and 4) - Doesn't align with texture layer (spacing 1), reducing visual repetition --- src/components/wallet/refraction/renderer.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/wallet/refraction/renderer.ts b/src/components/wallet/refraction/renderer.ts index 0f4197871..aca50910f 100644 --- a/src/components/wallet/refraction/renderer.ts +++ b/src/components/wallet/refraction/renderer.ts @@ -254,8 +254,10 @@ function ensureWatermarkCache( const pattern = ctx.createPattern(tile, 'repeat') if (!pattern) return null - // 2x2 tile 需要 2x 的逻辑间距,保持与原来相同的图标密度 - return { key, pattern, logicalSpacing: WATERMARK_LOGICAL_SPACING * 2, tileSize } + // 使用 3 作为逻辑间距: + // 1. 密度适中(比原来的 2 稍稀,视觉更舒适) + // 2. 与纹理层(间距 1)错开,避免视觉重复 + return { key, pattern, logicalSpacing: 3, tileSize } } function renderMaskedLayer(