Я работаю над базовым c визуализатором сортировки с использованием только HTML, CSS и JS, и у меня возникла проблема с аспектом анимации. Чтобы инициализировать массив, я генерирую случайные числа в определенном диапазоне и помещаю их в массив. Затем, основываясь на размерах веб-страницы, я создаю блоки div для каждого элемента и соответственно задаю каждому из них высоту и ширину и добавляю каждый в свой блок div «bar-container», находящийся в данный момент в dom.
function renderVisualizer() {
var barContainer = document.getElementById("bar-container");
//Empties bar-container div
while (barContainer.hasChildNodes()) {
barContainer.removeChild(barContainer.lastChild);
}
var heightMult = barContainer.offsetHeight / max_element;
var temp = barContainer.offsetWidth / array.length;
var barWidth = temp * 0.9;
var margin = temp * 0.05;
//Creating array element bars
for (var i = 0; i < array.length; i++) {
var arrayBar = document.createElement("div");
arrayBar.className = "array-bar"
if (barWidth > 30)
arrayBar.textContent = array[i];
//Style
arrayBar.style.textAlign = "center";
arrayBar.style.height = array[i] * heightMult + "px";
arrayBar.style.width = barWidth;
arrayBar.style.margin = margin;
barContainer.appendChild(arrayBar);
}
}
Я написал следующая анимированная сортировка выделения, и она работает хорошо, но единственная «анимированная» часть находится во внешнем for-l oop, и я не выделяю полосы при перемещении по ним.
function selectionSortAnimated() {
var barContainer = document.getElementById("bar-container");
var barArr = barContainer.childNodes;
for (let i = 0; i < barArr.length - 1; i++) {
let min_idx = i;
let minNum = parseInt(barArr[i].textContent);
for (let j = i + 1; j < barArr.length; j++) {
let jNum = parseInt(barArr[j].textContent, 10);
if (jNum < minNum) {
min_idx = j;
minNum = jNum;
}
}
//setTimeout(() => {
barContainer.insertBefore(barArr[i], barArr[min_idx])
barContainer.insertBefore(barArr[min_idx], barArr[i]);
//}, i * 500);
}
}
I Я пытаюсь использовать вложенные вызовы setTimeout, чтобы выделить каждую полосу, когда я прохожу через нее, а затем поменять местами полосы, но у меня возникла проблема. Я использую объект idxContainer
для хранения моего минимального индекса, но после каждого запуска innerLoopHelper
он оказывается равным i
, и, следовательно, своп отсутствует. Я застрял здесь на несколько часов и совершенно сбит с толку.
function selectionSortTest() {
var barContainer = document.getElementById("bar-container");
var barArr = barContainer.childNodes;
outerLoopHelper(0, barArr, barContainer);
console.log(array);
}
function outerLoopHelper(i, barArr, barContainer) {
if (i < array.length - 1) {
setTimeout(() => {
var idxContainer = {
idx: i
};
innerLoopHelper(i + 1, idxContainer, barArr);
console.log(idxContainer);
let minIdx = idxContainer.idx;
let temp = array[minIdx];
array[minIdx] = array[i];
array[i] = temp;
barContainer.insertBefore(barArr[i], barArr[minIdx])
barContainer.insertBefore(barArr[minIdx], barArr[i]);
//console.log("Swapping indices: " + i + " and " + minIdx);
outerLoopHelper(++i, barArr, barContainer);
}, 100);
}
}
function innerLoopHelper(j, idxContainer, barArr) {
if (j < array.length) {
setTimeout(() => {
if (j - 1 >= 0)
barArr[j - 1].style.backgroundColor = "gray";
barArr[j].style.backgroundColor = "red";
if (array[j] < array[idxContainer.idx])
idxContainer.idx = j;
innerLoopHelper(++j, idxContainer, barArr);
}, 100);
}
}
Я знаю, что это длинный пост, но я просто хотел быть как можно более конкретным c. Большое спасибо за чтение, и мы будем благодарны за любые рекомендации!