crop image 需要的基础知识

Posted keatkeat

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了crop image 需要的基础知识相关的知识,希望对你有一定的参考价值。

refer : 

https://www.youtube.com/watch?v=R7dObDtw1aA

https://www.shuxuele.com/algebra/trig-finding-angle-right-triangle.html

https://developer.mozilla.org/en-US/docs/Web/javascript/Reference/Global_Objects/Math/atan

https://www.rapidtables.com/convert/number/how-radians-to-degrees.html

 

1. coordinate 和 css translate 是不同的东西

数学有 coordinate x,y , 

左上是 ( -x, +y )

右上是 ( +x, +y)

左下是 ( -x, -y)

右下是 ( +x, -y)

css translate 是说移动的方向. 

+x 是往右

-x 是往左 

+y 是往下

-y 是往上 

注意 : coordinate y 和 translate y 是相反的. 

 

2. 三角形和 tan sin cos

tan sin cos 在 js 里是 Math.cos, Math.sin, Math.tan

反向是 Math.acos, Math.asin, Math.atan 

一般上我们 cos(degree) 使用的是 degree, 但是 js 使用的是 radian

所以要背一个转换的公式 

radian = degree * Math.PI / 180;

export function degreeToRadian(degree: number): number {
  return degree * Math.PI / 180;
}

export function radianToDegree(radian: number): number {
  return radian * 180 / Math.PI;
}

求三角形斜线的长度是 

技术图片

export function calcRadius(width: number, height: number): number {
  return Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));
}

求 x, y coordinate 当拥有 degree 和 radius (斜线的长度)

技术图片

cos(deg) = x / radius

sin(deg) = y / radius

export function calcCoordinate(radius: number, degree: number): Xy {
  return {
    x: Math.cos(degreeToRadian(degree)) * radius,
    y: Math.sin(degreeToRadian(degree)) * radius
  }
}

求 degree 当有 x, y

单靠反推上面求 x,y 的公式,我们是无法获取 degree 的,因为 cos(135) === cos(225).

所以更好的做法是通过 tan 

技术图片

tan(d) = y / x

有一点要特别注意就是, x y 的正负值, 代表了它在不同区域. 这个是会直接影响 degree 的. 我们要特别处理.

export function calcDegree(coordinate: Xy): number {
  const { x, y } = coordinate;
  const result = radianToDegree(Math.atan(y / x));
  if (x < 0 && y >= 0) {
    return 180 - Math.abs(result); // 这里 result 是 negative
  }
  else if (x < 0 && y < 0) {
    return 180 + result; // 这里 result 是 positive
  }
  else if (x >= 0 && y < 0) {
    return 360 - Math.abs(result) // 这里 result 是 negative
  }
  else { 
    return result; // 这里 result 是 positive
  }
}

最后是 js 的另一个函数来做到上面一样的效果. Math.atan2(y, x)

export function calcDegree(coordinate: Xy): number {
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2
  const result = radianToDegree(Math.atan2(coordinate.y, coordinate.x));
  return (result > 0) ? result : 360 - Math.abs(result);
}

 

css 的 rotate 和我们数学的方向也是不太一样的, 数学我们是 右边线开始,逆时针旋转 20 degree 是这样的. 上面的算法全部基于这个概念

 技术图片

所以如果我想说下面这个 x, y 顺势旋转 20 degree 算法应该是.. 

技术图片

export function calcCoordinateAfterRotate(currentCoordinate: Xy, rotateDegree: number): Xy {
  const radius = calcRadius(Math.abs(currentCoordinate.x), Math.abs(currentCoordinate.y));
  const degree = calcDegree(currentCoordinate);
  const degreeAfterRotate = degree - rotateDegree;
  return calcCoordinate(radius, degreeAfterRotate);
}

 

换算 coordinate 去 translate x, y

export function calcTranslate(fromCoordinate: Xy, toCoordinate: Xy): Xy {
  return {
    x: toCoordinate.x - fromCoordinate.x,
    y: fromCoordinate.y - toCoordinate.y
  }
}

 

以上是关于crop image 需要的基础知识的主要内容,如果未能解决你的问题,请参考以下文章

Umbraco image中使用Crop URL

react-native-image-crop-picker 详解

Yii Crop Image 上传使用 Ajax 问题

[RN] React Native 使用开源库 react-native-image-crop-picker 实现图片选择图片剪裁

通过 react-image-crop 模块获取裁剪图像

图像大小警告以及 django-image-cropping 中的裁剪字段意味着啥