В настоящее время я строю башню Ханоя Visualizer. Идея состоит в том, что вы вводите число, алгоритм создает диски, а затем вы можете видеть, как он перемещает диски, пока Башня не будет закончена. Пока все работает отлично, единственная проблема в том, что я не могу заставить анимацию работать.
Я пытался запустить функцию тайм-аута перед каждым изменением стиля, но всякий раз, когда я нажимал на кнопку отправки, я видел только конечный результат и никаких анимаций. Результат, который я ищу, состоит в том, чтобы увидеть, как каждый диск поднимается, перетаскивается на колышек назначения, а затем падает.
Я думаю, что проблема в том, что созданные элементы визуализируются последними и, следовательно, всегда имеют свойства css с конца. Тем не менее, я, конечно, могу ошибаться, поскольку ничего не знаю о временных анимациях.
Вот ссылка на этот проект. CSS просто для наглядности, я знаю, это выглядит плохо:)
https://jsfiddle.net/jakob_mayerhofer/rgx17hps/12/
//get submit values
const submit = document.getElementsByClassName('submit')[0];
var numberInput = document.getElementsByClassName('number')[0];
const tower1 = document.getElementsByClassName('tower1')[0];
submit.addEventListener('click', (e)=> {
const number = parseInt(numberInput.value);
towerOfHanoi(number);
numberInput.value = "";
e.preventDefault();
});
//start the game
async function towerOfHanoi(number){
const a = [];
const b = [];
const c = [];
let iterator = number;
//fill first tower with disks equal to number imput
for(iterator; iterator > 0; iterator--){
a.push(iterator);
}
// create the disks
a.forEach((item) => {
element = document.createElement("div");
element.className = "disk";
element.setAttribute("id", item);
const style = {
width: 400/(number+1)*item + "px",
bottom: a.indexOf(item)*10 + "px",
background: "rgb(" +Math.floor(Math.random()*256) +"," +Math.floor(Math.random()*256) +"," +Math.floor(Math.random()*256) +")",
transform: "translateX(0px)"
}
Object.assign(element.style, style);
tower1.appendChild(element);
});
// this moves the disks
if(number%2 != 0){
while(c.length < number){
moveDisk(a, c, c, number, 2);
moveDisk(a, b, c, number, 1);
moveDisk(b, c, c, number, 1)
console.log(a, b, c);
}
}else {
while(c.length < number){
moveDisk(a, b, c, number, 1);
moveDisk(a, c, c, number, 2);
moveDisk(b, c, c, number, 1);
console.log(a, b, c);
}
}
};
// move disk function, parameters are start, destination, finsh peg and distance between start and destination
function moveDisk(a, b, c, number, distance) {
if (c.length == number) return;
if(!a.length && b.length){
draw(b, a, distance*-1);
a.push(b[b.length-1]);
b.pop();
} else if (!b.length && a.length) {
draw(a, b, distance);
b.push(a[a.length-1]);
a.pop();
} else {
if(a[a.length-1] < b[b.length-1]){
while(a[a.length-1] < b[b.length-1]){
draw(a, b, distance);
b.push(a[a.length-1]);
a.pop();
}
} else if(b[b.length-1] < a[a.length-1]){
while(b[b.length-1] < a[a.length-1]){
draw(b, a, distance*-1);
a.push(b[b.length-1]);
b.pop();
}
}
}
};
//moving function: this should animate the disks
function draw(a, b, distance){
num = a[a.length-1].toString();
disk = document.getElementById(num);
//get current translateX css value and then add the distance between start and destination peg
regEx = /\.*translateX\((.*)px\)/i;
translate = disk.getAttribute('style')
value = parseInt(regEx.exec(translate)[1]) + (distance*400);
//move disk up
disk.style.bottom = "385px";
//move disk to the destination peg
disk.style.transform = "translateX(" + value +"px)";
//drop disk
disk.style.bottom = b.length*20 +"px";
};
Если у вас есть предложения по улучшению моего кода, Я, конечно, рад получить любую Обратную связь.
Я благодарен за каждый совет, который я могу получить.