javascript - 旋转放置在 Canvas 中的 2 个 Canvas 对象之一

标签 javascript jquery html jquery-ui canvas

我正在使用 Canvas 开发网络应用程序,我制作了三个。 canvas、canvas_panoramacanvas_image
第一个是类似主 Canvas 的东西,是其他 Canvas 的容器。 canvas_panoramacanvas_image 的背景。

右键单击 Canvas 后,我正在计算旋转canvas_image的 Angular :

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

当我有一个 Angular 后,我尝试像这样旋转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向你展示我的问题

最佳答案

我认为您对多个 Canvas 的想法感到困惑。

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

转换方法确实适用于 Canvas 的上下文矩阵,并且仅当您在设置它们时执行一些绘图操作时才会生效。

注意:要重置上下文矩阵,您可以使用 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>

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

您想要的是仅在主 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>

关于javascript - 旋转放置在 Canvas 中的 2 个 Canvas 对象之一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34975299/

相关文章:

jquery - $ ("body").ready() 有效,但 $ ("body").load() 不起作用?

html - box-shadow 覆盖我整个页面的问题

Javascript:可变宽度多维数组

javascript - 根据用户代理加载样式表

jquery - jeditable(内联编辑器)不适用于动态生成的元素

html - 嵌套元素中的 CSS 透明度问题

html - iOS UIWebView 强制图像大小 objective-c Xcode

javascript - 当绝对定位元素覆盖时忽略 mouseleave 事件

javascript - 原型(prototype)设计时跟踪 javascript 对象引用的最佳方法是什么

jquery - 如何更新本地存储阵列的特定键值?