#javascript #html #html5-canvas
#javascript #HTML #html5-холст
Вопрос:
Я пытаюсь создать веб-сайт, чтобы визуально показать работу алгоритма средней линии. Я хочу отобразить точки через определенный интервал времени, но функция setTimeout() работает неправильно. Он просто показывает конечный результат после ожидания в течение 3 секунд.
<canvas id="ltpcanvas" style="border: 1px solid #000000;">
</canvas>
<script>
window.onload = function(){
var ltpc = document.getElementById('ltpcanvas');
ltpc.width = window.innerWidth;
ltpc.height = window.innerHeight;
var context = ltpc.getContext('2d');
var cx1,cx2,cy1,cy2;
var count=0;
ltpc.addEventListener('mousedown',onDown,false);
function onDown(event){
count ;
cx = event.pageX;
cy = event.pageY;
cy-=9;
cx-=9;
if(count == 1){
cx1=cx;
cy1=cy;
}
else{
cx2=cx;
cy2=cy;
}
var ltpc = document.getElementById('ltpcanvas');
var context = ltpc.getContext('2d');
context.fillStyle = 'black';
context.beginPath();
context.arc(cx,cy,2,0*Math.PI,2*Math.PI,true);
context.closePath();
context.fill();
if(cx1!=undefined amp;amp; cx2!=undefined amp;amp; cy1!=undefined amp;amp; cy2!=undefined){
if(cx1<cx2amp;amp;cy1<cy2)
midpoint(cx1,cy1,cx2,cy2);
else{
alert('cx1 = ' cx1 ' cy1 = ' cy1 'ncx2 = ' cx2 ' cy2 = ' cy2);
}
}
}
}
function midpoint(X1,Y1,X2,Y2){
var dx = X2 - X1;
var dy = Y2 - Y1;
var d = dy - (dx/2);
var x = X1
var y = Y1;
while (x < X2)
{
x ;
if (d < 0)
d = d dy;
else
{
d = (dy - dx);
y ;
}
myvar = setTimeout(Dotfunction,3000,x,y);
console.log(x);
console.log(y);
}
}
function Dotfunction(x,y){
var ltpc = document.getElementById('ltpcanvas');
var context = ltpc.getContext('2d');
context.fillStyle = 'black';
context.beginPath();
context.arc(x,y,1,0*Math.PI,2*Math.PI,true);
context.closePath();
context.fill();
}
</script>
Я пытаюсь каждый раз откладывать выполнение Dotfunction(), но оно задерживается на 3 секунды, а затем показывает всю строку. Я хочу, чтобы он задерживался после отображения каждой точки.
Ответ №1:
Я хочу отображать точки через определенный интервал времени
Здесь важно то, что мы хотим показывать не «точки», а «каждую точку» через интервал. Это означает, что каждая точка будет нарисована сама по себе. Я предполагаю, что вы хотите, чтобы точки появлялись одна за другой в анимации.
Проблема в том, что в этом коде мы вызываем setTimeout()
несколько раз с одной и той же целевой задержкой. Т.Е. Мы говорим движку «сделать это за 3 секунды» много раз в течение одного мгновения. Самое простое решение для получения анимации — пропускать все более высокие таймауты. Поскольку мы вызываем функцию внутри цикла и поскольку в ней уже есть счетная переменная, мы можем просто использовать ее повторно и попросить движок JS отрисовывать каждую точку через 10 миллисекунд после предыдущей.
Следующий код рисует линию со скоростью 100 пикселей в секунду.
PS: Я удалил поле тела, так что больше нет необходимости вычитать его из положения курсора.
window.onload = function(){
var ltpc = document.getElementById('ltpcanvas');
ltpc.width = window.innerWidth;
ltpc.height = window.innerHeight;
var context = ltpc.getContext('2d');
var cx1, cx2, cy1, cy2;
var count = 0;
ltpc.addEventListener('mousedown', onDown, false);
function onDown(event) {
count ;
cx = event.pageX;
cy = event.pageY;
if (count == 1) {
cx1 = cx;
cy1 = cy;
}
else {
cx2 = cx;
cy2 = cy;
}
var ltpc = document.getElementById('ltpcanvas');
var context = ltpc.getContext('2d');
context.fillStyle = 'black';
context.beginPath();
context.arc(cx, cy, 2, 0 * Math.PI, 2 * Math.PI, true);
context.closePath();
context.fill();
if (cx1 != undefined amp;amp; cx2 != undefined amp;amp; cy1 != undefined amp;amp; cy2 != undefined) {
if (cx1 < cx2 amp;amp; cy1 < cy2)
midpoint(cx1, cy1, cx2, cy2);
else {
// alert('cx1 = ' cx1 ' cy1 = ' cy1 'ncx2 = ' cx2 ' cy2 = ' cy2);
}
}
}
}
function midpoint(X1, Y1, X2, Y2){
var dx = X2 - X1;
var dy = Y2 - Y1;
var d = dy - (dx / 2);
var x = X1
var y = Y1;
while (x < X2)
{
x ;
if (d < 0)
d = d dy;
else {
d = (dy - dx);
y ;
}
setTimeout(Dotfunction, x * 10, x, y);
//console.log(x);
//console.log(y);
}
}
function Dotfunction(x, y) {
var ltpc = document.getElementById('ltpcanvas');
var context = ltpc.getContext('2d');
context.fillStyle = 'black';
context.beginPath();
context.arc(x, y, 1,0 * Math.PI, 2 * Math.PI, true);
context.closePath();
context.fill();
}
body {
margin: 0;
}
<canvas id="ltpcanvas" style="border: 1px solid #000000;"></canvas>