for循环中的延迟lineTo
Delay lineTo in for loop
我有一个点形的 div (#option1
),它使用数组 Option1[]
对图形进行动画处理,其中几个 'dots' 包括在内。我正在使用 for 循环在两个点 (left: '+=5px'
) 之间创建 space 并从数组中获取下一个点的高度,如下所示:
for (var i = 0; i < Option1.length; ++i) {
$('#option1').animate({left: '+=5px',top: Option1[i]}, 200);
}
如您所见,div 需要 200 毫秒才能移动到它的下一个坐标。这一切都很好,但它只是一个移动的点。我实际上想让它看起来像点在画一条线,所以我尝试使用 canvas
和 lineTo
方法,如下所示:
var xaxis=5;
var a = document.getElementById("myCanvas1");
var atx = a.getContext("2d");
atx.beginPath();
atx.moveTo(5, 900);
for (var i = 0; i < Option1.length; ++i) {
xaxis += 5;
$('#option1').animate({left: '+=5px',top: Option1[i]}, 200);
atx.lineTo(xaxis, Option1[i]);
atx.stroke();
}
如您所见,该线从坐标 5,900 开始,然后向右移动 5px 并到达 Option1[]
数组下一个值的高度。
线路正确输出。问题是总线立即显示,然后点开始在已经绘制的线上移动。为了使线段仅在点超过新坐标后出现,我尝试了 setTimeout
函数,将超时设置为 200 毫秒,就像动画时间一样:
$(document).ready(function() {
var Option1 = [100, 150, 150, 130, 50, 100, 75, 125, 50, 100];
var xaxis = 5;
var a = document.getElementById("myCanvas1");
var atx = a.getContext("2d");
atx.beginPath();
atx.moveTo(5, 400);
atx.strokeStyle="green";
for (var i = 0; i < Option1.length; ++i) {
xaxis += 5;
$('#option1').animate({
left: '+=5px',
top: Option1[i]
}, 400);
setTimeout(drawLines(), 400);
function drawLines() {
atx.lineTo(xaxis, Option1[i]);
atx.stroke();
};
};
});
html,
body {
width: 100%;
height: 100%;
background-color: black;
}
#maindiv {
position: absolute;
top: 5px;
left: 5px;
z-index: 5;
cursor: pointer;
Width: 500px;
Height: 400px;
background-color: black;
border-radius: 1%;
border-width: 0px;
border-color: blue;
border-style: solid;
font-family: Verdana, Arial, Sans-Serif;
color: white;
box-shadow: 0 0 20px white;
}
canvas {
position: absolute;
z-index: 5;
cursor: pointer;
Width: 100%;
Height: 100%;
background-color: none;
border-radius: 1%;
border-width: 1px;
border-color: blue;
border-style: solid;
font-family: Verdana, Arial, Sans-Serif;
color: white;
box-shadow: 0 0 20px white;
}
#option1 {
position: absolute;
top: 390px;
left: 5px;
z-index: 10;
Width: 5px;
Height: 5px;
background-color: green;
border-radius: 50%;
border-width: 0px;
border-color: blue;
border-style: solid;
font-family: Verdana, Arial, Sans-Serif;
color: white;
box-shadow: 0 0 20px white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<html>
<body>
<div id="maindiv">
<canvas id="myCanvas1" width="500" height="400"></canvas>
<div id="option1"></div>
</div>
</body>
</html>
(最后一个隐藏的代码段包含 html 和 css 顺便说一句,所以它可以正常工作)。没有成功。总线瞬间就在那里。我还尝试使用 Whosebug 上的其他帖子以其他方式编写 setTimeout
,但总是立即显示总行。
如果能帮助我实时绘制线条,将不胜感激!也欢迎使用完全不同 methods/functions 的解决方案。
谢谢!
您的第一个问题是您立即调用 drawLines
函数,然后将该函数的结果(未定义)传递给 setTimeout
。
More on that here
一旦你解决了这个问题,你会发现你有一个循环闭包的问题。有很多方法可以解决这个问题,尽管我选择创建一个新函数并将所需的变量传递给它,然后在该函数中创建超时。
More info on closure inside a loop
解决了这两个问题后,您将得到以下结果:
新函数:
function drawLine(atx, xaxis, y, delay){
setTimeout(function(){
atx.lineTo(xaxis, y);
atx.stroke();
}, delay);
}
这样调用来代替现有的 setTimeout
:
drawLine(atx, xaxis, Option1[i], 400 * i);
您会注意到我有 400 * i
超时延迟,而不是像您那样只有 400
。如果使用400,他们会在400ms后一次全部绘制。
这是一个工作片段:
$(document).ready(function() {
var Option1 = [100, 150, 150, 130, 50, 100, 75, 125, 50, 100];
var xaxis = 5;
var a = document.getElementById("myCanvas1");
var atx = a.getContext("2d");
atx.beginPath();
atx.moveTo(5, 400);
atx.strokeStyle="green";
for (var i = 0; i < Option1.length; ++i) {
xaxis += 5;
$('#option1').animate({
left: '+=5px',
top: Option1[i]
}, 400);
drawLine(atx, xaxis, Option1[i], 400 * i);
};
});
function drawLine(atx, xaxis, y, delay){
setTimeout(function(){
atx.lineTo(xaxis, y);
atx.stroke();
}, delay);
}
html,
body {
width: 100%;
height: 100%;
background-color: black;
}
#maindiv {
position: absolute;
top: 5px;
left: 5px;
z-index: 5;
cursor: pointer;
Width: 500px;
Height: 400px;
background-color: black;
border-radius: 1%;
border-width: 0px;
border-color: blue;
border-style: solid;
font-family: Verdana, Arial, Sans-Serif;
color: white;
box-shadow: 0 0 20px white;
}
canvas {
position: absolute;
z-index: 5;
cursor: pointer;
Width: 100%;
Height: 100%;
background-color: none;
border-radius: 1%;
border-width: 1px;
border-color: blue;
border-style: solid;
font-family: Verdana, Arial, Sans-Serif;
color: white;
box-shadow: 0 0 20px white;
}
#option1 {
position: absolute;
top: 390px;
left: 5px;
z-index: 10;
Width: 5px;
Height: 5px;
background-color: green;
border-radius: 50%;
border-width: 0px;
border-color: blue;
border-style: solid;
font-family: Verdana, Arial, Sans-Serif;
color: white;
box-shadow: 0 0 20px white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<html>
<body>
<div id="maindiv">
<canvas id="myCanvas1" width="500" height="400"></canvas>
<div id="option1"></div>
</div>
</body>
</html>
我有一个点形的 div (#option1
),它使用数组 Option1[]
对图形进行动画处理,其中几个 'dots' 包括在内。我正在使用 for 循环在两个点 (left: '+=5px'
) 之间创建 space 并从数组中获取下一个点的高度,如下所示:
for (var i = 0; i < Option1.length; ++i) {
$('#option1').animate({left: '+=5px',top: Option1[i]}, 200);
}
如您所见,div 需要 200 毫秒才能移动到它的下一个坐标。这一切都很好,但它只是一个移动的点。我实际上想让它看起来像点在画一条线,所以我尝试使用 canvas
和 lineTo
方法,如下所示:
var xaxis=5;
var a = document.getElementById("myCanvas1");
var atx = a.getContext("2d");
atx.beginPath();
atx.moveTo(5, 900);
for (var i = 0; i < Option1.length; ++i) {
xaxis += 5;
$('#option1').animate({left: '+=5px',top: Option1[i]}, 200);
atx.lineTo(xaxis, Option1[i]);
atx.stroke();
}
如您所见,该线从坐标 5,900 开始,然后向右移动 5px 并到达 Option1[]
数组下一个值的高度。
线路正确输出。问题是总线立即显示,然后点开始在已经绘制的线上移动。为了使线段仅在点超过新坐标后出现,我尝试了 setTimeout
函数,将超时设置为 200 毫秒,就像动画时间一样:
$(document).ready(function() {
var Option1 = [100, 150, 150, 130, 50, 100, 75, 125, 50, 100];
var xaxis = 5;
var a = document.getElementById("myCanvas1");
var atx = a.getContext("2d");
atx.beginPath();
atx.moveTo(5, 400);
atx.strokeStyle="green";
for (var i = 0; i < Option1.length; ++i) {
xaxis += 5;
$('#option1').animate({
left: '+=5px',
top: Option1[i]
}, 400);
setTimeout(drawLines(), 400);
function drawLines() {
atx.lineTo(xaxis, Option1[i]);
atx.stroke();
};
};
});
html,
body {
width: 100%;
height: 100%;
background-color: black;
}
#maindiv {
position: absolute;
top: 5px;
left: 5px;
z-index: 5;
cursor: pointer;
Width: 500px;
Height: 400px;
background-color: black;
border-radius: 1%;
border-width: 0px;
border-color: blue;
border-style: solid;
font-family: Verdana, Arial, Sans-Serif;
color: white;
box-shadow: 0 0 20px white;
}
canvas {
position: absolute;
z-index: 5;
cursor: pointer;
Width: 100%;
Height: 100%;
background-color: none;
border-radius: 1%;
border-width: 1px;
border-color: blue;
border-style: solid;
font-family: Verdana, Arial, Sans-Serif;
color: white;
box-shadow: 0 0 20px white;
}
#option1 {
position: absolute;
top: 390px;
left: 5px;
z-index: 10;
Width: 5px;
Height: 5px;
background-color: green;
border-radius: 50%;
border-width: 0px;
border-color: blue;
border-style: solid;
font-family: Verdana, Arial, Sans-Serif;
color: white;
box-shadow: 0 0 20px white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<html>
<body>
<div id="maindiv">
<canvas id="myCanvas1" width="500" height="400"></canvas>
<div id="option1"></div>
</div>
</body>
</html>
(最后一个隐藏的代码段包含 html 和 css 顺便说一句,所以它可以正常工作)。没有成功。总线瞬间就在那里。我还尝试使用 Whosebug 上的其他帖子以其他方式编写 setTimeout
,但总是立即显示总行。
如果能帮助我实时绘制线条,将不胜感激!也欢迎使用完全不同 methods/functions 的解决方案。 谢谢!
您的第一个问题是您立即调用 drawLines
函数,然后将该函数的结果(未定义)传递给 setTimeout
。
More on that here
一旦你解决了这个问题,你会发现你有一个循环闭包的问题。有很多方法可以解决这个问题,尽管我选择创建一个新函数并将所需的变量传递给它,然后在该函数中创建超时。
More info on closure inside a loop
解决了这两个问题后,您将得到以下结果:
新函数:
function drawLine(atx, xaxis, y, delay){
setTimeout(function(){
atx.lineTo(xaxis, y);
atx.stroke();
}, delay);
}
这样调用来代替现有的 setTimeout
:
drawLine(atx, xaxis, Option1[i], 400 * i);
您会注意到我有 400 * i
超时延迟,而不是像您那样只有 400
。如果使用400,他们会在400ms后一次全部绘制。
这是一个工作片段:
$(document).ready(function() {
var Option1 = [100, 150, 150, 130, 50, 100, 75, 125, 50, 100];
var xaxis = 5;
var a = document.getElementById("myCanvas1");
var atx = a.getContext("2d");
atx.beginPath();
atx.moveTo(5, 400);
atx.strokeStyle="green";
for (var i = 0; i < Option1.length; ++i) {
xaxis += 5;
$('#option1').animate({
left: '+=5px',
top: Option1[i]
}, 400);
drawLine(atx, xaxis, Option1[i], 400 * i);
};
});
function drawLine(atx, xaxis, y, delay){
setTimeout(function(){
atx.lineTo(xaxis, y);
atx.stroke();
}, delay);
}
html,
body {
width: 100%;
height: 100%;
background-color: black;
}
#maindiv {
position: absolute;
top: 5px;
left: 5px;
z-index: 5;
cursor: pointer;
Width: 500px;
Height: 400px;
background-color: black;
border-radius: 1%;
border-width: 0px;
border-color: blue;
border-style: solid;
font-family: Verdana, Arial, Sans-Serif;
color: white;
box-shadow: 0 0 20px white;
}
canvas {
position: absolute;
z-index: 5;
cursor: pointer;
Width: 100%;
Height: 100%;
background-color: none;
border-radius: 1%;
border-width: 1px;
border-color: blue;
border-style: solid;
font-family: Verdana, Arial, Sans-Serif;
color: white;
box-shadow: 0 0 20px white;
}
#option1 {
position: absolute;
top: 390px;
left: 5px;
z-index: 10;
Width: 5px;
Height: 5px;
background-color: green;
border-radius: 50%;
border-width: 0px;
border-color: blue;
border-style: solid;
font-family: Verdana, Arial, Sans-Serif;
color: white;
box-shadow: 0 0 20px white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<html>
<body>
<div id="maindiv">
<canvas id="myCanvas1" width="500" height="400"></canvas>
<div id="option1"></div>
</div>
</body>
</html>