Javascript 河内塔可视化器计时动画

Javascript 河内塔可视化器计时动画,javascript,css,animation,Javascript,Css,Animation,我目前正在建造河内塔可视化工具。这个想法是,你输入一个数字,一个算法创建磁盘,然后你可以看到他移动磁盘,直到塔完成。到目前为止,一切都很好,唯一的问题是,我似乎无法使动画工作 在每次样式更改之前,我都尝试运行超时功能,但每当我单击submit时,我只看到最终结果,没有看到动画。我要寻找的结果是看到每个磁盘被提起,拖到目标位置,然后被放下 我认为问题在于,创建的元素最后被渲染,因此从最后开始总是具有css属性。然而,我当然可能是错的,因为我对计时动物一无所知 这里是这个项目的链接。CSS只是用于表

我目前正在建造河内塔可视化工具。这个想法是,你输入一个数字,一个算法创建磁盘,然后你可以看到他移动磁盘,直到塔完成。到目前为止,一切都很好,唯一的问题是,我似乎无法使动画工作

在每次样式更改之前,我都尝试运行超时功能,但每当我单击submit时,我只看到最终结果,没有看到动画。我要寻找的结果是看到每个磁盘被提起,拖到目标位置,然后被放下

我认为问题在于,创建的元素最后被渲染,因此从最后开始总是具有css属性。然而,我当然可能是错的,因为我对计时动物一无所知

这里是这个项目的链接。CSS只是用于表示,我知道它看起来很糟糕:)

//获取提交值
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);
河内塔(编号);
numberInput.value=“”;
e、 预防默认值();
});
//开始比赛
异步函数towerOfHanoi(编号){
常数a=[];
常数b=[];
常数c=[];
让迭代器=数字;
//用等于输入数量的圆盘填充第一个塔
对于(迭代器;迭代器>0;迭代器--){
a、 推(迭代器);
}
//创建磁盘
a、 forEach((项目)=>{
元素=document.createElement(“div”);
element.className=“磁盘”;
元素。setAttribute(“id”,项);
常量样式={
宽度:400/(数字+1)*项目+“px”,
底部:a.indexOf(项目)*10+“px”,
背景:“rgb(“+Math.floor(Math.random()*256)+”,“+Math.floor(Math.random()*256)+”,“+Math.floor(Math.random()*256)+”),
转换:“translateX(0px)”
}
Object.assign(element.style,style);
1.附加子元素(元素);
});
//这会移动磁盘
如果(编号%2!=0){
而(c.长度<数量){
移动磁盘(a,c,c,数字,2);
移动磁盘(a,b,c,数字,1);
移动磁盘(b、c、c、数字、1)
控制台日志(a、b、c);
}
}否则{
而(c.长度<数量){
移动磁盘(a,b,c,数字,1);
移动磁盘(a,c,c,数字,2);
移动磁盘(b,c,c,数字,1);
控制台日志(a、b、c);
}
}
};
//移动磁盘功能,参数包括开始、目的地、finsh peg和开始和目的地之间的距离
功能移动磁盘(a、b、c、数字、距离){
if(c.length==number)返回;
如果(!a.length&&b.length){
图纸(b,a,距离*-1);
a、 推(b[b.length-1]);
b、 pop();
}else if(!b.length&&a.length){
绘制(a、b、距离);
b、 推(a[a.长度-1]);
a、 pop();
}否则{
如果(a[a.length-1]
如果您对改进我的代码有任何建议,我当然很高兴收到任何反馈


我很感激能得到的每一点建议

您的代码没有引入延迟/暂停的内容。仅仅将函数定义为
async
,如果没有内部的承诺,就不会有任何用处

使其工作的步骤:

  • 定义一个函数,该函数返回一个承诺,该承诺将在某个给定时间后解析:

    const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
    
  • 使
    draw
    成为
    async
    函数,并在每次样式更改之间添加延迟:

    //move disk up 
    disk.style.bottom = "385px";
    await delay(250);
    //move disk to the destination peg
    disk.style.transform = "translateX(" + value +"px)";
    await delay(250);
    //drop disk
    disk.style.bottom = b.length*20 +"px";
    await delay(250);
    
  • 使
    moveDisk
    成为
    async
    函数,在调用
    draw
    的地方,在其前面加上
    wait
    ,例如:

    await draw(b, a, distance*-1);
    
    await moveDisk(a, c, c, number, 2);
    
    无论您在哪里调用
    draw
    ,都可以执行此操作

  • 无论您在哪里调用
    moveDisk
    ,都要等待它的承诺,例如:

    await draw(b, a, distance*-1);
    
    await moveDisk(a, c, c, number, 2);
    
    无论您在哪里调用
    moveDisk
    ,都可以执行此操作

  • const delay=ms=>新承诺(resolve=>setTimeout(resolve,ms));
    //获取提交值
    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);
    河内塔(编号);
    numberInput.value=“”;
    e、 预防默认值();
    });
    //开始比赛
    异步函数towerOfHanoi(编号){
    常数a=[];
    常数b=[];
    常数c=[];
    让迭代器=数字;
    //用等于输入数量的圆盘填充第一个塔
    对于(迭代器;迭代器>0;迭代器--){
    a、 推(迭代器);
    }
    //创建磁盘
    a、 forEach((项目)=>{
    元素=document.createElement(“div”);
    element.className=“磁盘”;
    元素。setAttribute(“id”,项);
    常量样式={
    宽度:400/(数字+1)*项目+“px”,
    底部:a.indexOf(项目)*10+“px”,
    背景:“rgb(“+Math.floor(Math.random()*256)+”,“+Math.floor(Math.random()*256)+”,“+Math.floor(Math.random()*256)+”),
    转换:“translateX(0px)”