Skip to content

Commit a74844a

Browse files
committed
使用path替代text渲染
1 parent 8405ae6 commit a74844a

4 files changed

Lines changed: 27 additions & 35 deletions

File tree

‎src/gensvg.ts‎

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { startSimulation } from './server/physics'
22
import type { ContributionJson, SimulationResult } from './utils'
3-
import { FONT_SIZE, HEIGHT, SCALE, SIZE, TEXT, TEXT_TOP, WIDTH } from './utils'
3+
import { HEIGHT, SCALE, SIZE, WIDTH } from './utils'
44

55
export interface GensvgOptions {
66
username: string
@@ -54,34 +54,25 @@ export async function gensvg({
5454
})
5555
.join('\n')
5656

57-
const textSvg = `
58-
<text
59-
x="${(WIDTH / 2) * SCALE}"
60-
y="${TEXT_TOP * SCALE}"
61-
font-size="${FONT_SIZE}"
62-
font-family="ArialCustom, sans-serif"
63-
text-anchor="middle"
64-
dominant-baseline="hanging"
65-
fill="black"
66-
>
67-
${TEXT}
68-
</text>`
57+
// 用 path 渲染文字路径,与物理碰撞体坐标对齐
58+
// opentype 坐标 → SVG 坐标: svgX = (opentypeX + offsetX) * SCALE, svgY = (HEIGHT - centerY + opentypeY) * SCALE
59+
const textPathsSvg = result.textPaths
60+
.map(({ pathData }) => ` <path d="${pathData}" fill="black" />`)
61+
.join('\n')
62+
63+
const textGroupSvg = `
64+
<g transform="translate(${result.offsetX * SCALE}, ${(HEIGHT - result.centerY) * SCALE}) scale(${SCALE})">
65+
${textPathsSvg}
66+
</g>`
6967

7068
const svg = `<svg
7169
xmlns="http://www.w3.org/2000/svg"
7270
width="${svgWidth}"
7371
height="${svgHeight}"
7472
viewBox="0 0 ${svgWidth} ${svgHeight}"
7573
>
76-
<style>
77-
@font-face {
78-
font-family: "ArialCustom";
79-
src: url("/assets/ARIAL.ttf") format("truetype");
80-
}
81-
</style>
8274
${contributionsSvg}
83-
${textSvg}
75+
${textGroupSvg}
8476
</svg>`
85-
8677
return svg
8778
}

‎src/server/physics.ts‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,8 @@ export async function startSimulation(
239239
pathData: pathData,
240240
rect: rect
241241
})),
242-
textTriangles
242+
textTriangles,
243+
offsetX,
244+
centerY
243245
}
244246
}

‎src/utils/index.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,8 @@ export interface SimulationResult {
3838
contributions: ContributionJson[]
3939
/** 用户名文字碰撞体的三角网格(世界坐标),用于 web 端渲染 */
4040
textTriangles: number[][]
41+
/** 文字在物理世界中的 X 偏移量 */
42+
offsetX: number
43+
/** 文字在物理世界中的 Y 偏移量 */
44+
centerY: number
4145
}

‎src/web/index.ts‎

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -63,21 +63,16 @@ trajectoryRes.contributions.forEach(createContribution)
6363
// svg.appendChild(poly)
6464
// }
6565

66-
// 参考文字:用 SVG <text> 居中渲染,方便对比碰撞体轮廓是否对齐
67-
const textEl = document.createElementNS('http://www.w3.org/2000/svg', 'text')
68-
textEl.textContent = TEXT
69-
textEl.setAttribute('x', `${(WIDTH / 2) * SCALE}`)
70-
textEl.setAttribute('y', `${TEXT_TOP * SCALE}`)
71-
textEl.setAttribute('font-size', `${FONT_SIZE}`)
72-
textEl.setAttribute('font-family', 'ArialCustom, sans-serif')
73-
textEl.setAttribute('text-anchor', 'middle')
74-
textEl.setAttribute('dominant-baseline', 'hanging')
75-
textEl.setAttribute('fill', 'black')
76-
svg.appendChild(textEl)
77-
7866
const g = document.createElementNS('http://www.w3.org/2000/svg', 'g')
67+
// 将 opentype 坐标(Y 轴向上)变换到 SVG 坐标(Y 轴向下),与物理体世界坐标对齐
68+
// 物理世界: worldX = opentypeX + offsetX, worldY = -opentypeY + centerY
69+
// SVG: svgX = worldX * SCALE, svgY = (HEIGHT - worldY) * SCALE
70+
// 合并: svgX = (opentypeX + offsetX) * SCALE, svgY = (HEIGHT - centerY + opentypeY) * SCALE
71+
g.setAttribute(
72+
'transform',
73+
`translate(${trajectoryRes.offsetX * SCALE}, ${(HEIGHT - trajectoryRes.centerY) * SCALE}) scale(${SCALE})`
74+
)
7975
svg.appendChild(g)
80-
g.style.transform = `scale(${SCALE}) translate(0, ${TEXT_TOP}px)`
8176

8277
trajectoryRes.textPaths.forEach(({ pathData, rect }) => {
8378
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')

0 commit comments

Comments
 (0)