Add slider hover tooltip and CSV/paste import for custom arrays
This commit is contained in:
parent
1e812c86c6
commit
01a4840393
1 changed files with 99 additions and 2 deletions
|
|
@ -73,6 +73,24 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
touch-action: none;
|
touch-action: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Slider Tooltip ── */
|
||||||
|
.slider-tooltip {
|
||||||
|
position: fixed;
|
||||||
|
background: var(--c-surface2, #1e2235);
|
||||||
|
border: 1px solid var(--c-border, #2a2d3d);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 3px 8px;
|
||||||
|
font-size: 11px;
|
||||||
|
font-family: monospace;
|
||||||
|
color: var(--c-accent, #4a7cff);
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.15s ease;
|
||||||
|
z-index: 9999;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.slider-tooltip.visible { opacity: 1; }
|
||||||
input[type="range"]::-webkit-slider-runnable-track {
|
input[type="range"]::-webkit-slider-runnable-track {
|
||||||
height: 6px;
|
height: 6px;
|
||||||
background: var(--c-surface2);
|
background: var(--c-surface2);
|
||||||
|
|
@ -197,7 +215,7 @@
|
||||||
<div class="flex-1"></div>
|
<div class="flex-1"></div>
|
||||||
<div class="text-center">
|
<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);">
|
<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.8</span>
|
Sortier-Algorithmen <span style="font-size: 0.45em; font-weight: 400; opacity: 0.5; vertical-align: middle;">v0.2.9</span>
|
||||||
</h1>
|
</h1>
|
||||||
<p class="text-muted text-sm mt-0.5">Interaktive Visualisierung mit schrittweiser Animation</p>
|
<p class="text-muted text-sm mt-0.5">Interaktive Visualisierung mit schrittweiser Animation</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -275,10 +293,14 @@
|
||||||
<div class="space-y-1.5">
|
<div class="space-y-1.5">
|
||||||
<label for="customArray" class="label-text uppercase tracking-wider text-muted font-medium flex items-center gap-1.5">
|
<label for="customArray" class="label-text uppercase tracking-wider text-muted font-medium flex items-center gap-1.5">
|
||||||
<i data-lucide="pencil" class="w-3.5 h-3.5"></i> Eigene Werte
|
<i data-lucide="pencil" class="w-3.5 h-3.5"></i> Eigene Werte
|
||||||
|
<span id="customArrayCount" class="text-[10px] text-muted ml-auto normal-case tracking-normal font-mono"></span>
|
||||||
</label>
|
</label>
|
||||||
<div class="flex gap-1.5">
|
<div class="flex gap-1.5">
|
||||||
<input type="text" id="customArray" placeholder="z.B. 5, 3, 8, 1"
|
<input type="text" id="customArray" placeholder="z.B. 5, 3, 8, 1 oder Mehrfachpaste"
|
||||||
class="flex-1 min-w-0 bg-surface2 border border-border rounded-lg px-2 py-2 text-sm outline-none focus:border-accent focus:ring-1 focus:ring-accent/30 transition" style="color: var(--c-text);">
|
class="flex-1 min-w-0 bg-surface2 border border-border rounded-lg px-2 py-2 text-sm outline-none focus:border-accent focus:ring-1 focus:ring-accent/30 transition" style="color: var(--c-text);">
|
||||||
|
<button id="btnPasteCustom" class="px-2.5 min-w-[36px] flex items-center justify-center rounded-lg border border-border bg-surface2 hover:bg-accent hover:border-accent hover:text-white transition-colors" style="color: var(--c-text);" title="Aus Zwischenablage einfügen" aria-label="Aus Zwischenablage einfügen">
|
||||||
|
<i data-lucide="clipboard-paste" class="w-4 h-4"></i>
|
||||||
|
</button>
|
||||||
<button id="btnClearCustom" class="px-2.5 min-w-[36px] flex items-center justify-center rounded-lg border border-border bg-surface2 hover:bg-accent hover:border-accent hover:text-white transition-colors" style="color: var(--c-text);" title="Eigene Werte leeren">
|
<button id="btnClearCustom" class="px-2.5 min-w-[36px] flex items-center justify-center rounded-lg border border-border bg-surface2 hover:bg-accent hover:border-accent hover:text-white transition-colors" style="color: var(--c-text);" title="Eigene Werte leeren">
|
||||||
<i data-lucide="x" class="w-4 h-4"></i>
|
<i data-lucide="x" class="w-4 h-4"></i>
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -316,6 +338,9 @@
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<!-- Floating Slider Tooltip -->
|
||||||
|
<div id="sliderTooltip" class="slider-tooltip"></div>
|
||||||
|
|
||||||
<!-- Transport Buttons -->
|
<!-- Transport Buttons -->
|
||||||
<section class="bg-surface border border-border rounded-xl p-4">
|
<section class="bg-surface border border-border rounded-xl p-4">
|
||||||
<div class="grid grid-cols-4 sm:grid-cols-5 gap-2">
|
<div class="grid grid-cols-4 sm:grid-cols-5 gap-2">
|
||||||
|
|
@ -809,6 +834,8 @@ const $algoSelect = document.getElementById('algoSelect');
|
||||||
const $presetSelect = document.getElementById('presetSelect');
|
const $presetSelect = document.getElementById('presetSelect');
|
||||||
const $customArray = document.getElementById('customArray');
|
const $customArray = document.getElementById('customArray');
|
||||||
const $btnClearCustom = document.getElementById('btnClearCustom');
|
const $btnClearCustom = document.getElementById('btnClearCustom');
|
||||||
|
const $btnPasteCustom = document.getElementById('btnPasteCustom');
|
||||||
|
const $customArrayCount = document.getElementById('customArrayCount');
|
||||||
const $sizeSlider = document.getElementById('sizeSlider');
|
const $sizeSlider = document.getElementById('sizeSlider');
|
||||||
const $speedSlider = document.getElementById('speedSlider');
|
const $speedSlider = document.getElementById('speedSlider');
|
||||||
const $threadSlider = document.getElementById('threadSlider');
|
const $threadSlider = document.getElementById('threadSlider');
|
||||||
|
|
@ -2840,14 +2867,41 @@ $presetSelect.addEventListener('change', function() {
|
||||||
|
|
||||||
$customArray.addEventListener('change', function() {
|
$customArray.addEventListener('change', function() {
|
||||||
if (!isRunning) doReset();
|
if (!isRunning) doReset();
|
||||||
|
updateCustomArrayCount();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$customArray.addEventListener('input', function() {
|
||||||
|
updateCustomArrayCount();
|
||||||
|
});
|
||||||
|
|
||||||
|
function updateCustomArrayCount() {
|
||||||
|
const text = $customArray.value.trim();
|
||||||
|
if (!text) {
|
||||||
|
$customArrayCount.textContent = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const values = text.split(/[,;\s\n\t]+/).filter(function(v) { return v !== '' && !isNaN(parseFloat(v)); });
|
||||||
|
$customArrayCount.textContent = values.length + ' Wert' + (values.length === 1 ? '' : 'e');
|
||||||
|
}
|
||||||
|
|
||||||
$btnClearCustom.addEventListener('click', function() {
|
$btnClearCustom.addEventListener('click', function() {
|
||||||
$customArray.value = '';
|
$customArray.value = '';
|
||||||
|
$customArrayCount.textContent = '';
|
||||||
$sizeSlider.disabled = false;
|
$sizeSlider.disabled = false;
|
||||||
if (!isRunning) doReset();
|
if (!isRunning) doReset();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$btnPasteCustom.addEventListener('click', async function() {
|
||||||
|
try {
|
||||||
|
const text = await navigator.clipboard.readText();
|
||||||
|
$customArray.value = text.replace(/[\r\n]+/g, ', ').replace(/,/g, ', ');
|
||||||
|
updateCustomArrayCount();
|
||||||
|
$customArray.dispatchEvent(new Event('change'));
|
||||||
|
} catch (e) {
|
||||||
|
// Clipboard API not available or permission denied
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$btnTheme.addEventListener('click', function() {
|
$btnTheme.addEventListener('click', function() {
|
||||||
const isDark = document.documentElement.classList.contains('dark');
|
const isDark = document.documentElement.classList.contains('dark');
|
||||||
const newTheme = !isDark;
|
const newTheme = !isDark;
|
||||||
|
|
@ -2922,6 +2976,49 @@ makeTouchSlider($sizeSlider);
|
||||||
makeTouchSlider($speedSlider);
|
makeTouchSlider($speedSlider);
|
||||||
makeTouchSlider($threadSlider);
|
makeTouchSlider($threadSlider);
|
||||||
|
|
||||||
|
// ================================================================
|
||||||
|
// Slider Tooltip on Hover
|
||||||
|
// ================================================================
|
||||||
|
|
||||||
|
const $sliderTooltip = document.getElementById('sliderTooltip');
|
||||||
|
const $allSliders = [$sizeSlider, $speedSlider, $threadSlider].filter(Boolean);
|
||||||
|
|
||||||
|
$allSliders.forEach(function(slider) {
|
||||||
|
slider.addEventListener('mouseenter', function() {
|
||||||
|
updateSliderTooltip(slider);
|
||||||
|
$sliderTooltip.classList.add('visible');
|
||||||
|
});
|
||||||
|
slider.addEventListener('mousemove', function(e) {
|
||||||
|
updateSliderTooltipPosition(e.clientX, e.clientY);
|
||||||
|
});
|
||||||
|
slider.addEventListener('mouseleave', function() {
|
||||||
|
$sliderTooltip.classList.remove('visible');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function updateSliderTooltip(slider) {
|
||||||
|
if (slider.id === 'sizeSlider') {
|
||||||
|
$sliderTooltip.textContent = slider.value + ' Elemente';
|
||||||
|
} else if (slider.id === 'speedSlider') {
|
||||||
|
const ms = Math.round(1000 * Math.pow(0.001, (parseInt(slider.value) - 1) / 99));
|
||||||
|
$sliderTooltip.textContent = ms + ' ms/Schritt';
|
||||||
|
} else if (slider.id === 'threadSlider') {
|
||||||
|
$sliderTooltip.textContent = slider.value + ' Thread(s)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateSliderTooltipPosition(x, y) {
|
||||||
|
const tw = $sliderTooltip.offsetWidth;
|
||||||
|
const th = $sliderTooltip.offsetHeight;
|
||||||
|
let left = x - tw / 2;
|
||||||
|
let top = y - th - 12;
|
||||||
|
if (left < 8) left = 8;
|
||||||
|
if (left + tw > window.innerWidth - 8) left = window.innerWidth - tw - 8;
|
||||||
|
if (top < 8) top = y + 16;
|
||||||
|
$sliderTooltip.style.left = left + 'px';
|
||||||
|
$sliderTooltip.style.top = top + 'px';
|
||||||
|
}
|
||||||
|
|
||||||
// ================================================================
|
// ================================================================
|
||||||
// URL State Persistence
|
// URL State Persistence
|
||||||
// ================================================================
|
// ================================================================
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue