首頁 web前端 js教程 Vue-cropper對圖片進行裁剪

Vue-cropper對圖片進行裁剪

Jun 08, 2018 am 11:04 AM
vue 圖片裁切

這次帶給大家Vue-cropper對圖片進行裁剪,Vue-cropper對圖片進行裁剪的注意事項有哪些,下面就是實戰案例,一起來看一下。

一:裁切的想法:

1-1,裁切區域:需要進行裁切首先需要形成裁切區域,裁切區域的大小和我們的滑鼠移動的距離相關聯,滑鼠移動有多遠,裁剪區域就有多大。如下圖:

1-2 裁剪區域的寬和高的計算:

如上圖,滑鼠的橫向移動距離和縱向移動距離就形成了裁剪區域的寬和高。那麼裁剪區域的寬和高的計算是:當我們點下滑鼠時,就能夠透過event事件

物件取得滑鼠點擊位置,e.clientX 和e.clientY; 當滑鼠進行移動的時候,也能透過event取得滑鼠的位置,透過兩次滑鼠位置的改變,就能夠得到

滑鼠移動的距離。即:初始的x軸位置為initX = e.clientX, initY = e.clientY;

移動到某點的位置為:endX = e.clientX, endY = e.clientY;

因此裁切區域的寬Tx = endX - initX;

裁切區域的高是Ty = endY - initY;

1-3 陰影區域的形成

被我們裁切圖片中除了裁切區域以外的部分,都屬於陰影部分。如下圖所示:

那麼陰影區域要如何計算呢?例如左陰影寬,左陰影寬= 裁剪區域的左偏移值- 圖片本身的左偏移值;那麼上陰影高= 裁剪區域的上偏移值- 圖片上偏移值, 如下圖所示:

那麼下陰影的高度= 圖片本身的高度- 上陰影的高度- 裁剪區域的高度;那麼右陰影的寬度= 圖片的寬度- 左陰影寬- 裁剪區域的寬。

1-4 理解裁切區域被越界

在裁切圖片過程中會出現越界的情況,那麼越界又需要分成2種情況, 第一種是:裁切過程中的越界,第二種是移動裁切區域的越界。

1-4-1 裁切越界

什麼是裁切時越界?就是當我們使用滑鼠拖曳區域裁剪超出了圖片的寬度和高度,形成了的越界;如下圖所示:

對於這種越界需要判斷被裁剪區域的右側相對於瀏覽器左側的位置,不能超過圖片右側的位置相對於瀏覽器左側的位置;

#且被裁切區域的底部相對於瀏覽器頂部的位置不能超過圖片的底部相對於瀏覽器頂部的位置,如下圖所示:

#1-4-2 移動越界

移動越界指已經形成了裁剪區域了,但是我們可以透過滑鼠裁剪區域時產生了越界。其實判斷原理和裁剪越界的原理一樣的。

2. 圖片如何進行壓縮?

當圖片的寬度大於容器的寬度,就需要進行壓縮;因此var scale = 容器的寬度/ 圖片的寬度;

如果圖片的高度* 縮放比例>容器的高度,那麼縮放比例scale = 容器的高度/ 圖片的高度;否則的話,不進行壓縮。

2-1:對於壓縮後translate3d中的X軸和Y軸移動位置計算方式:

x = 容器的寬度/ 壓縮比

y = 容器的高度/ 壓縮比

即:transform: translate3d(x, y, z) -> translate3d(容器的寬度/ 壓縮比'px', 容器的高度/ 壓縮比'px', 0)

因此頁面佈局變成如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

<!DOCTYPE html>

<html>

<head>

 <title>图片裁剪</title>

 <meta charset="utf-8">

 <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">

 <link rel="stylesheet" type="text/css" href="./index.css">

</head>

<body>

 <p id="app" style="height:500px;margin: 0 auto;">

 <p class="vue-cropper">

 <p class="cropper-box">

 <p class="cropper-box-canvas" style="width:644px;height:642px;transform: scale(0.778816, 0.778816) translate3d(453.252px, -87.312px, 0px) rotateZ(0deg)">

  <img src="https://images2018.cnblogs.com/blog/561794/201804/561794-20180416230443389-1451524334.jp" />

 </p>

 </p>

 <p class="cropper-drag-box cropper-crop"></p>

 </p>

 </p>

</body>

</html>

登入後複製

4. 在裁切的過程中,如何計算裁切的寬度和高度?

当我们点下鼠标时,就能够通过event事件对象获取鼠标点击位置,e.clientX 和 e.clientY; 当鼠标进行移动的时候,也能通过event获取鼠标的位置,

通过两次鼠标位置的改变,就能够获得鼠标移动的距离。即:

初始的x轴和Y轴位置分别为 cropX = e.clientX, cropY = e.clientY;

移动后现在的X轴和Y轴的位置分别为:nowX = e.clientX, nowY = e.clientY;

因此裁剪区域的临时值 var fw = ~~(nowX - cropX);

裁剪区域的临时值是 fh = ~~(nowY - cropY);

裁剪图片的时候,有可能往右拖动(值会越来越大),也有可能往相反的方向(向左)拖动(值会越来越小),同理,向上或向下拖动也是同一个道理。因此需要判断 fw 和 fh是否大于0的判断;在鼠标按键下去的时候,先获取鼠标相对于事件源元素的X和Y轴坐标,e.offsetX 和 e.offsetY;

因此 cropChangeX = e.offsetX; cropChangeY = e.offsetY;

对于offsetX 和 offsetY 的理解如下;

1

2

3

4

if (fw > 0) {

var cropW(裁剪区域的实际宽度) = cropChangeX + fw > w(图片的实际宽度) ? w - cropChangeX : fw;

cropOffsertX = cropChangeX;

}

登入後複製

cropOffsertX 就是保存事件源相对于元素的距离。

如果fw 小于0,说明是往左裁剪,那么裁剪的距离 fw = (事件结束的clientX - 事件的开始clientX);

如果 (图片的实际宽度 - e.offsetX) + Math.abs(fw) > 图片的实际宽度 ? this.cropChangeX : Math.abs(fw);

即:

1

2

3

4

if (fw < 0) {

var cropW(裁剪区域的实际宽度) = (w - cropChangeX) + Math.abs(fw) > w ? cropChangeX : Math.abs(fw);

cropOffsertX = cropChangeX + fw > 0 ? cropChangeX + fw : 0;

}

登入後複製

说明往左裁剪的最大宽度只能是 e.offsetX; 不能超过该值,否则的话,就会越界。

此时cropOffsertX偏移值改变了; cropOffsertX = cropChangeX + fw > 0 ? cropChangeX + fw : 0; 如图下所示:

上面分析的是 宽和高不固定比例的裁剪,下面我们来看下 宽和高固定比例的裁剪。

5. 宽和高固定比例裁剪计算;

比如宽和高比是 3:4 这样的截图;fixedNumber = [3, 4]

因此 固定比例高度的计算

fixedHeight 裁剪区域的实际宽度

------------- = ---------------

fixedNumber[1] fixedNumber[0]

因此:

1

var fixedHeight = ~~(裁剪区域的实际宽度 / fixedNumber[0] * fixedNumber[1]);

登入後複製

如果固定比例的移动的高度 + Y轴上相对于图片的偏移值 > 大于图片的高度的话,那么裁剪区域的高度(cropH) = 图片的高度(h) - Y轴上相对于图片的偏移值(cropOffsertY); 如下图所示:

获取到了 裁剪区域的高度的话,就可以获取到裁剪区域的宽度了;计算方式是:

1

cropW(裁剪区域的宽度) = ~~(cropH / fixedNumber[1] * fixedNumber[0]);

登入後複製

同时也要判断fw 是否大于0,来计算 cropOffsertX 的值;

1

2

3

4

5

