2014-09-12 5 views
1

У меня есть две кнопки, которые позволяют увеличивать и уменьшать масштаб из моего холста анимацииКак масштабировать холст во время анимации?

<button id="zoomInButton">Zoom ++</button> 
<button id="zoomOutButton">Zoom -- </button> 

<canvas id="myCanvasmatchPage" > 
     Sorry, your browser doesn't support canvas technology 
</canvas> 

И у меня есть цикл анимации (пропущенный) с помощью setInterval и холст. Чтобы не было масштабирования, каждый setInterval должен быть вне цикла функции draw. Фактически ctx.scale сбрасывается при нажатии кнопки.

$('#myCanvasmatchPage').attr({width:100,height:200}).css({width:'100px',height:'200px'});  

var canvas = document.getElementById("myCanvasmatchPage"); 
ctx = canvas.getContext("2d"); 
ctx.translate(0.5,0.5); 

var nextFrame =0; 
var animationData = []; 

var canvasZoom = 1; //initial is scale 100% 
var incrementZoom = 0.05; 
$("#zoomInButton").click(function() 
    { 
    canvasZoom += incrementZoom; 
    ctx.scale(canvasZoom, canvasZoom); 
    }); 
$("#zoomOutButton").click(function() 
    { 
    if (canvasZoom > 1){//i dont want to allow a less than 100% scale zoom 
      canvasZoom -= incrementZoom; 
      ctx.scale(canvasZoom, canvasZoom); 
    } 
    }); 


var draw = function(){ 
    //cannot set scale within animation loop! keeps resetting! 
    ctx.clearRect(0, 0, canvas.width, canvas.height); 
    ctx.drawImage(images['background'], 0, 0, 622, 924, 0, 0, 311, 462); 

       if (nextFrame<=animationData.length){ 
        //animation loop 
       }else{ 
        clearTimeout(draw);//get out of the loop 
        return; 
       } 

       nextFrame++;  
    } 
    setInterval(draw,200); 

Мое текущее состояние этого кода заключается в том, что zoomIn 'works', но zoomOut doesn-t. Запись в консоли показала мне, что canvasZoom постоянно увеличивается и уменьшается на 0,05 (иногда 0,05000001 ха-ха), но холст не будет увеличиваться негативно.

Это заставляет меня думать, что проблема заключается в очистке холста, а не от масштабирования.

+0

Вы намерены сделать что-то еще, кроме масштабирования (поворот/перевод/перекос)? – GameAlchemist

+0

@GameAlchemist, на самом деле да, вращение, а также способ перемещения «центра пятна» анимации. – Gamemorize

ответ

1

Вы сделали довольно распространенную ошибку думать, что масштаб будет установить масштаб, когда канвы context2d это состояние машины, которая будет аккумулировать каждое изменение в верхней части друг с другом (EXPL масштаб X2, то масштаб x2 == масштаба X4).

Общий ответ на этот вопрос заключается в том, чтобы сохранить() ваш контекст, сделать ваши преобразования, сделать свои рисунки, а затем восстановить() его.

Так просто чтобы дать вам направление (непроверенные):

function Transform() { 
    this.scale = 1; 
    this.rotation = 0; 
    this.translation = {x:0, y:0 }; 
    this.zoomIn = function() { 
    this.scale+=0.5; 
    }; 
    this.zoomOut = function() { 
    this.scale-=0.5; 
    }; 
    this.translate(x,y) = function (x,y) { 
    this.translation.x+=x; // OR +=x*currentZoom; 
    this.translation.y+=y; // OR +=y*currentZoom; 
    }; 
    this.rotate = function (angle) { 
     this.rotation+=angle; 
    }; 
    this.applyTransform = function (ctx) { 
     ctx.translate(translation.x, translation.y); // ?? order ?? 
     ctx.scale(currentZoom, currentZoom);   // ?? order ?? 
     ctx.rotate(rotation);     
    } 
} 

var imageTransform = new Transform(); 

function drawImage(img) { 
    ctx.save(); 
    ctx.translate(img.width/2, img.height/2); 
    imageTransform.applyTransform(ctx); 
    ctx.drawImage(img, -img.wdth/2, -img.height/2); 
    ctx.restore(); 
} 

Порядок, в котором вы переводите/масштаб/поворот зависит фактически от вашего намерения: вы перемещения камеры или перемещения изображения? Вы масштабируете камеру или изображение? (вопрос имеет значение только в том случае, если есть несколько предметов для показа).

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

+0

Спасибо! Я собираюсь сделать изменения для шкалы через минуту. Что касается приоритезации других преобразований (очень умных, которые вы предвидели возможность), то сценарий заключается в том, что вы смотрите анимацию футбольного матча (поэтому более одного объекта для преобразования). Зритель будет иметь возможность увеличивать/уменьшать масштаб и либо удерживать стадию в центре мяча, либо уходить далеко от мяча, чтобы осмотреть другую часть поля. Вращение позволит просматривать портрет или пейзаж. – Gamemorize

+0

Теперь я посмотрю на ваш ответ, ваш первоначальный комментарий был достаточно, чтобы решить эту проблему примитивным способом. (см. мой ответ ниже) Еще раз спасибо. Посмотрите в свое решение сейчас. – Gamemorize

+0

Я обеспокоен, как я сказал в своем вопросе, что наличие преобразований внутри функции рисования анимации нежелательно. Может быть, более примитивный метод с ссылкой на контекст только с помощью функции щелчка лучше. Как вы думаете? – Gamemorize

0

Хотя я смотрю на более тщательное решение @GameAlchemist, здесь было бы решение простой задачи преобразования. Спасибо GameAlchemist за то, что он указал (очень важно!), Что масштабные изменения являются кумулятивными!

В функции мыши, важно сохранить чистую копию базы в масштабе против (здесь initialZoom)

var initialZoom = 1; //100% same as container (less border) 
    var zoomCounter = 1; 
    var incrementZoom = 0.05; 
    var canvasZoom = 1;//just to declare 

$("#zoomInButton").click(function() 
    { 
    canvasZoom = initialZoom + incrementZoom; 
    zoomCounter = zoomCounter + incrementZoom;//so i can track compared to original and block cumulative < 100& 
    ctx.scale(canvasZoom, canvasZoom); 
    }); 
$("#zoomOutButton").click(function() 
    { 
    if (zoomCounter > 1){//i dont want to allow a less than 100% scale zoom 
      canvasZoom = initialZoom - incrementZoom; 
      zoomCounter = zoomCounter - incrementZoom; 
      ctx.scale(canvasZoom, canvasZoom); 
    } 
    }); 

теперь прочь, чтобы увидеть, если решение GameAlchemist-s позволяет мне проще мульти преобразования!

+0

Хотя это должно работать только с масштабированием, я боюсь головных болей, когда вы добавляете ротацию/перевод. На самом деле я рассматриваю только два варианта viables: во-первых, как и мой ответ, но с ООП, поэтому все свойства находятся в пределах одного объекта, который не только более чист, но и позволяет использовать анимацию или другие функции. Во-вторых, это одно и то же, но вы сами построили матрицу преобразований, чтобы обновить преобразование с помощью одного setTransform. Это было бы быстрее, но я боюсь, что это слишком оптимистично, первое решение должно быть достаточно быстрым. – GameAlchemist

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