完善样式系统与调试链路底座
This commit is contained in:
@@ -9,6 +9,25 @@ export interface ScreenPoint {
|
||||
y: number
|
||||
}
|
||||
|
||||
function smoothTrackScreenPoints(points: ScreenPoint[]): ScreenPoint[] {
|
||||
if (points.length < 3) {
|
||||
return points
|
||||
}
|
||||
|
||||
const smoothed: ScreenPoint[] = [points[0]]
|
||||
for (let index = 1; index < points.length - 1; index += 1) {
|
||||
const prev = points[index - 1]
|
||||
const current = points[index]
|
||||
const next = points[index + 1]
|
||||
smoothed.push({
|
||||
x: prev.x * 0.2 + current.x * 0.6 + next.x * 0.2,
|
||||
y: prev.y * 0.2 + current.y * 0.6 + next.y * 0.2,
|
||||
})
|
||||
}
|
||||
smoothed.push(points[points.length - 1])
|
||||
return smoothed
|
||||
}
|
||||
|
||||
function buildVectorCamera(scene: MapScene): CameraState {
|
||||
return {
|
||||
centerWorldX: scene.exactCenterWorldX,
|
||||
@@ -31,7 +50,10 @@ export class TrackLayer implements MapLayer {
|
||||
|
||||
draw(context: LayerRenderContext): void {
|
||||
const { ctx, scene } = context
|
||||
const points = this.projectPoints(scene)
|
||||
if (scene.trackMode === 'none') {
|
||||
return
|
||||
}
|
||||
const points = smoothTrackScreenPoints(this.projectPoints(scene))
|
||||
if (!points.length) {
|
||||
return
|
||||
}
|
||||
@@ -39,34 +61,42 @@ export class TrackLayer implements MapLayer {
|
||||
ctx.save()
|
||||
ctx.lineCap = 'round'
|
||||
ctx.lineJoin = 'round'
|
||||
ctx.strokeStyle = 'rgba(23, 109, 93, 0.96)'
|
||||
ctx.lineWidth = 6
|
||||
ctx.beginPath()
|
||||
|
||||
points.forEach((screenPoint, index) => {
|
||||
if (index === 0) {
|
||||
ctx.moveTo(screenPoint.x, screenPoint.y)
|
||||
return
|
||||
}
|
||||
ctx.lineTo(screenPoint.x, screenPoint.y)
|
||||
})
|
||||
ctx.stroke()
|
||||
|
||||
ctx.fillStyle = '#f7fbf2'
|
||||
ctx.strokeStyle = '#176d5d'
|
||||
ctx.lineWidth = 4
|
||||
points.forEach((screenPoint, index) => {
|
||||
if (scene.trackMode === 'tail') {
|
||||
const baseAlpha = 0.12 + scene.trackStyleConfig.glowStrength * 0.08
|
||||
points.forEach((screenPoint, index) => {
|
||||
if (index === 0) {
|
||||
return
|
||||
}
|
||||
const progress = index / Math.max(1, points.length - 1)
|
||||
ctx.strokeStyle = `rgba(84, 243, 216, ${baseAlpha + progress * 0.58})`
|
||||
ctx.lineWidth = 1.4 + progress * 4.2
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(points[index - 1].x, points[index - 1].y)
|
||||
ctx.lineTo(screenPoint.x, screenPoint.y)
|
||||
ctx.stroke()
|
||||
})
|
||||
const head = points[points.length - 1]
|
||||
ctx.fillStyle = 'rgba(84, 243, 216, 0.24)'
|
||||
ctx.beginPath()
|
||||
ctx.arc(screenPoint.x, screenPoint.y, 10, 0, Math.PI * 2)
|
||||
ctx.arc(head.x, head.y, 11, 0, Math.PI * 2)
|
||||
ctx.fill()
|
||||
ctx.fillStyle = '#54f3d8'
|
||||
ctx.beginPath()
|
||||
ctx.arc(head.x, head.y, 5.2, 0, Math.PI * 2)
|
||||
ctx.fill()
|
||||
} else {
|
||||
ctx.strokeStyle = 'rgba(23, 109, 93, 0.96)'
|
||||
ctx.lineWidth = 4.2
|
||||
ctx.beginPath()
|
||||
points.forEach((screenPoint, index) => {
|
||||
if (index === 0) {
|
||||
ctx.moveTo(screenPoint.x, screenPoint.y)
|
||||
return
|
||||
}
|
||||
ctx.lineTo(screenPoint.x, screenPoint.y)
|
||||
})
|
||||
ctx.stroke()
|
||||
ctx.fillStyle = '#176d5d'
|
||||
ctx.font = 'bold 14px sans-serif'
|
||||
ctx.textAlign = 'center'
|
||||
ctx.textBaseline = 'middle'
|
||||
ctx.fillText(String(index + 1), screenPoint.x, screenPoint.y)
|
||||
ctx.fillStyle = '#f7fbf2'
|
||||
})
|
||||
}
|
||||
ctx.restore()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user