2014-09-12 168 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 2014-09-12 15:43:41

+0

@GameAlchemist,實際上是旋轉,也是一種移動動畫「中心點」的方式。 – Gamemorize 2014-09-12 15:46:20

回答

1

你所做的很常見的錯誤地認爲規模將設置規模,當畫布的context2D是一個狀態機,這將累積在彼此的頂部每一個變化(EXPL規模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 2014-09-12 16:29:49

+0

我現在要看看你的答案,你的初步評論足以以一種原始的方式解決這個問題。 (請參閱下面的答案)再次感謝。現在看看你的解決方案。 – Gamemorize 2014-09-12 17:02:13

+0

我擔心,就像我在我的問題中所說的那樣,在動畫的繪製函數內部進行變換是不可取的。也許只通過點擊函數引用上下文的更原始的方法更好。你怎麼看? – Gamemorize 2014-09-12 17:10:37

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

儘管這隻適用於縮放,但我擔心在添加旋轉/平移時會頭疼。實際上,我認爲只有兩個可行選項:第一個就像我的答案,但與OOP,所以所有的屬性都在一個單一的對象,這不僅是更清潔,但也允許補間或其他功能。其次是完全相同的,但是你會自己構建一個變換矩陣來用一個setTransform來更新變換。這會更快,但我擔心它過度優化,首先解決方案應該足夠快。 – GameAlchemist 2014-09-12 17:16:14