Fix: timsort snap params, passive resize, drawPath optimization, aria-live, readUrlState labels
This commit is contained in:
parent
6950c4d788
commit
113b8ff758
1 changed files with 34 additions and 29 deletions
|
|
@ -197,7 +197,7 @@
|
|||
<div class="flex-1"></div>
|
||||
<div class="text-center">
|
||||
<h1 class="title-text font-bold tracking-tight" style="color: var(--c-text); text-shadow: 0 0 40px rgba(74,124,255,0.3);">
|
||||
Sortier-Algorithmen <span style="font-size: 0.45em; font-weight: 400; opacity: 0.5; vertical-align: middle;">v0.2.5</span>
|
||||
Sortier-Algorithmen <span style="font-size: 0.45em; font-weight: 400; opacity: 0.5; vertical-align: middle;">v0.2.6</span>
|
||||
</h1>
|
||||
<p class="text-muted text-sm mt-0.5">Interaktive Visualisierung mit schrittweiser Animation</p>
|
||||
</div>
|
||||
|
|
@ -359,8 +359,8 @@
|
|||
|
||||
<!-- Phase Label + Step Explanation (fixed height to prevent layout shift) -->
|
||||
<div class="bg-surface border border-border rounded-xl px-4 py-2 space-y-0.5" style="min-height: 52px;">
|
||||
<div id="phaseLabel" class="text-xs font-semibold text-accent truncate" style="min-height: 20px;"> </div>
|
||||
<div id="stepExplanation" class="text-xs text-muted truncate font-mono" style="min-height: 18px;"> </div>
|
||||
<div id="phaseLabel" aria-live="polite" class="text-xs font-semibold text-accent truncate" style="min-height: 20px;"> </div>
|
||||
<div id="stepExplanation" aria-live="polite" class="text-xs text-muted truncate font-mono" style="min-height: 18px;"> </div>
|
||||
</div>
|
||||
|
||||
<!-- Canvas -->
|
||||
|
|
@ -381,7 +381,7 @@
|
|||
<div class="progress-track flex-1">
|
||||
<div id="progressFill" class="progress-fill" style="width: 0%;"></div>
|
||||
</div>
|
||||
<span id="stepCounter" class="text-xs text-muted font-mono whitespace-nowrap">0 / 0</span>
|
||||
<span id="stepCounter" aria-live="polite" class="text-xs text-muted font-mono whitespace-nowrap">0 / 0</span>
|
||||
</div>
|
||||
|
||||
<!-- Statistics -->
|
||||
|
|
@ -1687,6 +1687,8 @@ function buildSteps(algoName) {
|
|||
case 'timsort': {
|
||||
const n = arr.length;
|
||||
const RUN = 32;
|
||||
const runMeta = { runs: [] };
|
||||
for (let r = 0; r < n; r += RUN) runMeta.runs.push(r);
|
||||
// Phase 1: Insertion Sort auf Runs der Größe RUN
|
||||
for (let start = 0; start < n; start += RUN) {
|
||||
const end = Math.min(start + RUN, n);
|
||||
|
|
@ -1695,11 +1697,11 @@ function buildSteps(algoName) {
|
|||
let j = i - 1;
|
||||
while (j >= start) {
|
||||
compares++;
|
||||
snap('compare', [j, j + 1]);
|
||||
snap('compare', [j, j + 1], null, runMeta);
|
||||
if (arr[j] > key) {
|
||||
arr[j + 1] = arr[j];
|
||||
moves++;
|
||||
snap('move', [j + 1]);
|
||||
snap('move', [j + 1], null, runMeta);
|
||||
j--;
|
||||
} else {
|
||||
break;
|
||||
|
|
@ -1708,7 +1710,7 @@ function buildSteps(algoName) {
|
|||
if (arr[j + 1] !== key) {
|
||||
arr[j + 1] = key;
|
||||
moves++;
|
||||
snap('move', [j + 1]);
|
||||
snap('move', [j + 1], null, runMeta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2109,6 +2111,24 @@ function drawBars(arr, highlights, allSorted, meta, connectedPair) {
|
|||
ctx.textAlign = 'center';
|
||||
ctx.textBaseline = 'bottom';
|
||||
|
||||
// Reusable rounded-rect path helper (defined once, called per bar)
|
||||
function drawRoundedRectPath(ctx, px, py, pw, ph, pr) {
|
||||
if (pr > 0 && ph > pr * 2) {
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(px + pr, py);
|
||||
ctx.lineTo(px + pw - pr, py);
|
||||
ctx.quadraticCurveTo(px + pw, py, px + pw, py + pr);
|
||||
ctx.lineTo(px + pw, py + ph);
|
||||
ctx.lineTo(px, py + ph);
|
||||
ctx.lineTo(px, py + pr);
|
||||
ctx.quadraticCurveTo(px, py, px + pr, py);
|
||||
ctx.closePath();
|
||||
} else {
|
||||
ctx.beginPath();
|
||||
ctx.rect(px, py, pw, ph);
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < n; i++) {
|
||||
const val = arr[i];
|
||||
const barH = Math.max(2, (val / maxVal) * areaH);
|
||||
|
|
@ -2126,41 +2146,24 @@ function drawBars(arr, highlights, allSorted, meta, connectedPair) {
|
|||
else if (t === 'move') color = COLORS.move;
|
||||
}
|
||||
|
||||
// Rounded-top bar path generator
|
||||
const r = Math.min(3, barW / 4);
|
||||
function drawPath() {
|
||||
if (r > 0 && barH > r * 2) {
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x + r, y);
|
||||
ctx.lineTo(x + barW - r, y);
|
||||
ctx.quadraticCurveTo(x + barW, y, x + barW, y + r);
|
||||
ctx.lineTo(x + barW, y + barH);
|
||||
ctx.lineTo(x, y + barH);
|
||||
ctx.lineTo(x, y + r);
|
||||
ctx.quadraticCurveTo(x, y, x + r, y);
|
||||
ctx.closePath();
|
||||
} else {
|
||||
ctx.beginPath();
|
||||
ctx.rect(x, y, barW, barH);
|
||||
}
|
||||
}
|
||||
|
||||
// FIX: Glow-Effekt VOR dem normalen Balken zeichnen
|
||||
// Glow-Effekt
|
||||
if (highlights[i] && !allSorted) {
|
||||
ctx.save();
|
||||
ctx.fillStyle = color;
|
||||
ctx.shadowColor = color;
|
||||
ctx.shadowBlur = 14;
|
||||
ctx.globalAlpha = 0.35;
|
||||
drawPath();
|
||||
drawRoundedRectPath(ctx, x, y, barW, barH, r);
|
||||
ctx.fill();
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
// Haupt-Balken zeichnen
|
||||
// Haupt-Balken
|
||||
ctx.fillStyle = color;
|
||||
ctx.globalAlpha = 1;
|
||||
drawPath();
|
||||
drawRoundedRectPath(ctx, x, y, barW, barH, r);
|
||||
ctx.fill();
|
||||
|
||||
// Value label
|
||||
|
|
@ -2929,6 +2932,8 @@ function readUrlState() {
|
|||
if (params.has('preset')) $presetSelect.value = params.get('preset');
|
||||
if (params.has('size')) $sizeSlider.value = Math.max(5, Math.min(200, parseInt(params.get('size'), 10) || 50));
|
||||
if (params.has('speed')) $speedSlider.value = Math.max(1, Math.min(100, parseInt(params.get('speed'), 10) || 50));
|
||||
updateSizeLabel();
|
||||
updateSpeedLabel();
|
||||
}
|
||||
|
||||
function writeUrlState() {
|
||||
|
|
@ -2961,7 +2966,7 @@ function handleResize() {
|
|||
}
|
||||
|
||||
// Use window resize to avoid feedback loops (ResizeObserver on canvas parent causes blowout)
|
||||
window.addEventListener('resize', handleResize);
|
||||
window.addEventListener('resize', handleResize, { passive: true });
|
||||
|
||||
// ================================================================
|
||||
// Initialization
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue