旋转放置在画布中的2个画布对象之一

时间:2016-01-24 11:40:21

标签: javascript jquery html5 jquery-ui canvas

我正在使用画布开发Web应用程序,我做了三个。 canvas, canvas_panoramacanvas_image
第一个是像主画布,其他人的主张。 canvas_panoramacanvas_image的背景。

右键单击画布后,我正在计算旋转canvas_image的角度:

function getAngle( e, pw /*canvas*/ ){
      var offset = pw.offset();
      var center_x = (offset.left) + ($(pw).width() / 2);
      var center_y = (offset.top) + ($(pw).height() / 2);
      var mouse_x = e.pageX;
      var mouse_y = e.pageY;
      var radians = Math.atan2(mouse_x - center_x, mouse_y - center_y);
      angle = radians;
}

在我有角度后,我正试图像这样旋转canvas_image

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

    canvas_image_ctx.drawImage(image_img, 0, 0, 150, 150);

    canvas_panorama_ctx.drawImage(panorama_img, 0, 0, 600, 300);
    canvas_panorama_ctx.drawImage(canvas_image, 20, 20);

    // rotate panorama_img around its center
    // x = x + 0.5 * width
    // y = y + 0.5 * height
    canvas_panorama_ctx.translate(95, 95);
    canvas_panorama_ctx.rotate(angle);
    // translate to back
    canvas_panorama_ctx.translate(-95, -95);

    ctx.drawImage(canvas_panorama, 0, 0);
 }

但这会同时调整canvas_imagecanvas_panorama。它应该只旋转canvas_image

JSFiddle向您展示我的问题

1 个答案:

答案 0 :(得分:2)

我认为你对这种多幅画布的想法感到困惑。

一旦进入drawImage()方法,您的每幅画布都只是图像,可能只是一个,甚至只是简单的形状。

转换方法确实适用于画布的上下文矩阵,只有在设置它们时进行一些绘制操作才会生效。

注意:要重置上下文矩阵,您可以使用save();restore()方法,这些方法也会保存上下文的所有其他属性,因此如果您只需要重置转换,那么它就是首选将转换矩阵重置为默认值:ctx.setTransform(1,0,0,1,0,0)

这是一个简化的例子,可以让事情变得更加清晰:

var ctx = canvas.getContext('2d');

// a single shape, with the border of the context matrix
var drawRect = function(){
    ctx.beginPath();
    ctx.rect(10, 10, 50, 20);
    ctx.fill();
    ctx.stroke();
    ctx.beginPath();
    ctx.rect(0, 0, canvas.width, canvas.height);
    ctx.stroke();
};

// set the color of our shapes
var gradient = ctx.createLinearGradient(0,0,70,0);
gradient.addColorStop(0,"green");
gradient.addColorStop(1,"yellow");
ctx.fillStyle = gradient;

// here comes the actual drawings

//we don't have modified the transform matrix yet
ctx.strokeStyle  = "green";
drawRect();

// here we translate of 100px then we do rotate the context of 45deg
ctx.translate(100, 0)
ctx.rotate(Math.PI/4)
ctx.strokeStyle = "red";
drawRect();

// reset the matrix
ctx.setTransform(1,0,0,1,0,0);

// here we move of 150px to the right and 25px to the bottom
ctx.translate(150, 25)
ctx.strokeStyle = "blue";
drawRect();

// reset the matrix
ctx.setTransform(1,0,0,1,0,0);
<canvas id="canvas" width="500" height="200"></canvas>

在您的代码中,您将在画布上设置代表您图像的转换,并在每次调用时绘制每个画布。

您想要的只是在主画布上设置转换,并绘制未转换的图像:

var main_ctx = canvas.getContext('2d');

var img_canvas = canvas.cloneNode();

var bg_canvas = canvas.cloneNode();

var angle = 0;

// draw on the main canvas, and only on the main canvas
var drawToMain = function(){
  // first clear the canvas
  main_ctx.clearRect(0,0,canvas.width, canvas.height);
  // draw the background image
  main_ctx.drawImage(bg_canvas, 0,0);
  // do the transforms
  main_ctx.translate(img_canvas.width/2, img_canvas.height/2);
  main_ctx.rotate(angle);
  main_ctx.translate(-img_canvas.width/2, -img_canvas.height/2);
  // draw the img with the transforms applied
  main_ctx.drawImage(img_canvas, 0,0);
  // reset the transforms
  main_ctx.setTransform(1,0,0,1,0,0);
  };

// I changed the event to a simple onclick
canvas.onclick = function(e){
    e.preventDefault();
    angle+=Math.PI/8;
    drawToMain();
  }


// a dirty image loader
var init = function(){
  var img = (this.src.indexOf('lena')>0);
  var this_canvas = img ? img_canvas : bg_canvas;
  this_canvas.width = this.width;
  this_canvas.height = this.height;
  this_canvas.getContext('2d').drawImage(this, 0,0);
  if(!--toLoad){
      drawToMain();
    }
  };

var toLoad = 2;
var img = new Image();
img.onload = init;
img.src = "http://pgmagick.readthedocs.org/en/latest/_images/lena_scale.jpg";

var bg = new Image();
bg.onload = init;
bg.src = 'http://www.fnordware.com/superpng/pnggradHDrgba.png';
<canvas id="canvas" width="500" height="300"></canvas>