2016-04-11 2 views
1

Мой холст действует как карта. Пользователь получает щелчок по холсту, и он отображает маркер на карте (холст). Координаты хранятся в массиве.Сроки в HTML5 Холст

Когда пользователь нажимает кнопку воспроизведения, холст отображает первый маркер массива в своем положении, а второй - второй маркер, второй - позже, третий график и т. Д.

Как я мог достичь этого? Я пробовал использовать цикл for и вызывать функцию setTimeout, которая передает значение i в цикле, но циклы идут быстро, и я не могу опустить его в голову.

function timer() { 
    for (i=0; i<array.length; i++){ 
     play(i); 
    } 
} 


    function play(i) { 
    setTimeout(function() { 
    ctx.clearRect(0,0, c.width, c.height); 
    ctx.beginPath(); 
    ctx.moveTo(array[i].x, array[i].y); 
    ctx.lineTo(array[i].x,array[i].y); 
    cursor(array[i].x,array[i].y); 
    }, 1000); 

} 

ответ

1

Вы хотите установить интервал и очистить интервал, когда счетчик (который увеличивается в пределах этого) достигает определенной точки. Например: -

var t; 
var counter = 0; 
var array = ['your', 'data']; 

function timer() { 
    t = setInterval(play, 1000); 
} 

function play() { 
    if (counter !== array.length) { 
     ctx.clearRect(0,0, c.width, c.height); 
     ctx.beginPath(); 
     ctx.moveTo(array[counter].x, array[counter].y); 
     ctx.lineTo(array[counter].x,array[counter].y); 
     cursor(array[counter].x,array[counter].y); 
     counter++; 
    } else { 
     clearInterval(t); 
     t = null; 
    } 
} 

timer(); // begin calling play() every 1 second for array.length (2 in example) loops 
+0

Это хорошо, за исключением 99 как maxCount. Просто вытяните длину массива. :) – zfrisch

+0

setInterval - не лучший способ сделать это, так как он будет галочкой, даже если предыдущие тики не завершились. setTimeout было бы лучше или желательно requestAnimationFrame, но с логикой для обработки того, должен ли кадр обрабатываться или нет. И если вы используете requestAnimationFrame, то тикинг прекратится, если вы перейдете на другую вкладку, эффективно разместив анимацию на паузе, готовой для вас, когда вы вернетесь на вкладку. Гораздо эффективнее также часы с часами. – ManoDestra

1

setTimeout не может быть лучшим решением. Вы бы лучше использовали setInterval для вызова отдельной функции каждые x миллисекунд. Можете ли вы вставить цикл for?

редактировать:

Прежде всего, я вижу, что вы используете холст, так что я предполагаю, GoogleMaps API? Тем не менее, вы должны использовать requestAnimationFrame для любой анимационной работы. Кроме того, поскольку работа выполняется в вашей функции воспроизведения, функция таймера практически не имеет значения.

Я немного ржавый по запросуAnimationFrame сам, но я думаю, что этот код может немного помочь. Я думаю, что часть setInterval сделает requestAnimationFrame бессмысленным, и вам нужно перенести фактическое время в функцию воспроизведения. Я просто не могу вспомнить, как это сделать.

var i = 0; 
 
    
 
    /* 
 
    * change the 1000 to make the animation faster or slower. 
 
    * 1000ms == 1s so 10000 = 10 seconds 
 
    */ 
 
    setInterval(timer(), 1000); 
 

 
    function timer() { 
 
     window.requestAnimationFrame(play); 
 
    } 
 

 
    function play() { 
 
     if (i <= array.length) { 
 
     ctx.clearRect(0, 0, c.width, c.height); 
 
     ctx.beginPath(); 
 
     ctx.moveTo(array[i].x, array[i].y); 
 
     ctx.lineTo(array[i].x, array[i].y); 
 
     cursor(array[i].x, array[i].y); 
 
     i++; 
 
     window.requestAnimationFrame(play); 
 
     } 
 
    }

+0

обновленный вопрос с кодом –

+0

Yep, 'requestAnimationFrame' является путь - его более эффективно интегрировать с циклами обновления аппаратных средств и т.д. Кроме того, последняя версия RAF автоматически посылает временную метку аргумента, что вы можете используйте дроссельную заслонку в нужном темпе. Upvote. – markE

+1

Это потрясающе, как вы можете получить доступ к этой метке времени? Подключается ли она к функции, которую вы вызываете, или она сохраняется как переменная окна? Редактировать: btw спасибо за мой первый upvote! :) –

1

Используйте requestAnimationFrame и сохранить разницу в значениях клеща, так что вы только обработать ваши изменения после того, как каждый второй прошло.

Если вы не можете использовать requestAnimationFrame, используйте setTimeout (play, 1000), чтобы снова вызвать функцию воспроизведения через 1000 секунд. И просто увеличивайте свой индекс в конце и остановитесь, прежде чем вы получите индекс за пределы, конечно.

НЕ используйте setInterval, так как это может привести к перегрузке ваших операций предыдущего интервала. Он не дожидается завершения завершения предыдущей части обработки.

E.g.

<script> 
    var lastTick = 0; 
    var elapsed = 0; 
    var index = 0; 
    var array = [4, 5, 6, 7, 8, 9, 10]; 

    function animationLoop(tick) { 
     var diff = tick - lastTick; 
     elapsed += diff; 
     if (elapsed > 1000) { 
      ctx.clearRect(0, 0, c.width, c.height); 
      ctx.beginPath(); 
      ctx.moveTo(array[index].x, array[index].y); 
      ctx.lineTo(array[index].x, array[index].y); 
      cursor(array[index].x, array[index].y); 
      elapsed -= 1000; 
      index++; 
     } 

     if (index < array.length) { 
      lastTick = tick; 
      window.requestAnimationFrame(animationLoop); 
     } 
    } 

    window.requestAnimationFrame(animationLoop); 
</script>