Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何移动旋转的画布图像而不致迷失方向?_Javascript_Jquery_Canvas_Html5 Canvas_Filereader - Fatal编程技术网

Javascript 如何移动旋转的画布图像而不致迷失方向?

Javascript 如何移动旋转的画布图像而不致迷失方向?,javascript,jquery,canvas,html5-canvas,filereader,Javascript,Jquery,Canvas,Html5 Canvas,Filereader,我有一个图像加载到画布。旋转后,我无法(拖动)正确移动图像。实际上,它会移动,但它会根据图像的坐标平面移动。因此,将旋转90度的图像向右移动,会向下移动,而不是像预期的那样向右移动。解决这个问题的好办法是什么 这是我的绘图功能: function draw(){ var im_width = parseInt( imageObj.width + resizeAmount ); var im_height = parseInt( imageObj.height + resizeA

我有一个图像加载到画布。旋转后,我无法(拖动)正确移动图像。实际上,它会移动,但它会根据图像的坐标平面移动。因此,将旋转90度的图像向右移动,会向下移动,而不是像预期的那样向右移动。解决这个问题的好办法是什么

这是我的绘图功能:

function draw(){
    var im_width = parseInt( imageObj.width + resizeAmount );
    var im_height = parseInt( imageObj.height + resizeAmount );
    var rotationAmount = rotationVal - prevRotation;
    prevRotation = rotationVal;

    context.clearRect( 0, 0, canvas.width, canvas.height );
    context.translate( canvas.width/2, canvas.height/2 );
    context.rotate( rotationAmount * Math.PI / 180 );
    context.translate( -canvas.width/2, -canvas.height/2 );
    context.drawImage( imageObj, moveXAmount, moveYAmount, im_width, im_height );     
} 
在这里,你可以模拟它,看看我的意思


PS:您可以使用左侧的滑块旋转图像。底部滑块用于缩放。如果第一次加载时图像没有出现,请重新运行小提琴。

绘制后重置变换。鼠标事件在应用于画布上下文时也会被转换,因此只有在绘图时使用转换才能解决此问题。但是,这也要求代码使用绝对值,例如:

function draw(){
    var im_width = parseInt( imageObj.width + resizeAmount, 10 );
    var im_height = parseInt( imageObj.height + resizeAmount, 10 );
    var rotationAmount = rotationVal; // disabled: - prevRotation;

    context.clearRect( 0, 0, canvas.width, canvas.height );

    // move to origin first
    context.translate( moveXAmount, moveYAmount );

    // rotate
    context.rotate( rotationAmount * Math.PI / 180 );

    // change to translate back based on image size
    // (remember to compensate for scale, not shown here)
    context.translate( -imageObj.width/2, -imageObj.height/2 );
    context.drawImage( imageObj, 0, 0, im_width, im_height );

    // reset transforms (identity matrix)
    context.setTransform(1,0,0,1,0,0);
} 

或者,您需要使用逆矩阵。当我们可以根据当前的变换矩阵提取SVG矩阵时,这将成为一种可用的方法,但目前还不能广泛使用。否则,逆矩阵将应用于鼠标的x/y位置,以对主变换的效果进行排序(顾名思义)

可以选择使用自定义转换矩阵解决方案来跟踪转换(我将邀请您查看我自己的方法,这是免费的)

PS:还修复了图像加载问题(请参阅fiddle)


投票选出好答案。另外,@Skeletor:我强烈推荐K3N的转换库。如果您将来需要在转换后的图像上点击测试鼠标,那么K3N的库将非常方便。:-)
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
canvas.width = 500;
canvas.height = 500;
var x      = 250;
var y      = 500;
var width  = 100;
var height = 100
var cx     = x + 0.5 * width;   // x of shape center
var cy     = y + 0.5 * height;  // y of shape center



class Meteor {
  constuctor(degrees){
    this.degrees = degrees;
    //this.y = 0; 
  }
  draw(d){
      //this.y = y++
      ctx.save();
      ctx.translate(x,d)
      ctx.rotate( (Math.PI / 180) * d);  //rotate 25 degrees.
      ctx.translate(-cx, -cy);            //translate center 
      ctx.fillStyle = "#0000ff";
       ctx.fillRect(x, y, width, height);
      ctx.restore();

      //ctx.setTransform(1, 0, 0, 1, 0, 0);

  }
}
let m = new Meteor(90)

d = 0; 
function animate(){
  ctx.clearRect(0,0,canvas.width,canvas.height)
  // Save the default state
  d++;
  m.draw(d)


  // Restore the default state


  ctx.fillRect(250, 40, 10, 10); //spaceship 
  ctx.fillRect(150, d, 100, 100);  
  window.requestAnimationFrame(animate)
}
animate()





function draw(){
    var im_width = parseInt( imageObj.width + resizeAmount, 10 );
    var im_height = parseInt( imageObj.height + resizeAmount, 10 );
    var rotationAmount = rotationVal; // disabled: - prevRotation;

    context.clearRect( 0, 0, canvas.width, canvas.height );

    // move to origin first
    context.translate( moveXAmount, moveYAmount );

    // rotate
    context.rotate( rotationAmount * Math.PI / 180 );

    // change to translate back based on image size
    // (remember to compensate for scale, not shown here)
    context.translate( -imageObj.width/2, -imageObj.height/2 );
    context.drawImage( imageObj, 0, 0, im_width, im_height );

    // reset transforms (identity matrix)
    context.setTransform(1,0,0,1,0,0);
}