javascript - 如何在动画期间缩放 Canvas ?

标签 javascript jquery animation html5-canvas

我有两个按钮可以放大和缩小 Canvas 动画

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

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

我有一个使用 setInterval 和 canvas 的动画循环(省略)。为了不让每个 setInterval 发生缩放,它必须脱离绘制函数循环。事实上,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“有效”,但zoomOut则不行。控制台日志记录显示,canvasZoom 确实会一致地上下移动 0.05(有时也是 0.05000001 哈哈),但 Canvas 不会负向缩放。

这让我认为问题在于 Canvas 的清理而不是缩放。

最佳答案

您犯了一个很常见的错误,认为当 Canvas 的 context2D 是一个状态机时,比例将设置比例,状态机会将每个更改累积到彼此之上(expl 比例 X2,然后比例x2 == 缩放 X4 )。

这个问题的常见答案是 save() 你的上下文,进行转换,进行绘图,然后恢复 () 它。

所以只是给你方向(未经测试):

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();
}

平移/缩放/旋转的顺序实际上取决于您的意图:您是在移动相机,还是在移动图像?您正在缩放相机或图像吗? (仅当有多个项目要显示时才相关问题)。

希望这会有所帮助。

关于javascript - 如何在动画期间缩放 Canvas ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25811410/

相关文章:

javascript - 将谷歌地图自动完成限制在欧洲边界

javascript - Rails 中的 AJAX 与 jQuery 问题

javascript - 单击 <img> 切换 Div 类

ios - 并行多个快速动画不起作用

javascript - 将一个数组与另一个数组值拼接

javascript - 创建指令,将每个列表元素包装在 Bootstrap 面板内,并带有删除、重新排序等控件。

javascript - jQuery动态复选框位置、合并示例发现

ios - 如何在 iOS 中使用图像创建连续动画

javascript - 从上到下隐藏方 block

javascript - 在 jQuery 中检测对具有不可预测 ID 的 DIV 的点击