diff --git a/static/script.js b/static/script.js index b52ba07f..e5c595e4 100644 --- a/static/script.js +++ b/static/script.js @@ -1777,25 +1777,24 @@ function render(players) { /* ---------- rendering trails ------------------------------- */ function renderTrails(trailData) { - trailsContainer.innerHTML = ''; - const byChar = trailData.reduce((acc, pt) => { - (acc[pt.character_name] = acc[pt.character_name] || []).push(pt); - return acc; - }, {}); - for (const [name, pts] of Object.entries(byChar)) { - if (pts.length < 2) continue; - const points = pts.map(pt => { - const { x, y } = worldToPx(pt.ew, pt.ns); - return `${x},${y}`; - }).join(' '); - const poly = document.createElementNS('http://www.w3.org/2000/svg', 'polyline'); - poly.setAttribute('points', points); - // Use the same color as the player dot for consistency - poly.setAttribute('stroke', getColorFor(name)); - poly.setAttribute('fill', 'none'); - poly.setAttribute('class', 'trail-path'); - trailsContainer.appendChild(poly); - } + trailsContainer.innerHTML = ''; + // Build point strings directly - avoid intermediate arrays + const byChar = {}; + for (const pt of trailData) { + const { x, y } = worldToPx(pt.ew, pt.ns); + const key = pt.character_name; + if (!byChar[key]) byChar[key] = { points: `${x},${y}`, count: 1 }; + else { byChar[key].points += ` ${x},${y}`; byChar[key].count++; } + } + for (const name in byChar) { + if (byChar[name].count < 2) continue; + const poly = document.createElementNS('http://www.w3.org/2000/svg', 'polyline'); + poly.setAttribute('points', byChar[name].points); + poly.setAttribute('stroke', getColorFor(name)); + poly.setAttribute('fill', 'none'); + poly.setAttribute('class', 'trail-path'); + trailsContainer.appendChild(poly); + } } /* ---------- selection centering, focus zoom & blink ------------ */ function selectPlayer(p, x, y) {