summaryrefslogtreecommitdiff
path: root/web/frontend/ride-detail-canvas.ts
diff options
context:
space:
mode:
authorMartin Kagamino Lehoux <martin@lehoux.net>2026-08-17 09:06:41 +0200
committerMartin Kagamino Lehoux <martin@lehoux.net>2026-08-17 09:06:41 +0200
commit2a20ea69a3d62c32c09e62e756a872a3042372b2 (patch)
treee57fb5a35ba19ae252fb32f7f95e9f585d7973d7 /web/frontend/ride-detail-canvas.ts
parentfcbfad33a8e8fdb671d2907b55a8074df9a558e6 (diff)
feat(web): refine ride profile climb labels
Diffstat (limited to 'web/frontend/ride-detail-canvas.ts')
-rw-r--r--web/frontend/ride-detail-canvas.ts19
1 files changed, 14 insertions, 5 deletions
diff --git a/web/frontend/ride-detail-canvas.ts b/web/frontend/ride-detail-canvas.ts
index c61afee..23f9621 100644
--- a/web/frontend/ride-detail-canvas.ts
+++ b/web/frontend/ride-detail-canvas.ts
@@ -137,11 +137,20 @@ export class RideProfileCanvas {
const endX = clamp(this.xForDistance(metrics.end.distanceKm), plot.left, plot.right);
this.context.fillStyle = climbIndex === this.focusedClimbIndex ? this.colors.climbFocusFill : this.colors.accentFill;
this.context.fillRect(startX, plot.top, Math.max(endX - startX, 1), plot.bottom - plot.top);
- const label = formatClimbLabel(climb.name, metrics.category, metrics.cotacol);
+ const label = formatClimbLabel(climb.name, metrics.category, metrics.cotacol, climb.officialClimbId !== undefined);
this.context.fillStyle = this.colors.climbLabel;
this.context.textAlign = "center";
- this.context.textBaseline = "top";
- this.context.fillText(label, clamp((startX + endX) / 2, plot.left + 24, plot.right - 24), plot.top + 4);
+ this.context.textBaseline = "middle";
+ const labelWidth = this.context.measureText(label).width;
+ const labelX = clamp((startX + endX) / 2, plot.left + 8, plot.right - 8);
+ const labelAngle = -Math.PI / 3;
+ const labelHeight = Math.abs(Math.sin(labelAngle)) * labelWidth + Math.abs(Math.cos(labelAngle)) * 14;
+ const labelY = clamp(plot.top + labelHeight / 2 + 4, plot.top + labelHeight / 2, plot.bottom - labelHeight / 2);
+ this.context.save();
+ this.context.translate(labelX, labelY);
+ this.context.rotate(labelAngle);
+ this.context.fillText(label, 0, 0);
+ this.context.restore();
}
for (const crossing of this.profile.crossings || []) {
@@ -161,7 +170,7 @@ export class RideProfileCanvas {
for (const point of this.points) this.context.lineTo(this.xForDistance(point.distanceKm), this.yForElevation(point.elevationM));
this.context.lineTo(this.xForDistance(this.points[this.points.length - 1].distanceKm), plot.bottom);
this.context.closePath();
- this.context.fillStyle = this.colors.accentFill;
+ this.context.fillStyle = this.colors.profileFill;
this.context.fill();
this.context.beginPath();
for (let index = 0; index < this.points.length; index++) {
@@ -169,7 +178,7 @@ export class RideProfileCanvas {
if (index === 0) this.context.moveTo(this.xForDistance(point.distanceKm), this.yForElevation(point.elevationM));
else this.context.lineTo(this.xForDistance(point.distanceKm), this.yForElevation(point.elevationM));
}
- this.context.strokeStyle = this.colors.accent;
+ this.context.strokeStyle = this.colors.profileLine;
this.context.lineWidth = 2.5;
this.context.stroke();
for (const crossing of this.profile.crossings || []) {