Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/418.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在画布中创建从递归线条到调用的动画?_Javascript_Html_Canvas - Fatal编程技术网

Javascript 如何在画布中创建从递归线条到调用的动画?

Javascript 如何在画布中创建从递归线条到调用的动画?,javascript,html,canvas,Javascript,Html,Canvas,这段代码在画布中生成希尔伯特曲线,每次调用ctx.lineTo时,我都试图从中创建动画。我尝试了许多使用setInterval和requestAnimationFrame的解决方案,但都不起作用 以下是代码: const bw=904; 常数bh=820; 常量像素x=10; const canvas=document.getElementById(“board”); canvas.setAttribute(“宽度”,bw); canvas.setAttribute(“高度”,bh); con

这段代码在画布中生成希尔伯特曲线,每次调用
ctx.lineTo
时,我都试图从中创建动画。我尝试了许多使用
setInterval
requestAnimationFrame
的解决方案,但都不起作用

以下是代码:

const bw=904;
常数bh=820;
常量像素x=10;
const canvas=document.getElementById(“board”);
canvas.setAttribute(“宽度”,bw);
canvas.setAttribute(“高度”,bh);
const ctx=canvas.getContext(“2d”);
const席伯曲线=(x,y,x,xj,yy,yj.n)={
if(n<0){
ctx.lineTo(x+(Xi+Yi)/2,y+(Xj+Yj)/2);
}否则{
席伯曲线(X,Y,YI/2,YJ/ 2,XI/2,XJ/2,N-1);
席伯席曲线(x+XI/2,Y+XJ/ 2,XI/2,XJ/2,Y/2,YJ/2,N-1);
希尔伯特曲线(
x+席/2+y/ 2,
y+Xj/2+Yj/2,
席/ 2
Xj/2,
Yi/2,
Yj/2,
n-1
);
希尔伯特曲线(
X+席/2 +易,
y+Xj/2+Yj,
-Yi/2,
-Yj/2,
-Xi/2,
-Xj/2,
n-1
);
}
};
函数绘图(){
ctx.beginPath();
希尔伯特曲线(0,0,bw,0,0,bh,7);
ctx.strokeStyle=“红色”;
ctx.stroke();
}
函数init(){
window.requestAnimationFrame(绘制);
}
init()

这是我刚刚得到的答案

const bw=904;
常数bh=820;
常量像素x=10;
const canvas=document.getElementById(“board”);
canvas.setAttribute(“宽度”,bw);
canvas.setAttribute(“高度”,bh);
常量行=[];
const ctx=canvas.getContext(“2d”);
const席伯曲线=(x,y,x,xj,yy,yj.n)={
if(n<0){
Press({x,席,XJ,Y,Yi,Yj });
}否则{
席伯曲线(X,Y,YI/2,YJ/ 2,XI/2,XJ/2,N-1);
席伯席曲线(x+XI/2,Y+XJ/ 2,XI/2,XJ/2,Y/2,YJ/2,N-1);
希尔伯特曲线(
x+席/2+y/ 2,
y+Xj/2+Yj/2,
席/ 2
Xj/2,
Yi/2,
Yj/2,
n-1
);
希尔伯特曲线(
X+席/2 +易,
y+Xj/2+Yj,
-Yi/2,
-Yj/2,
-Xi/2,
-Xj/2,
n-1
);
}
};
希尔伯特曲线(0,0,bw,0,0,bh,7);
设nextLine=0;
请求动画帧(动画);
函数animate(){
如果(下一行<行长度){
请求动画帧(动画);
}
const prevLine=nextLine-1>-1?行[nextLine-1]:行[nextLine];
常量行=行[下一行];
ctx.beginPath();
移动到(
PREXLION.X+(PROFLIL.XI+ PREPANDY YY)/ 2,
prevLine.y+(prevLine.Xj+prevLine.Yj)/2
);
ctx.lineTo(
X+(LI.XI+线,Yi)/ 2,
line.y+(line.Xj+line.Yj)/2
);
ctx.strokeStyle=“红色”;
ctx.stroke();
nextLine++;
}
制作动画()

一个简单的解决方案是使用一个
笔划划线数组
技巧,习惯SVG的人已经知道了。
我们只定义路径,将
笔划划线数组
设置为路径的长度,然后在每次迭代中增加
笔划划线偏移
,使其看起来是连续绘制的

这个解决方案最大的问题是,我们需要能够得到我们的路径长度

不幸的是,由于我不知道什么原因,这个接口并没有提供任何简单的方法来实现这一点。另一方面,SVGGeometryElement有一种非常方便的方法。 Path2d和svg元素可以接受相同的字符串路径定义,因此我们可以简单地使您的
hilbertCurve
函数返回字符串定义,然后将此字符串用于svg和可在上下文中绘制的Path2d对象

const bw=904;
常数bh=820;
常量像素x=10;
设path_as_string=“”+hilbertCurve(0,0,bw,0,0,bh,7)。替换为('L','M');
常量路径=新路径2D(路径作为字符串);
恒速=5;
const totalLength=getPathLength(路径作为字符串);
设偏移量=0;
const canvas=document.getElementById(“board”);
canvas.setAttribute(“宽度”,bw);
canvas.setAttribute(“高度”,bh);
const ctx=canvas.getContext(“2d”);
功能席伯曲线(X,Y,XI,XJ,YI,YJ,N){
if(n<0){
返回“L+(x+(Xi+Yi)/2+”,“+(y+(Xj+Yj)/2);
}否则{
返回(
席伯曲线(X,Y,Y/2,YJ/ 2,XI/2,XJ/2,N-1)+
席伯曲线(x+XI/2,Y+XJ/2,席/ 2,XJ/2,Y/2,YJ/2,N-1)+
希尔伯特曲线(
x+席/2+y/ 2,
y+Xj/2+Yj/2,
席/ 2
Xj/2,
Yi/2,
Yj/2,
n-1
) +
希尔伯特曲线(
X+席/2 +易,
y+Xj/2+Yj,
-Yi/2,
-Yj/2,
-Xi/2,
-Xj/2,
n-1
)
);
}
};
函数绘图(){
clearRect(0,0,canvas.width,canvas.height)
ctx.lineDashOffset=偏移量;
冲程(路径);
偏移量+=速度;
如果(偏移量<总长度){
请求动画帧(绘制);
}
}
函数init(){
ctx.strokeStyle=“红色”;
ctx.setLineDash([0,总长度,总长度]);
请求动画帧(绘制);
}
init();
//从字符串定义返回路径的长度
函数getPathLength(路径){
const elem=document.createElements('http://www.w3.org/2000/svg","路径",;
元素setAttribute('d',路径);
返回elem.getTotalLength();
}
canvas{border:1px solid;}
动画从左下角开始