Clear entire, transformed HTML5 Canvas while preserving context transform

前端 未结 2 2051
走了就别回头了
走了就别回头了 2020-12-16 00:38

I want to zoom and pan an HTML5 Canvas by transforming the context using translate() and scale(), clearing the canvas, and then redrawing. Note tha

2条回答
  •  时光说笑
    2020-12-16 01:06

    For those who care to track their full context transforms, here's my code for doing so in an on-demand, per-context basis. This is prefaced with the usage that shows how to clear the full rectangle based on the transformed coordinates. You can see the code in use on my website.

    window.onload = function(){
      var canvas = document.getElementsByTagName('canvas')[0];
      var ctx = canvas.getContext('2d');
      trackTransforms(ctx);
      function redraw(){
        var p1 = ctx.transformedPoint(0,0);
        var p2 = ctx.transformedPoint(canvas.width,canvas.height);
        ctx.clearRect(p1.x,p1.y,p2.x-p1.x,p2.y-p1.y);
        // ... 
      }
    }
    
    
    // Adds ctx.getTransform(), returning an SVGMatrix
    // Adds ctx.transformedPoint(x,y), returning an SVGPoint
    function trackTransforms(ctx){
      var svg = document.createElementNS("http://www.w3.org/2000/svg",'svg');
      var xform = svg.createSVGMatrix();
      ctx.getTransform = function(){ return xform; };
    
      var savedTransforms = [];
      var save = ctx.save;
      ctx.save = function(){
        savedTransforms.push(xform.translate(0,0));
        return save.call(ctx);
      };
      var restore = ctx.restore;
      ctx.restore = function(){
        xform = savedTransforms.pop();
        return restore.call(ctx);
      };
    
      var scale = ctx.scale;
      ctx.scale = function(sx,sy){
        xform = xform.scaleNonUniform(sx,sy);
        return scale.call(ctx,sx,sy);
      };
      var rotate = ctx.rotate;
      ctx.rotate = function(radians){
        xform = xform.rotate(radians*180/Math.PI);
        return rotate.call(ctx,radians);
      };
      var translate = ctx.translate;
      ctx.translate = function(dx,dy){
        xform = xform.translate(dx,dy);
        return translate.call(ctx,dx,dy);
      };
      var transform = ctx.transform;
      ctx.transform = function(a,b,c,d,e,f){
        var m2 = svg.createSVGMatrix();
        m2.a=a; m2.b=b; m2.c=c; m2.d=d; m2.e=e; m2.f=f;
        xform = xform.multiply(m2);
        return transform.call(ctx,a,b,c,d,e,f);
      };
      var setTransform = ctx.setTransform;
      ctx.setTransform = function(a,b,c,d,e,f){
        xform.a = a;
        xform.b = b;
        xform.c = c;
        xform.d = d;
        xform.e = e;
        xform.f = f;
        return setTransform.call(ctx,a,b,c,d,e,f);
      };
      var pt  = svg.createSVGPoint();
      ctx.transformedPoint = function(x,y){
        pt.x=x; pt.y=y;
        return pt.matrixTransform(xform.inverse());
      }
    }
    

提交回复
热议问题