if (fw > 0) {

var cropOffsertX = cropChangeX

else {

var cropOffsertX = cropChangeX - cropW

}

登入後複製

fw > 0 说明是往右移动,因此 cropOffsertX = cropChangeX;

fw < 0 说明是往左移动,cropOffsertX = 初始的 e.offsetX - 裁剪区域的宽度

即:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

if (fw > 0) {

var cropOffsertX = cropChangeX

else {

var cropOffsertX = cropChangeX - cropW

}

fw > 0 说明是往右移动,因此 cropOffsertX = cropChangeX;

fw < 0 说明是往左移动,cropOffsertX = 初始的 e.offsetX - 裁剪区域的宽度

即:

if (fixedHeight + cropOffsertY > h) { 

 cropH(裁剪区域的高度) = h - cropOffsertY;

 cropW(裁剪区域的宽度) = ~~(cropH / fixedNumber[1] * fixedNumber[0]);

 if (fw > 0) {

 var cropOffsertX = cropChangeX

 else {

 var cropOffsertX = cropChangeX - cropW

 }

else {

 // 否则 

 cropH = fixedHeight;

}</p>

<p style="text-align: left;"><strong>6. 理解裁剪区域拉伸原理</strong></p>

<p style="text-align: left;">控制裁剪区域拉伸的点,共有12种可以拉伸的点,分别有裁剪区域的四根线可以拉伸,有四根线上的八个点可以拉伸;如下图所示:</p>

<p style="text-align: left;"><img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/002/bb0d95fdc559be8871b0db805adc370b-9.jpg" class="lazy" alt=""></p>

<p style="text-align: left;">当鼠标点击拉伸的时候,会触发mousedown事件;因此需要区分下到底是那根线或那个点向什么方向拉伸。因此定义 canChangeX 和 canChangeY 两个变量,</p>

<p style="text-align: left;">判断是否能改变X轴和Y轴;默认是false;同时定义两个变量为 changeCropTypeX 和 changeCropTypeY,含义是能否改变x轴或Y轴的基准点。默认为1;可以改变。</p>

<p style="text-align: left;">1. 裁剪区域的最上面的线; 可以上下拉伸, 不能左右拉伸;</p>

<p style="text-align: left;">因此可以约定: canChangeX = false, canChangeY = true; changeCropTypeX = 0; changeCropTypeY = 1;</p>

<p style="text-align: left;">2. 裁剪区域左边的线;可以左右拉伸,不能上下拉伸;</p>

<p style="text-align: left;">因此可以约定:canChangeX = true, canChangeY = false; changeCropTypeX = 1; changeCropTypeY = 0;</p>

<p style="text-align: left;">3. 裁剪区域底部线; 可以上下拉伸,不能左右拉伸;</p>

<p style="text-align: left;">因此可以约定:canChangeX = false; canChangeY = true; changeCropTypeX = 0; changeCropTypeY = 2;(为了区分上面的线,因此等于2);</p>

<p style="text-align: left;">4. 裁剪区域右边线;可以左右拉伸,不能上下拉伸;</p>

<p style="text-align: left;">因此可以约定:canChangeX = true; canChangeY = false; changeCropTypeX = 2;(为了区分左边的线) changeCropTypeY = 0;</p>

<p style="text-align: left;">5. 左上角的点;可以向上或向左移动;</p>

<p style="text-align: left;">因此 canChangeX = true, canChangeY = true; changeCropTypeX = 1; changeCropTypeY = 1;</p>

<p style="text-align: left;">6. 上面中间的点,只能上下拉伸,不能左右拉伸;</p>

<p style="text-align: left;">因此 canChangeX = false, canChangeY = true; changeCropTypeX = 0; changeCropTypeY = 1;</p>

<p style="text-align: left;">7. 右上角的点,可以左右拉伸和上下拉伸;</p>

<p style="text-align: left;">因此 canChangeX = true, canChangeY = true; changeCropTypeX = 2; changeCropTypeY = 1;</p>

<p style="text-align: left;">8. 左中角的点,只能左右拉伸,不能上下拉伸;</p>

<p style="text-align: left;">因此 canChangeX = true, canChangeY = false; changeCropTypeX = 1; changeCropTypeY = 0;</p>

<p style="text-align: left;">9. 右中角的点,只能左右拉伸,不能上下拉伸;</p>

<p style="text-align: left;">因此 canChangeX = true, canChangeY = false; changeCropTypeX = 2; changeCropTypeY = 0;</p>

<p style="text-align: left;">10. 左下角的点,可以向上或向左移动;</p>

<p style="text-align: left;">因此 canChangeX = true, canChangeY = true; changeCropTypeX = 1; changeCropTypeY = 2;</p>

<p style="text-align: left;">11. 下线中间的店,可以上下拉伸,不能左右拉伸;</p>

<p style="text-align: left;">因此 canChangeX = false, canChangeY = true; changeCropTypeX = 0; changeCropTypeY = 2;</p>

<p style="text-align: left;">12. 下右角点,可以上下拉伸,左右拉伸;</p>

<p style="text-align: left;">因此 canChangeX = true, canChangeY = true; changeCropTypeX = 2; changeCropTypeY = 2;</p>

<p style="text-align: left;">下面来看看移动操作;</p>

<pre class="brush:php;toolbar:false">var fw = ~~(移动结束的clientX - 初始的clientX);

var fh = ~~(移动结束的clientY - 初始的clientY);

登入後複製

6-1 向左或向右拉伸的基本原理:

1

2

3

4

5

6

7

8

9

10

if (canChangeX) {

 // 如果x轴能改变的话,说明是 裁剪区域中左右两根线或是左右两个线上的点了。

 if (changeCropTypeX === 1) {

 // 如果x轴的基点能改变的话,并且等于1,说明是裁剪区域左边的线或左边线上的点了。

 // 那就有四种可能值,1. 左边的线,2. 左上角的点,3. 左中角的点。 4. 左下角的点。

 else if (changeCropTypeX === 2) {

 // 同理,说明是裁剪区域右边的线或右边线上的点了。

 // 那也有四种可能值,1. 右边的线,2. 右上角的点,3. 右中角的点。4. 右下角的点。

 }

}

登入後複製

changeCropTypeX === 1 的情况;继续如下判断:

假设裁剪区域的原始宽度为 cropOldW,裁剪区域的原始高度为 cropOldY, cropChangeX 保存原始的裁剪区域相对于图片的e.offsetX;

1

2

3

4

5

6

7

if (cropOldW - fw > 0) {

 如果裁剪区域的原始宽度 大于 移动的距离的话,那么说明两点,第一是向左拉伸的话,fw为负数,第二是向右拉伸,但是拉伸的距离小于裁剪区域的原始宽度

 裁剪区域后的宽度 = 图片的宽度 - 拉伸前的offsetX - 拉伸的距离 <= 图片的宽度的话 ? 拉伸前的offsetX(cropChangeX) - 拉伸的距离

 : 裁剪区原始宽度 + 拉伸前的offsetX.

 裁剪后的 cropOffsertX = 图片的宽度 - 拉伸前的offsetX(cropChangeX) - 拉伸的距离 <= 图片的宽度的话 ?

 裁剪区域前的offsertX(cropChangeX) + 拉伸的距离 : 0;

}

登入後複製

不管向左拉还是向右拉,裁剪区后的宽度 都等于 = 拉伸前的offsetX(cropChangeX) - 拉伸的距离;

裁剪后的 cropOffsertX = 裁剪区域前的offsertX(cropChangeX) + 拉伸的距离; 如下图所示:

1

2

3

4

5

if (cropOldW - fw <= 0) {

 裁剪拉伸后的宽度 = 拉伸后的距离fw + cropChangeX <= 图片的宽度 ? 拉伸后的距离fw - 拉伸前的裁剪区域的宽度 :

 图片的宽度 - 拉伸前的裁剪区域的宽度 - cropChangeX;

 裁剪拉伸后的 cropOffsertX = 拉伸前的裁剪区域的offsetX(cropChangeX) + 裁剪区域之前的宽度;

}

登入後複製

如下图所示:

changeCropTypeX === 2 的情况;

说明是裁剪区域右边的线或右边线上的点拉伸了。那也有四种可能值,1. 右边的线,2. 右上角的点,3. 右中角的点。4. 右下角的点。

同理;右边的线拉伸也有向左拉伸和向右拉伸,如果向左拉伸的话,那么fw肯定为负数,如果向右拉伸的话,那么fw就为正数。

1

2

3

4

if (cropOldW + fw > 0) {

// 如果原始的裁剪区域的宽度 + 拉伸的距离大于0,说明是向右拉伸或者向左拉伸,但是向左拉伸的距离小于原始裁剪区域

if (裁剪区域的原始宽度 + 移动距离fw + cropOffsertX <= 图片的宽度的话) {

}

登入後複製

这里的 裁剪区域的原始宽度 + 移动距离fw + cropOffsertX <= 图片的宽度的话 也有两种情况,第一种是向左拉伸,第二种是向右拉伸,但是没有拉伸到底,

也就是说拉伸的距离没有到图片的最右边;

现在的图片裁剪区域宽度(cropW) = 图片的原始区域的宽度 + fw(拉伸的距离,向左拉伸或向右拉伸);

否则的话,也就是说拉伸到最右边了,那么 图片裁剪区域宽度(cropW) = 图片的宽度 - 裁剪区域拉伸前的cropOffsertX;

1

2

因此此时 cropOffsertX = 拉伸前的裁剪区域的offsetX(cropChangeX);

}

登入後複製

如下图所示:

1

2

3

if (cropOldW + fw <=0) {

 // 如果原始裁剪区域的宽度 + 拉伸的距离小于或等于0的话,说明是向左拉伸,并且拉伸的距离正好大于或等于裁剪区域原始的宽度;

}

登入後複製

这边向左拉伸的距离又可以分为2种情况,第一种是 向左拉伸的距离 小于 (原始裁剪区域 + 拉伸前的offsetX); 第二种就是向左拉伸的时候越界了,

那么让拉伸后的宽度还控制在 offsetX的宽度即可,即不越界;因此如下逻辑判断:

现在图片裁剪区域的宽度(cropW) = (图片的宽度w - 拉伸前的offsetX + Math.abs(拉伸的总距离 + 裁剪前的原始距离)) <= 图片的宽度w ? Math.abs(拉伸的总距离 + 裁剪前的原始距离) : 拉伸前的offsetX; 此时的 cropOffsertX = (图片的宽度w - 拉伸前的offsetX + Math.abs(拉伸的总距离 + 裁剪前的原始距离)) <= 图片的宽度w ?拉伸前的offsetX - Math.abs(拉伸的总距离 + 裁剪前的原始距离) : 0; 如下图所示:

6-2 向上或向下拉伸的基本原理

1

2

3

4

5

6

7

8

9

10

if (canChangeY) {

 // 如果Y轴能改变的话,说明是 裁剪区域中上下两根线或是上下两个线上的点了。

 if (this.changeCropTypeY === 1) {

 // 如果Y轴的基点能改变的话,并且等于1,说明是裁剪区域上边的线或上边线上的点了。

 // 那就有四种可能值,1. 上边的线,2. 上左角的点,3. 上中角的点。 4. 上右角的点。

 } else if(this.changeCropTypeY === 2) {

 // 等于2,说明是裁剪区域下边的线或下边线上的点了。

 // 同理也就有四种可能值,1. 下边的线,2. 下左角的点,3. 下中角的点。 4. 下右角的点。

 }

}

登入後複製

changeCropTypeY === 1 的情况;

假设裁剪区域的原始宽度为 cropOldH,裁剪区域的原始高度为 cropOldY, cropChangeY 保存原始的裁剪区域相对于图片的e.offsetY,

向上或向下拉伸的距离为fh.

如果是向下拉伸的话,又分为2种情况,第一种是向下拉伸它的距离不超过原始裁剪区域的高度 cropOldH, 第二种是已经超过它的原始裁剪区域的高度了。

1

2

3

4

5

6

7

8

if (原始裁剪区域的高度cropOldH - 拉伸的距离fh > 0) {

// 说明是向上拉伸(fw肯定为负数)或向下拉伸(fw肯定为正数),但是向下拉伸的距离不超过原裁剪区域的高度

裁剪区域后的高度cropH 计算又分为2种情况,第一种是向上拉伸的距离fh小于或等于拉伸前的 e.offsetY, 第二种拉伸距离是大于e.offsetY,也就是向上

拉伸的时候越界了, 如果越界了,那么拉伸后的高度 = 裁剪之前的原始高度 + e.offsetY(裁剪区域之前的offsetY);因此:

裁剪区域后的高度cropH = 图片的高度 - e.offsetY(裁剪区域之前的offsetY) - fh <= 图片的高度 ? 图片的原始高度cropOldH - 拉伸的距离fh :

裁剪之前的原始高度 + e.offsetY(裁剪区域之前的offsetY);

拉伸区域之后的cropOffsertY = 图片的高度 - e.offsetY(裁剪区域之前的offsetY) - fh <= 图片的高度 ? e.offsetY(裁剪区域之前的offsetY) + fh : 0

}

登入後複製

如下图所示:

1

2

3

4

5

6

7

if (原始裁剪区域的高度cropOldH - 拉伸的距离fh <= 0) {

// 说明是向下拉伸,且拉伸的距离fh大于或等于原始裁剪区域的高度cropOldH

同时一样也要判断两种情况,第一种是向下拉伸后,没有超过图片的最低端,第二种是超过了图片的最低端,也就是越界的情况。

拉伸后裁剪区域的高度 = 拉伸后的总距离fh + 拉伸前的offsetY <= 图片的高度h ? 拉伸后的总距离fh - 裁剪区域原始的高度cropOldH : 图片的高度H -

拉伸前的offsetY - 裁剪区域原始的高度 cropOldH;

拉伸区域之后的cropOffsetY = 拉伸前的offsetY + 裁剪区域原始的高度cropOldH;

}

登入後複製

如下图所示:

changeCropTypeY === 2 的情况

等于2,说明是裁剪区域下边的线或下边线上的点了。

1

2

3

4

5

6

if (原裁剪区域的高度 + 被拉伸的距离fh > 0) {

// 说明了有可能是向下拉伸,或向上拉伸,但是向上拉伸的距离小于原裁剪区域的高度

裁剪区域后的高度 = 原裁剪区域的高度 + 被拉伸的距离fh + 原始裁剪区域的offsetY <= 图片的高度 ? 原裁剪区域的高度 + 被拉伸的距离fh : 图片的高度 -

原始裁剪的offsetY

裁剪后的cropOffsertY = 原始裁剪的offsetY;

}

登入後複製

如下图所示:

1

2

3

4

5

6

if (原裁剪区域的高度 + 被拉伸的距离fh <= 0) {

// 说明是向上拉伸,且向上拉伸的距离大于或等于原始裁剪区域的高度

裁剪区域后的高度 = 图片的高度 - 原裁剪区域的offsetY + Math.abs(fh + 原裁剪区域的高度) <= 图片的高度 ? 原裁剪区域的高度 + 被拉伸的总距离fh :

原裁剪区域的offsetY;

裁剪后的offsetY = 图片的高度 - 原裁剪区域的offsetY + Math.abs(fh + 原裁剪区域的高度) <= 图片的高度 ? 原裁剪区域的offsetY - Math.abs(被拉伸的总距 离fh + 原裁剪区域的高度) : 0;

}

登入後複製

如下图所示:

6-3: 向左或向右拉伸且是固定比例拉伸,假设固定比例 3:4, 即 fixedNumber = [3, 4];

向左或向右拉伸,高度会随着变化。如下图所示:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

if (canChangeX && fixed) {

比如宽和高比是 3:4 这样的比例;fixedNumber = [3, 4]

因此 固定比例高度的计算

裁剪区域的高度 fixedNumber[1]

------------- = ---------------

裁剪区域的宽度 fixedNumber[0]

因此:

var 裁剪区域的高度(fixedHeight) = ~~(裁剪区域的宽度 / fixedNumber[0] * fixedNumber[1]);

if (裁剪区域的高度 + 原裁剪区域的offsetY > 图片的高度) {

// 说明向左拉伸或向右拉伸,导致纵向区域越界了,

拉伸后的高度 = 图片的高度 - 原裁剪区域的offsetY;

拉伸后的宽度 3

---------- = ----

拉伸后的高度 4

拉伸后的宽度 = 拉伸后的高度 / fixedNumber[1] * fixedNumber[0];

else {

拉伸后的高度 = fixedHeight;

}

}

登入後複製

同样的道理,如果Y轴上的上下线拉伸的话,宽度会跟着变化,也是一样的计算方式:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

if (this.canChangeY && this.fixed) {

比如宽和高比是 3:4 这样的比例;fixedNumber = [3, 4];

因此 固定比例宽度的计算

裁剪区域的高度 fixedNumber[1]

------------- = ---------------

裁剪区域的宽度 fixedNumber[0]

裁剪区域的宽度(fixedWidth) = ~~(裁剪区域的高度 / fixedNumber[1] * fixedNumber[0]);

if (裁剪区域的宽度 + 原裁剪区域的offsetX > 图片的宽度) {

// 说明向上或向下拉伸,横向区域越界了

拉伸后的宽度 = 图片的宽度 - 原裁剪区的offsetX;

拉伸后的宽度 3

---------- = ----

拉伸后的高度 4

拉伸后的高度 = 拉伸后的宽度 / fixedNumber[0] * fixedNumber[1];

else {

拉伸后的宽度 = fixedWidth;

}

}

登入後複製

7. 截图移动操作

首先可以先获取原裁剪区域的offsetx,和 offsetY, 该offsetX和offsetY是相对于浏览器的,因此原坐标的x轴和Y轴的 e.clientx 和 e.clientY;

当鼠标移动裁剪区到一个新坐标的时候,会有一个新的 e.clientX 和 e.clientY; 把终点的x轴和Y轴离客户端的距离 - 起点的x轴和Y轴的距离,

就等于移动了多少的距离了,再加上原裁剪区相对于浏览器的 offsetX 或 offsetY后,就是最终相对于浏览器的坐标了;因此;

fw = 终点的x轴坐标(e.clientX) - 起点的x轴坐标(e.clientX) + 原裁剪区相对于浏览器的x轴坐标(offsetX);

fh = 终点的y轴坐标(e.clientY) - 起点的y轴坐标(e.clientY) + 原裁剪区相对于浏览器的y轴坐标(offsetY);

如下图所示:

1

2

3

4

5

6

if (移动后的距离fw小于或等于1的话) {

移动后的cropOffsertX = 1;

else if ((移动后的距离 + 裁剪区域的宽度) > 图片的宽度的话) {

// 说明移动的裁剪区域越界了,那么就让裁剪区处于中间的位置

移动后的cropOffsertX = 图片的宽度 - 裁剪区的宽度 - 1;

}

登入後複製

如下图所示:

1

2

3

4

5

6

7

8

9

10

11

else {

移动后的cropOffsertX = fw;

}

同理 if (移动后的距离fh小于或等于1的话) {

移动后的cropOffsertY = 1;

else if ((移动后的距离 + 裁剪区域的高度) > 图片的高度的话) {

// 说明移动的裁剪区域越界了,那么就让裁剪区处于中间的位置

移动后的cropOffsertY = 图片的高度 - 裁剪区的高度 - 1;

else {

移动后的cropOffsertY = fh;

}

登入後複製

8. 自动截图操作

代码的基本原理是:看组件是否传递了 autoCropWidth 和 autoCropHeight, 如果传递了该参数的宽度和高度的话,那么使用该参数的值,

如果没有传递的话,或者说该宽度和高度的值都为0的话,那么截取的宽度和高度就是图片的宽度和高度的80%;如果传递的宽度w和高度h大于图片的

本身的宽度或高度的话,那么宽度或高度的值就是图片的本身的宽度和高度的值。

如果传递了固定比例的话,那么高度的计算是根据宽度的比例来计算出来的。计算方式还是之前一样的:如下:

1

2

3

  w    fixedNumber[0]

 ------------- = ---------------

  h    fixedNumber[1]

登入後複製

因此 h = w / this.fixedNumber[0] * this.fixedNumber[1]

如果高度大于图片的高度的话,那么高度就是等于图片的高度,然后根据现在的高度重新计算宽度;

代码如下:

1

2

3

4

5

// 如果比例之后 高度大于h

if (h > this.h) {

h = this.h

w = h / this.fixedNumber[1] * this.fixedNumber[0]

}

登入後複製

自动截图的主要代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

var w = this.autoCropWidth

var h = this.autoCropHeight

if (w === 0 || h === 0) {

 w = this.w * 0.8

 h = this.h * 0.8

}

w = w > this.w ? this.w : w

h = h > this.h ? this.h : h

if (this.fixed) {

 h = w / this.fixedNumber[0] * this.fixedNumber[1]

}

// 如果比例之后 高度大于h

if (h > this.h) {

 h = this.h

 w = h / this.fixedNumber[1] * this.fixedNumber[0]

}

登入後複製

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

如何进行Angular容器部署

怎样操作日历范围选择插件

以上是Vue-cropper對圖片進行裁剪的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1671
14
CakePHP 教程
1428
52
Laravel 教程
1329
25
PHP教程
1276
29
C# 教程
1256
24
vue中怎麼用bootstrap vue中怎麼用bootstrap Apr 07, 2025 pm 11:33 PM

在 Vue.js 中使用 Bootstrap 分為五個步驟:安裝 Bootstrap。在 main.js 中導入 Bootstrap。直接在模板中使用 Bootstrap 組件。可選:自定義樣式。可選:使用插件。

vue怎麼給按鈕添加函數 vue怎麼給按鈕添加函數 Apr 08, 2025 am 08:51 AM

可以通過以下步驟為 Vue 按鈕添加函數:將 HTML 模板中的按鈕綁定到一個方法。在 Vue 實例中定義該方法並編寫函數邏輯。

vue中的watch怎麼用 vue中的watch怎麼用 Apr 07, 2025 pm 11:36 PM

Vue.js 中的 watch 選項允許開發者監聽特定數據的變化。當數據發生變化時,watch 會觸發一個回調函數,用於執行更新視圖或其他任務。其配置選項包括 immediate,用於指定是否立即執行回調,以及 deep,用於指定是否遞歸監聽對像或數組的更改。

vue返回上一頁的方法 vue返回上一頁的方法 Apr 07, 2025 pm 11:30 PM

Vue.js 返回上一頁有四種方法:$router.go(-1)$router.back()使用 &lt;router-link to=&quot;/&quot;&gt; 組件window.history.back(),方法選擇取決於場景。

React與Vue:Netflix使用哪個框架? React與Vue:Netflix使用哪個框架? Apr 14, 2025 am 12:19 AM

NetflixusesAcustomFrameworkcalled“ Gibbon” BuiltonReact,notReactorVuedIrectly.1)TeamSperience:selectBasedonFamiliarity.2)ProjectComplexity:vueforsimplerprojects:reactforforforproproject,reactforforforcompleplexones.3)cocatizationneedneeds:reactoffipicatizationneedneedneedneedneedneeds:reactoffersizationneedneedneedneedneeds:reactoffersizatization needefersmoreflexibleise.4)

vue多頁面開發是啥意思 vue多頁面開發是啥意思 Apr 07, 2025 pm 11:57 PM

Vue 多頁面開發是一種使用 Vue.js 框架構建應用程序的方法,其中應用程序被劃分為獨立的頁面:代碼維護性:將應用程序拆分為多個頁面可以使代碼更易於管理和維護。模塊化:每個頁面都可以作為獨立的模塊,便於重用和替換。路由簡單:頁面之間的導航可以通過簡單的路由配置來管理。 SEO 優化:每個頁面都有自己的 URL,這有助於搜索引擎優化。

vue遍歷怎麼用 vue遍歷怎麼用 Apr 07, 2025 pm 11:48 PM

Vue.js 遍歷數組和對像有三種常見方法:v-for 指令用於遍歷每個元素並渲染模板;v-bind 指令可與 v-for 一起使用,為每個元素動態設置屬性值;.map 方法可將數組元素轉換為新數組。

vue.js怎麼引用js文件 vue.js怎麼引用js文件 Apr 07, 2025 pm 11:27 PM

在 Vue.js 中引用 JS 文件的方法有三種:直接使用 &lt;script&gt; 標籤指定路徑;利用 mounted() 生命週期鉤子動態導入;通過 Vuex 狀態管理庫進行導入。

See all articles