2015-06-13 5 views
0

Моя проблема в том, что линия ничья мгновенно.медленно анимировать простую линию

То, что я хочу, это Нарисуйте линию очень медленно, почти за 3-5 секунд до этого заканчивается на dy. По какой-то причине я не могу заставить setTimeout() работать. Я пробовал большие и маленькие значения.

У меня только пример базовой строки, но я буду расширять эту концепцию, чтобы включить x и bezier lines, как только я смогу понять, как работает тайм-аут.

var canvas = document.getElementById('myCanvas'); 
var context = canvas.getContext('2d'); 

function myLine(x, y, dx, dy) { //Line constructor 
    this.x = x; //start x 
    this.y = y; //start y 
    this.dx = dx; //end x 
    this.dy = dy; //end y 
} 
var line = new myLine(100, 5, 100, 100); //line object 

function drawLine(myLine, context) { //Draw function 
    context.moveTo(myLine.x, myLine.y); 
    animate(line, context); 
    } 
function animate(myLine, context) { //animation function 
    if (myLine.y < myLine.dy) { 
     myLine.y = myLine.y + 1; 
     context.lineTo(myLine.dx, myLine.y); 
     context.stroke(); 
     window.setTimeout(animate(line, context), 1000/60); 
    } 
} 
drawLine(line, context); 
+0

можно использовать jQuery или это нужно делать только с помощью javaScript? – alpha

+0

Я могу использовать jQuery. –

ответ

2

Это фактически не что вы хотите сделать: компьютеры не делают «медленно», особенно не в контексте однопоточности. Вместо этого вы должны сделать вывод: лотов строк, снова и снова, где каждая следующая строка немного длиннее предыдущей. Таким образом, это выглядит, как линия растет, и вы получите именно то, что вы хотите:

function drawLine(x1,y1,x2,y2,ratio) { 
    ctx.fillRect(0,0,300,300); 
    ctx.beginPath(); 
    ctx.moveTo(x1,y1); 
    x2 = x1 + ratio * (x2-x1); 
    y2 = y1 + ratio * (y2-y1); 
    ctx.lineTo(x2,y2); 
    ctx.stroke(); 
    // And if we intend to start new things after 
    // this, and this is part of an outline, 
    // we probably also want a ctx.closePath() 
} 

function animate(ratio) { 
    ratio = ratio || 0; 
    drawLine(0,0,300,300,ratio); 
    if(ratio<1) { 
    requestAnimationFrame(function() { 
     animate(ratio + 0.01); 
    }); 
    } 
} 

animate(); 

Запуск код: http://jsbin.com/hanaqahoyu/edit?html,js,output

Также обратите внимание, что мы не хотите использовать SetTimeout: для того, чтобы обеспечить плавную анимацию, современные браузеры имеют requestAnimationFrame, что будет вызывать , когда это имеет смысл для рамки анимации, что очень удобно: мы будем использовать это.

+0

Какова эффективность между вашим подходом и моим подходом, если я добавил requestAnimationFrame к моему? –

+0

почти то же самое сопоставимо, хотя я бы сказал, что способ распространения вашей логики немного затягивается, поэтому вы выполняете всю свою логику «что рисовать, а затем рисовать» внутри одной функции. Следовательно, небольшая перекодировка для вычисления отношения в jsbin –

+0

очень приятная, теперь есть хороший способ оживить с помощью bezierCurveTo? Я полагаю, что контрольные точки будут некоторым типом отношения x2 и y2? –

0

window.setTimeout принимает ссылку на функцию в качестве первого аргумента, вы прошли в результате вызова animate(), который undefined. Это не будет сделано.

Простая установка - анонимная функция.

window.setTimeout(function() { animate(line, context); }, 1000/60); 

Более совершенный метод заключается в использовании .bind().

window.setTimeout(animate.bind(null, line, context), 1000/60); 

Кроме того, поскольку вы работаете с анимацией, подумайте в requestAnimationFrame.

+0

Спасибо, что сработало. Я был смущен документами, потому что некоторые из них имели анонимные звонки, а другие - нет. Я должен был сначала выполнить анонимные вызовы функций –

+0

Я просмотрел requestAnimationFrame, но я не знаю, будет ли он в этом нуждаться. Я создаю интерактивную функцию Q/A на веб-сайте, и эта анимация будет активирована только тогда, когда пользователь нажимает на div –

+0

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

0

Другим подходом может быть использование requestAnimationFrame. Взгляните на код ниже:

window.requestAnimFrame = (function() { 
    return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback) { 
     window.setTimeout(callback, 1000/60); 
    }; 
})(); 

var canvas = document.getElementById('myCanvas'); 
var context = canvas.getContext('2d'); 
var line = null; 

function myLine(x, y, dx, dy) { 
    this.x = x; 
    this.y = y; 
    this.dx = dx; 
    this.dy = dy; 
} 

line = new myLine(100, 5, 100, 100); 

requestAnimFrame(render); 

function render() { 
    requestAnimFrame(render); 
    if (line.y < line.dy) { 
     line.y = line.y + 1; 
     context.lineTo(line.dx, line.y); 
     context.stroke(); 
    } 
} 

Надеюсь, что это поможет.

Смежные вопросы