旋转中心点为盒子中心点,缩放相对于左上角缩放。这样的思路会引起图像在旋转后做缩放操作时导致图像位移。以下是解决方式:

思路是:原本的缩放是相对与top和left的,也就是说top和left不会变。现在我们需要计算出两个图形(缩放前后)的相对点的x和y的差,然后设置top和left来保证相对点的稳定。

步骤:

  1. 在缩放前记录图形信息
  2. 在缩放后计算出当前图形信息
  3. 对比前后信息,然后进行位移

关键代码

/*
x:left,y:top,width:宽度,height:高度
sin:旋转角度正弦,cos余弦
*/
function transform(options, sin, cos) {
  let x = options.x;
  let y = options.y;
  let width = options.width;
  let height = options.height;
 
  let centerX = x + width / 2;
  let centerY = y + height / 2;
 
  let top_left_x = centerX + (cos * -1 * width / 2 - sin * height / 2)
  let top_left_y = centerY - (sin * -1 * width / 2 + cos * height / 2)
 
  let top_right_x = centerX + (cos * width / 2 - sin * height / 2)
  let top_right_y = centerY - (sin * width / 2 + cos * height / 2)
 
  let bottom_left_x = centerX + (cos * -1 * width / 2 - sin * -1 * height / 2)
  let bottom_left_y = centerY - (sin * -1 * width / 2 + cos * -1 * height / 2)
 
  let bottom_right_x = centerX + (cos * width / 2 - sin * -1 * height / 2)
  let bottom_right_y = centerY - (sin * width / 2 + cos * -1 * height / 2)
 
  return {
    point: {
      topLeft: [top_left_x, top_left_y],
      topRight: [top_right_x, top_right_y],
      bottomLeft: [bottom_left_x, bottom_left_y],
      bottomRight: [bottom_right_x, bottom_right_y]
    },
    centerX: centerX,
    centerY: centerY,
    maxY: Math.max(top_left_y, top_right_y, bottom_right_y, bottom_left_y),
    minX: Math.min(top_left_x, top_right_x, bottom_left_x, bottom_right_x),
    minY: Math.min(top_left_y, top_right_y, bottom_right_y, bottom_left_y),
    maxX: Math.max(top_left_x, top_right_x, bottom_left_x, bottom_right_x)
  }
}

注:

  • 旋转公式:x=x0cos-y0sin y=x0sin+y0cos (x,y:旋转后的横,纵坐标;x0,y0:原坐标;sin,cos:旋转角度的正余弦)
  • 变换矩阵:matrix(cos, sin, -sin, cos, tx, ty) tx:x位移,ty:y位移

标签: 矩阵, 图像变换, javascript

仅有一条评论

  1. 獲益良多

添加新评论