Repository navigation
Slur of a legato slide / hammer-on between two-note chords is not drawn in the standard notation staff when beats are tightly spaced (path with NaN) #2904
Description
Is there an existing issue for this?
- I have searched the existing issues
I have read the contribution rules
- I have read CONTRIBUTING.md and, if any AI agent helped draft this issue, AGENTS.md.
AI authorship
AI-assisted (disclosure block included as described in AGENTS.md)
Current Behavior
Note
AI-authored disclosure (alphatab-ai-authored-v1)
Portions of this content were authored by an AI agent. The agent has read
AGENTS.md and the human submitter accepts responsibility for
compliance with the rules in that document.
When a two-note chord with a legato slide ({sl}) or hammer-on ({h}) is followed by tightly spaced beats, the slur between the two chords is missing from the standard notation staff. The browser console shows an error for the slur's SVG path, whose control points are NaN:
Error: <path> attribute d: Expected number, "…0000001,44.915 CNaN,NaN,NaN,NaN,…".
The d attribute of the affected path (1.8.4, render width 400px):
M122.80787500000001,44.915 CNaN,NaN,NaN,NaN,132.5,49.415 CNaN,NaN,NaN,NaN,122.80787500000001,44.915 z
Whether it happens depends on how tightly the beats are laid out, so the same score renders correctly at one width and loses the slur at a narrower one. Number of paths containing NaN for the snippet below, by render width:
| Version | 1200px | 600px | 400px | 300px |
|---|---|---|---|---|
| 1.8.4 | 0 | 0 | 1 | 1 |
| 1.9.0-alpha.1891 | 0 | 1 | 1 | 1 |
Observations with the same snippet at 400px:
{h}instead of{sl}: same result.- Without the legato effect: no
NaNpath. - Single notes instead of two-note chords: no
NaNpath. \staff {tabs}only: noNaNpath (the tab staff draws its arc).\staff {score}only: theNaNpath appears.
Expected Behavior
The slur between the two chords is drawn in the standard notation staff at any render width (it may be very short when the beats are close together), and no SVG path with NaN is produced.
Steps To Reproduce
- Render this alphaTex with the SVG engine (
core.useWorkers = false,core.enableLazyLoading = false) into a container that is 400px wide:\staff {score tabs} \tuning e4 b3 g3 d3 a2 e2 \ts 4 4 (14.1{sl} 11.3{sl}).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 | - Open the browser console: the
Expected number, "… CNaN,NaN,NaN,NaN,…"error appears. - In the standard notation staff, there is no slur between the first and the second chord. The tab staff shows its arc.
- Render the same snippet into a 1200px wide container: no error, the slur is drawn.
Link to jsFiddle, CodePen, Project
https://jsfiddle.net/shimabox/6csLz4px/
Version and Environment
[AlphaTab][VersionInfo] alphaTab 1.8.4
[AlphaTab][VersionInfo] commit: 022a45c8e42370f9e12e68949d11eada370da83d
[AlphaTab][VersionInfo] build date: 2026-07-05T14:46:18.224Z
[AlphaTab][VersionInfo] High DPI: 1
[AlphaTab][VersionInfo] Platform: Browser
[AlphaTab][VersionInfo] WebPack: false
[AlphaTab][VersionInfo] Vite: false
[AlphaTab][VersionInfo] Browser: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36
[AlphaTab][VersionInfo] Window Size: 953x826
[AlphaTab][VersionInfo] Screen Size: 1200x800
Also reproduced with:
[AlphaTab][VersionInfo] alphaTab 1.9.0-alpha.1891
[AlphaTab][VersionInfo] commit: 2a460d7c4b6d879465fe23382adc67bf6fd3196d
[AlphaTab][VersionInfo] build date: 2026-08-10T02:28:09.977ZPlatform
Web
Anything else?
Screenshots of the snippet with 1.8.4.
600px wide (no NaN path; the slur in the standard notation staff is drawn, but only about 6px wide, between the first chord and the accidentals of the second chord):
400px wide (slur missing in the standard notation staff):
Single-file reproduction (loads alphaTab from jsDelivr; ?v= selects the version, ?w= the container width, ?case=sl|h|none the snippet):
repro.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>alphaTab legato slur NaN repro</title>
<style>
body { font-family: sans-serif; margin: 16px; }
#surface { border: 1px dashed #aaa; }
pre { background: #f4f4f4; padding: 8px; }
</style>
</head>
<body>
<p>version: <b id="ver"></b> / width: <b id="wid"></b> / NaN paths: <b id="nan">…</b></p>
<pre id="tex"></pre>
<div id="surface"></div>
<script>
// Usage: repro.html?v=1.8.4&w=500&case=sl
var q = new URLSearchParams(location.search);
var version = q.get("v") || "1.8.4";
var width = parseInt(q.get("w") || "500", 10);
var cases = {
// two-note chords, 16th notes, legato slide into the next beat
sl: "\\tuning e4 b3 g3 d3 a2 e2\n\\ts 4 4\n" +
"(14.1{sl} 11.3{sl}).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 " +
"(16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 " +
"(16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 " +
"(16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 |",
// same rhythm, hammer-on instead of slide
h: "\\tuning e4 b3 g3 d3 a2 e2\n\\ts 4 4\n" +
"(14.1{h} 11.3{h}).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 " +
"(16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 " +
"(16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 " +
"(16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 |",
// control: no legato effect
none: "\\tuning e4 b3 g3 d3 a2 e2\n\\ts 4 4\n" +
"(14.1 11.3).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 " +
"(16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 " +
"(16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 " +
"(16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 (16.1 13.3).16 |"
};
var tex = q.get("tex") || cases[q.get("case") || "sl"];
document.getElementById("ver").textContent = version;
document.getElementById("wid").textContent = width + "px";
document.getElementById("tex").textContent = tex;
var surface = document.getElementById("surface");
surface.style.width = width + "px";
window.__result = null;
var base = "https://cdn.jsdelivr.net/npm/@coderline/alphatab@" + version + "/dist/";
var s = document.createElement("script");
s.src = base + "alphaTab.min.js";
s.onload = function () {
var api = new alphaTab.AlphaTabApi(surface, {
core: { useWorkers: false, enableLazyLoading: false, fontDirectory: base + "font/" },
player: { enablePlayer: false }
});
api.renderFinished.on(function () {
var bad = Array.prototype.filter.call(surface.querySelectorAll("path"), function (p) {
return /NaN/.test(p.getAttribute("d") || "");
});
document.getElementById("nan").textContent = String(bad.length);
window.__result = { version: version, width: width, nan: bad.length,
sample: bad.length ? bad[0].getAttribute("d").slice(0, 120) : "" };
});
api.tex(tex);
};
document.head.appendChild(s);
</script>
</body>
</html>Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Effort
Area
Platform
Work State
Projects
- StatusShow more project fieldsDone
Activity
README に既知の問題として、五線のスライド・ハンマリングの弧が消えることがある件を書く
Danielku15 commentedon Oct 5, 2026
I have to check whether this is actually a bug as described. You are squeezing the notation to a size where it cannot fit anymore. there are overlaps in the notation which clearly indicate this. alphaTab cannot solve you the problem of not giving it enough space to fit. we rather let overlaps at the cost of problematic display. the alternative would be to not scale the notation smaller, but then it would overlap the available container.
I'll check if we can improve anything here.
Danielku15 commentedon Oct 9, 2026
I made various improvements in #2943 and #2944 but the core problem remains as described: if there is not enough space for the notation to fit, it will cause overlaps. If you have concrete needs it it might be better to open a GitHub Discussion to show your concrete app setup so we can plan more detailed what new features alphaTab could get (mid-bar system breaks, alternative sizing modes and callbacks to ensure the min-size,...)
in #2943 I improved various slur placement and spacing aspects and warn about the situation that there is not enough space via the logger.
shimabox commentedon Oct 9, 2026
Thanks for the fixes and the detailed explanation! I understand that overlaps can still occur when there isn’t enough width. Thanks also for pointing me to Discussions for questions about the layout.