vue-cropper.es.js 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068
  1. import { defineComponent as M, openBlock as C, createElementBlock as x, withDirectives as O, createElementVNode as v, normalizeStyle as y, vShow as X, createCommentVNode as b, normalizeClass as S, toDisplayString as H } from "vue";
  2. const Y = {};
  3. Y.getData = (t) => new Promise((e, i) => {
  4. let s = {};
  5. I(t).then((r) => {
  6. s.arrayBuffer = r, s.orientation = k(r), e(s);
  7. }).catch((r) => {
  8. i(r);
  9. });
  10. });
  11. function I(t) {
  12. let e = null;
  13. return new Promise((i, s) => {
  14. if (t.src)
  15. if (/^data\:/i.test(t.src))
  16. e = L(t.src), i(e);
  17. else if (/^blob\:/i.test(t.src)) {
  18. var r = new FileReader();
  19. r.onload = function(h) {
  20. e = h.target.result, i(e);
  21. }, E(t.src, function(h) {
  22. r.readAsArrayBuffer(h);
  23. });
  24. } else {
  25. var o = new XMLHttpRequest();
  26. o.onload = function() {
  27. if (this.status == 200 || this.status === 0)
  28. e = o.response, i(e);
  29. else
  30. throw "Could not load image";
  31. o = null;
  32. }, o.open("GET", t.src, !0), o.responseType = "arraybuffer", o.send(null);
  33. }
  34. else
  35. s("img error");
  36. });
  37. }
  38. function E(t, e) {
  39. var i = new XMLHttpRequest();
  40. i.open("GET", t, !0), i.responseType = "blob", i.onload = function(s) {
  41. (this.status == 200 || this.status === 0) && e(this.response);
  42. }, i.send();
  43. }
  44. function L(t) {
  45. t = t.replace(/^data\:([^\;]+)\;base64,/gmi, "");
  46. for (var e = atob(t), i = e.length, s = new ArrayBuffer(i), r = new Uint8Array(s), o = 0; o < i; o++)
  47. r[o] = e.charCodeAt(o);
  48. return s;
  49. }
  50. function T(t, e, i) {
  51. var s = "", r;
  52. for (r = e, i += e; r < i; r++)
  53. s += String.fromCharCode(t.getUint8(r));
  54. return s;
  55. }
  56. function k(t) {
  57. var e = new DataView(t), i = e.byteLength, s, r, o, h, n, l, c, a, p, u;
  58. if (e.getUint8(0) === 255 && e.getUint8(1) === 216)
  59. for (p = 2; p < i; ) {
  60. if (e.getUint8(p) === 255 && e.getUint8(p + 1) === 225) {
  61. c = p;
  62. break;
  63. }
  64. p++;
  65. }
  66. if (c && (r = c + 4, o = c + 10, T(e, r, 4) === "Exif" && (l = e.getUint16(o), n = l === 18761, (n || l === 19789) && e.getUint16(o + 2, n) === 42 && (h = e.getUint32(o + 4, n), h >= 8 && (a = o + h)))), a) {
  67. for (i = e.getUint16(a, n), u = 0; u < i; u++)
  68. if (p = a + u * 12 + 2, e.getUint16(p, n) === 274) {
  69. p += 8, s = e.getUint16(p, n);
  70. break;
  71. }
  72. }
  73. return s;
  74. }
  75. const N = (t, e) => {
  76. const i = t.__vccOpts || t;
  77. for (const [s, r] of e)
  78. i[s] = r;
  79. return i;
  80. }, A = M({
  81. data: function() {
  82. return {
  83. // 容器高宽
  84. w: 0,
  85. h: 0,
  86. // 图片缩放比例
  87. scale: 1,
  88. // 图片偏移x轴
  89. x: 0,
  90. // 图片偏移y轴
  91. y: 0,
  92. // 图片加载
  93. loading: !0,
  94. // 图片真实宽度
  95. trueWidth: 0,
  96. // 图片真实高度
  97. trueHeight: 0,
  98. move: !0,
  99. // 移动的x
  100. moveX: 0,
  101. // 移动的y
  102. moveY: 0,
  103. // 开启截图
  104. crop: !1,
  105. // 正在截图
  106. cropping: !1,
  107. // 裁剪框大小
  108. cropW: 0,
  109. cropH: 0,
  110. cropOldW: 0,
  111. cropOldH: 0,
  112. // 判断是否能够改变
  113. canChangeX: !1,
  114. canChangeY: !1,
  115. // 改变的基准点
  116. changeCropTypeX: 1,
  117. changeCropTypeY: 1,
  118. // 裁剪框的坐标轴
  119. cropX: 0,
  120. cropY: 0,
  121. cropChangeX: 0,
  122. cropChangeY: 0,
  123. cropOffsertX: 0,
  124. cropOffsertY: 0,
  125. // 支持的滚动事件
  126. support: "",
  127. // 移动端手指缩放
  128. touches: [],
  129. touchNow: !1,
  130. // 图片旋转
  131. rotate: 0,
  132. isIos: !1,
  133. orientation: 0,
  134. imgs: "",
  135. // 图片缩放系数
  136. coe: 0.2,
  137. // 是否正在多次缩放
  138. scaling: !1,
  139. scalingSet: "",
  140. coeStatus: "",
  141. // 控制emit触发频率
  142. isCanShow: !0
  143. };
  144. },
  145. props: {
  146. img: {
  147. type: [String, Blob, null, File],
  148. default: ""
  149. },
  150. // 输出图片压缩比
  151. outputSize: {
  152. type: Number,
  153. default: 1
  154. },
  155. outputType: {
  156. type: String,
  157. default: "jpeg"
  158. },
  159. info: {
  160. type: Boolean,
  161. default: !0
  162. },
  163. // 是否开启滚轮放大缩小
  164. canScale: {
  165. type: Boolean,
  166. default: !0
  167. },
  168. // 是否自成截图框
  169. autoCrop: {
  170. type: Boolean,
  171. default: !1
  172. },
  173. autoCropWidth: {
  174. type: [Number, String],
  175. default: 0
  176. },
  177. autoCropHeight: {
  178. type: [Number, String],
  179. default: 0
  180. },
  181. // 是否开启固定宽高比
  182. fixed: {
  183. type: Boolean,
  184. default: !1
  185. },
  186. // 宽高比 w/h
  187. fixedNumber: {
  188. type: Array,
  189. default: () => [1, 1]
  190. },
  191. // 固定大小 禁止改变截图框大小
  192. fixedBox: {
  193. type: Boolean,
  194. default: !1
  195. },
  196. // 输出截图是否缩放
  197. full: {
  198. type: Boolean,
  199. default: !1
  200. },
  201. // 是否可以拖动图片
  202. canMove: {
  203. type: Boolean,
  204. default: !0
  205. },
  206. // 是否可以拖动截图框
  207. canMoveBox: {
  208. type: Boolean,
  209. default: !0
  210. },
  211. // 上传图片按照原始比例显示
  212. original: {
  213. type: Boolean,
  214. default: !1
  215. },
  216. // 截图框能否超过图片
  217. centerBox: {
  218. type: Boolean,
  219. default: !1
  220. },
  221. // 是否根据dpr输出高清图片
  222. high: {
  223. type: Boolean,
  224. default: !0
  225. },
  226. // 截图框展示宽高类型
  227. infoTrue: {
  228. type: Boolean,
  229. default: !1
  230. },
  231. // 可以压缩图片宽高 默认不超过200
  232. maxImgSize: {
  233. type: [Number, String],
  234. default: 2e3
  235. },
  236. // 倍数 可渲染当前截图框的n倍 0 - 1000;
  237. enlarge: {
  238. type: [Number, String],
  239. default: 1
  240. },
  241. // 自动预览的固定宽度
  242. preW: {
  243. type: [Number, String],
  244. default: 0
  245. },
  246. /*
  247. 图片布局方式 mode 实现和css背景一样的效果
  248. contain 居中布局 默认不会缩放 保证图片在容器里面 mode: 'contain'
  249. cover 拉伸布局 填充整个容器 mode: 'cover'
  250. 如果仅有一个数值被给定,这个数值将作为宽度值大小,高度值将被设定为auto。 mode: '50px'
  251. 如果有两个数值被给定,第一个将作为宽度值大小,第二个作为高度值大小。 mode: '50px 60px'
  252. */
  253. mode: {
  254. type: String,
  255. default: "contain"
  256. },
  257. //限制最小区域,可传1以上的数字和字符串,限制长宽都是这么大
  258. // 也可以传数组[90,90]
  259. limitMinSize: {
  260. type: [Number, Array, String],
  261. default: () => 10,
  262. validator: function(t) {
  263. return Array.isArray(t) ? Number(t[0]) >= 0 && Number(t[1]) >= 0 : Number(t) >= 0;
  264. }
  265. }
  266. },
  267. computed: {
  268. cropInfo() {
  269. let t = {};
  270. if (t.top = this.cropOffsertY > 21 ? "-21px" : "0px", t.width = this.cropW > 0 ? this.cropW : 0, t.height = this.cropH > 0 ? this.cropH : 0, this.infoTrue) {
  271. let e = 1;
  272. this.high && !this.full && (e = window.devicePixelRatio), this.enlarge !== 1 & !this.full && (e = Math.abs(Number(this.enlarge))), t.width = t.width * e, t.height = t.height * e, this.full && (t.width = t.width / this.scale, t.height = t.height / this.scale);
  273. }
  274. return t.width = t.width.toFixed(0), t.height = t.height.toFixed(0), t;
  275. },
  276. isIE() {
  277. return !!window.ActiveXObject || "ActiveXObject" in window;
  278. },
  279. passive() {
  280. return this.isIE ? null : {
  281. passive: !1
  282. };
  283. }
  284. },
  285. watch: {
  286. // 如果图片改变, 重新布局
  287. img() {
  288. this.checkedImg();
  289. },
  290. imgs(t) {
  291. t !== "" && this.reload();
  292. },
  293. cropW() {
  294. this.showPreview();
  295. },
  296. cropH() {
  297. this.showPreview();
  298. },
  299. cropOffsertX() {
  300. this.showPreview();
  301. },
  302. cropOffsertY() {
  303. this.showPreview();
  304. },
  305. scale(t, e) {
  306. this.showPreview();
  307. },
  308. x() {
  309. this.showPreview();
  310. },
  311. y() {
  312. this.showPreview();
  313. },
  314. autoCrop(t) {
  315. t && this.goAutoCrop();
  316. },
  317. // 修改了自动截图框
  318. autoCropWidth() {
  319. this.autoCrop && this.goAutoCrop();
  320. },
  321. autoCropHeight() {
  322. this.autoCrop && this.goAutoCrop();
  323. },
  324. mode() {
  325. this.checkedImg();
  326. },
  327. rotate() {
  328. this.showPreview(), this.autoCrop ? this.goAutoCrop(this.cropW, this.cropH) : (this.cropW > 0 || this.cropH > 0) && this.goAutoCrop(this.cropW, this.cropH);
  329. }
  330. },
  331. methods: {
  332. getVersion(t) {
  333. var e = navigator.userAgent.split(" "), i = "";
  334. let s = 0;
  335. const r = new RegExp(t, "i");
  336. for (var o = 0; o < e.length; o++)
  337. r.test(e[o]) && (i = e[o]);
  338. return i ? s = i.split("/")[1].split(".") : s = ["0", "0", "0"], s;
  339. },
  340. checkOrientationImage(t, e, i, s) {
  341. if (this.getVersion("chrome")[0] >= 81)
  342. e = -1;
  343. else if (this.getVersion("safari")[0] >= 605) {
  344. const h = this.getVersion("version");
  345. h[0] > 13 && h[1] > 1 && (e = -1);
  346. } else {
  347. const h = navigator.userAgent.toLowerCase().match(/cpu iphone os (.*?) like mac os/);
  348. if (h) {
  349. let n = h[1];
  350. n = n.split("_"), (n[0] > 13 || n[0] >= 13 && n[1] >= 4) && (e = -1);
  351. }
  352. }
  353. let r = document.createElement("canvas"), o = r.getContext("2d");
  354. switch (o.save(), e) {
  355. case 2:
  356. r.width = i, r.height = s, o.translate(i, 0), o.scale(-1, 1);
  357. break;
  358. case 3:
  359. r.width = i, r.height = s, o.translate(i / 2, s / 2), o.rotate(180 * Math.PI / 180), o.translate(-i / 2, -s / 2);
  360. break;
  361. case 4:
  362. r.width = i, r.height = s, o.translate(0, s), o.scale(1, -1);
  363. break;
  364. case 5:
  365. r.height = i, r.width = s, o.rotate(0.5 * Math.PI), o.scale(1, -1);
  366. break;
  367. case 6:
  368. r.width = s, r.height = i, o.translate(s / 2, i / 2), o.rotate(90 * Math.PI / 180), o.translate(-i / 2, -s / 2);
  369. break;
  370. case 7:
  371. r.height = i, r.width = s, o.rotate(0.5 * Math.PI), o.translate(i, -s), o.scale(-1, 1);
  372. break;
  373. case 8:
  374. r.height = i, r.width = s, o.translate(s / 2, i / 2), o.rotate(-90 * Math.PI / 180), o.translate(-i / 2, -s / 2);
  375. break;
  376. default:
  377. r.width = i, r.height = s;
  378. }
  379. o.drawImage(t, 0, 0, i, s), o.restore(), r.toBlob(
  380. (h) => {
  381. let n = URL.createObjectURL(h);
  382. URL.revokeObjectURL(this.imgs), this.imgs = n;
  383. },
  384. "image/" + this.outputType,
  385. 1
  386. );
  387. },
  388. // checkout img
  389. checkedImg() {
  390. if (this.img === null || this.img === "") {
  391. this.imgs = "", this.clearCrop();
  392. return;
  393. }
  394. this.loading = !0, this.scale = 1, this.rotate = 0, this.clearCrop();
  395. let t = new Image();
  396. if (t.onload = () => {
  397. if (this.img === "")
  398. return this.$emit("img-load", "error"), !1;
  399. let i = t.width, s = t.height;
  400. Y.getData(t).then((r) => {
  401. this.orientation = r.orientation || 1;
  402. let o = Number(this.maxImgSize);
  403. if (!this.orientation && i < o & s < o) {
  404. this.imgs = this.img;
  405. return;
  406. }
  407. i > o && (s = s / i * o, i = o), s > o && (i = i / s * o, s = o), this.checkOrientationImage(t, this.orientation, i, s);
  408. });
  409. }, t.onerror = () => {
  410. this.$emit("img-load", "error");
  411. }, this.img.substr(0, 4) !== "data" && (t.crossOrigin = ""), this.isIE) {
  412. var e = new XMLHttpRequest();
  413. e.onload = function() {
  414. var i = URL.createObjectURL(this.response);
  415. t.src = i;
  416. }, e.open("GET", this.img, !0), e.responseType = "blob", e.send();
  417. } else
  418. t.src = this.img;
  419. },
  420. // 当按下鼠标键
  421. startMove(t) {
  422. if (t.preventDefault(), this.move && !this.crop) {
  423. if (!this.canMove)
  424. return !1;
  425. this.moveX = ("clientX" in t ? t.clientX : t.touches[0].clientX) - this.x, this.moveY = ("clientY" in t ? t.clientY : t.touches[0].clientY) - this.y, t.touches ? (window.addEventListener("touchmove", this.moveImg), window.addEventListener("touchend", this.leaveImg), t.touches.length == 2 && (this.touches = t.touches, window.addEventListener("touchmove", this.touchScale), window.addEventListener("touchend", this.cancelTouchScale))) : (window.addEventListener("mousemove", this.moveImg), window.addEventListener("mouseup", this.leaveImg)), this.$emit("img-moving", {
  426. moving: !0,
  427. axis: this.getImgAxis()
  428. });
  429. } else
  430. this.cropping = !0, window.addEventListener("mousemove", this.createCrop), window.addEventListener("mouseup", this.endCrop), window.addEventListener("touchmove", this.createCrop), window.addEventListener("touchend", this.endCrop), this.cropOffsertX = t.offsetX ? t.offsetX : t.touches[0].pageX - this.$refs.cropper.offsetLeft, this.cropOffsertY = t.offsetY ? t.offsetY : t.touches[0].pageY - this.$refs.cropper.offsetTop, this.cropX = "clientX" in t ? t.clientX : t.touches[0].clientX, this.cropY = "clientY" in t ? t.clientY : t.touches[0].clientY, this.cropChangeX = this.cropOffsertX, this.cropChangeY = this.cropOffsertY, this.cropW = 0, this.cropH = 0;
  431. },
  432. // 移动端缩放
  433. touchScale(t) {
  434. t.preventDefault();
  435. let e = this.scale;
  436. var i = {
  437. x: this.touches[0].clientX,
  438. y: this.touches[0].clientY
  439. }, s = {
  440. x: t.touches[0].clientX,
  441. y: t.touches[0].clientY
  442. }, r = {
  443. x: this.touches[1].clientX,
  444. y: this.touches[1].clientY
  445. }, o = {
  446. x: t.touches[1].clientX,
  447. y: t.touches[1].clientY
  448. }, h = Math.sqrt(
  449. Math.pow(i.x - r.x, 2) + Math.pow(i.y - r.y, 2)
  450. ), n = Math.sqrt(
  451. Math.pow(s.x - o.x, 2) + Math.pow(s.y - o.y, 2)
  452. ), l = n - h, c = 1;
  453. c = c / this.trueWidth > c / this.trueHeight ? c / this.trueHeight : c / this.trueWidth, c = c > 0.1 ? 0.1 : c;
  454. var a = c * l;
  455. if (!this.touchNow) {
  456. if (this.touchNow = !0, l > 0 ? e += Math.abs(a) : l < 0 && e > Math.abs(a) && (e -= Math.abs(a)), this.touches = t.touches, setTimeout(() => {
  457. this.touchNow = !1;
  458. }, 8), !this.checkoutImgAxis(this.x, this.y, e))
  459. return !1;
  460. this.scale = e;
  461. }
  462. },
  463. cancelTouchScale(t) {
  464. window.removeEventListener("touchmove", this.touchScale);
  465. },
  466. // 移动图片
  467. moveImg(t) {
  468. if (t.preventDefault(), t.touches && t.touches.length === 2)
  469. return this.touches = t.touches, window.addEventListener("touchmove", this.touchScale), window.addEventListener("touchend", this.cancelTouchScale), window.removeEventListener("touchmove", this.moveImg), !1;
  470. let e = "clientX" in t ? t.clientX : t.touches[0].clientX, i = "clientY" in t ? t.clientY : t.touches[0].clientY, s, r;
  471. s = e - this.moveX, r = i - this.moveY, this.$nextTick(() => {
  472. if (this.centerBox) {
  473. let o = this.getImgAxis(s, r, this.scale), h = this.getCropAxis(), n = this.trueHeight * this.scale, l = this.trueWidth * this.scale, c, a, p, u;
  474. switch (this.rotate) {
  475. case 1:
  476. case -1:
  477. case 3:
  478. case -3:
  479. c = this.cropOffsertX - this.trueWidth * (1 - this.scale) / 2 + (n - l) / 2, a = this.cropOffsertY - this.trueHeight * (1 - this.scale) / 2 + (l - n) / 2, p = c - n + this.cropW, u = a - l + this.cropH;
  480. break;
  481. default:
  482. c = this.cropOffsertX - this.trueWidth * (1 - this.scale) / 2, a = this.cropOffsertY - this.trueHeight * (1 - this.scale) / 2, p = c - l + this.cropW, u = a - n + this.cropH;
  483. break;
  484. }
  485. o.x1 >= h.x1 && (s = c), o.y1 >= h.y1 && (r = a), o.x2 <= h.x2 && (s = p), o.y2 <= h.y2 && (r = u);
  486. }
  487. this.x = s, this.y = r, this.$emit("img-moving", {
  488. moving: !0,
  489. axis: this.getImgAxis()
  490. });
  491. });
  492. },
  493. // 移动图片结束
  494. leaveImg(t) {
  495. window.removeEventListener("mousemove", this.moveImg), window.removeEventListener("touchmove", this.moveImg), window.removeEventListener("mouseup", this.leaveImg), window.removeEventListener("touchend", this.leaveImg), this.$emit("img-moving", {
  496. moving: !1,
  497. axis: this.getImgAxis()
  498. });
  499. },
  500. // 缩放图片
  501. scaleImg() {
  502. this.canScale && window.addEventListener(this.support, this.changeSize, this.passive);
  503. },
  504. // 移出框
  505. cancelScale() {
  506. this.canScale && window.removeEventListener(this.support, this.changeSize);
  507. },
  508. // 改变大小函数
  509. changeSize(t) {
  510. t.preventDefault();
  511. let e = this.scale;
  512. var i = t.deltaY || t.wheelDelta, s = navigator.userAgent.indexOf("Firefox");
  513. i = s > 0 ? i * 30 : i, this.isIE && (i = -i);
  514. var r = this.coe;
  515. r = r / this.trueWidth > r / this.trueHeight ? r / this.trueHeight : r / this.trueWidth;
  516. var o = r * i;
  517. o < 0 ? e += Math.abs(o) : e > Math.abs(o) && (e -= Math.abs(o));
  518. let h = o < 0 ? "add" : "reduce";
  519. if (h !== this.coeStatus && (this.coeStatus = h, this.coe = 0.2), this.scaling || (this.scalingSet = setTimeout(() => {
  520. this.scaling = !1, this.coe = this.coe += 0.01;
  521. }, 50)), this.scaling = !0, !this.checkoutImgAxis(this.x, this.y, e))
  522. return !1;
  523. this.scale = e;
  524. },
  525. // 修改图片大小函数
  526. changeScale(t) {
  527. let e = this.scale;
  528. t = t || 1;
  529. var i = 20;
  530. if (i = i / this.trueWidth > i / this.trueHeight ? i / this.trueHeight : i / this.trueWidth, t = t * i, t > 0 ? e += Math.abs(t) : e > Math.abs(t) && (e -= Math.abs(t)), !this.checkoutImgAxis(this.x, this.y, e))
  531. return !1;
  532. this.scale = e;
  533. },
  534. // 创建截图框
  535. createCrop(t) {
  536. t.preventDefault();
  537. var e = "clientX" in t ? t.clientX : t.touches ? t.touches[0].clientX : 0, i = "clientY" in t ? t.clientY : t.touches ? t.touches[0].clientY : 0;
  538. this.$nextTick(() => {
  539. var s = e - this.cropX, r = i - this.cropY;
  540. if (s > 0 ? (this.cropW = s + this.cropChangeX > this.w ? this.w - this.cropChangeX : s, this.cropOffsertX = this.cropChangeX) : (this.cropW = this.w - this.cropChangeX + Math.abs(s) > this.w ? this.cropChangeX : Math.abs(s), this.cropOffsertX = this.cropChangeX + s > 0 ? this.cropChangeX + s : 0), !this.fixed)
  541. r > 0 ? (this.cropH = r + this.cropChangeY > this.h ? this.h - this.cropChangeY : r, this.cropOffsertY = this.cropChangeY) : (this.cropH = this.h - this.cropChangeY + Math.abs(r) > this.h ? this.cropChangeY : Math.abs(r), this.cropOffsertY = this.cropChangeY + r > 0 ? this.cropChangeY + r : 0);
  542. else {
  543. var o = this.cropW / this.fixedNumber[0] * this.fixedNumber[1];
  544. o + this.cropOffsertY > this.h ? (this.cropH = this.h - this.cropOffsertY, this.cropW = this.cropH / this.fixedNumber[1] * this.fixedNumber[0], s > 0 ? this.cropOffsertX = this.cropChangeX : this.cropOffsertX = this.cropChangeX - this.cropW) : this.cropH = o, this.cropOffsertY = this.cropOffsertY;
  545. }
  546. });
  547. },
  548. // 改变截图框大小
  549. changeCropSize(t, e, i, s, r) {
  550. t.preventDefault(), window.addEventListener("mousemove", this.changeCropNow), window.addEventListener("mouseup", this.changeCropEnd), window.addEventListener("touchmove", this.changeCropNow), window.addEventListener("touchend", this.changeCropEnd), this.canChangeX = e, this.canChangeY = i, this.changeCropTypeX = s, this.changeCropTypeY = r, this.cropX = "clientX" in t ? t.clientX : t.touches[0].clientX, this.cropY = "clientY" in t ? t.clientY : t.touches[0].clientY, this.cropOldW = this.cropW, this.cropOldH = this.cropH, this.cropChangeX = this.cropOffsertX, this.cropChangeY = this.cropOffsertY, this.fixed && this.canChangeX && this.canChangeY && (this.canChangeY = 0), this.$emit("change-crop-size", {
  551. width: this.cropW,
  552. height: this.cropH
  553. });
  554. },
  555. // 正在改变
  556. changeCropNow(t) {
  557. t.preventDefault();
  558. var e = "clientX" in t ? t.clientX : t.touches ? t.touches[0].clientX : 0, i = "clientY" in t ? t.clientY : t.touches ? t.touches[0].clientY : 0;
  559. let s = this.w, r = this.h, o = 0, h = 0;
  560. if (this.centerBox) {
  561. let c = this.getImgAxis(), a = c.x2, p = c.y2;
  562. o = c.x1 > 0 ? c.x1 : 0, h = c.y1 > 0 ? c.y1 : 0, s > a && (s = a), r > p && (r = p);
  563. }
  564. const [n, l] = this.checkCropLimitSize();
  565. this.$nextTick(() => {
  566. var c = e - this.cropX, a = i - this.cropY;
  567. if (this.canChangeX && (this.changeCropTypeX === 1 ? this.cropOldW - c < n ? (this.cropW = n, this.cropOffsertX = this.cropOldW + this.cropChangeX - o - n) : this.cropOldW - c > 0 ? (this.cropW = s - this.cropChangeX - c <= s - o ? this.cropOldW - c : this.cropOldW + this.cropChangeX - o, this.cropOffsertX = s - this.cropChangeX - c <= s - o ? this.cropChangeX + c : o) : (this.cropW = Math.abs(c) + this.cropChangeX <= s ? Math.abs(c) - this.cropOldW : s - this.cropOldW - this.cropChangeX, this.cropOffsertX = this.cropChangeX + this.cropOldW) : this.changeCropTypeX === 2 && (this.cropOldW + c < n ? this.cropW = n : this.cropOldW + c > 0 ? (this.cropW = this.cropOldW + c + this.cropOffsertX <= s ? this.cropOldW + c : s - this.cropOffsertX, this.cropOffsertX = this.cropChangeX) : (this.cropW = s - this.cropChangeX + Math.abs(c + this.cropOldW) <= s - o ? Math.abs(c + this.cropOldW) : this.cropChangeX - o, this.cropOffsertX = s - this.cropChangeX + Math.abs(c + this.cropOldW) <= s - o ? this.cropChangeX - Math.abs(c + this.cropOldW) : o))), this.canChangeY && (this.changeCropTypeY === 1 ? this.cropOldH - a < l ? (this.cropH = l, this.cropOffsertY = this.cropOldH + this.cropChangeY - h - l) : this.cropOldH - a > 0 ? (this.cropH = r - this.cropChangeY - a <= r - h ? this.cropOldH - a : this.cropOldH + this.cropChangeY - h, this.cropOffsertY = r - this.cropChangeY - a <= r - h ? this.cropChangeY + a : h) : (this.cropH = Math.abs(a) + this.cropChangeY <= r ? Math.abs(a) - this.cropOldH : r - this.cropOldH - this.cropChangeY, this.cropOffsertY = this.cropChangeY + this.cropOldH) : this.changeCropTypeY === 2 && (this.cropOldH + a < l ? this.cropH = l : this.cropOldH + a > 0 ? (this.cropH = this.cropOldH + a + this.cropOffsertY <= r ? this.cropOldH + a : r - this.cropOffsertY, this.cropOffsertY = this.cropChangeY) : (this.cropH = r - this.cropChangeY + Math.abs(a + this.cropOldH) <= r - h ? Math.abs(a + this.cropOldH) : this.cropChangeY - h, this.cropOffsertY = r - this.cropChangeY + Math.abs(a + this.cropOldH) <= r - h ? this.cropChangeY - Math.abs(a + this.cropOldH) : h))), this.canChangeX && this.fixed) {
  568. var p = this.cropW / this.fixedNumber[0] * this.fixedNumber[1];
  569. p < l ? (this.cropH = l, this.cropW = this.fixedNumber[0] * l / this.fixedNumber[1], this.changeCropTypeX === 1 && (this.cropOffsertX = this.cropChangeX + (this.cropOldW - this.cropW))) : p + this.cropOffsertY > r ? (this.cropH = r - this.cropOffsertY, this.cropW = this.cropH / this.fixedNumber[1] * this.fixedNumber[0], this.changeCropTypeX === 1 && (this.cropOffsertX = this.cropChangeX + (this.cropOldW - this.cropW))) : this.cropH = p;
  570. }
  571. if (this.canChangeY && this.fixed) {
  572. var u = this.cropH / this.fixedNumber[1] * this.fixedNumber[0];
  573. u < n ? (this.cropW = n, this.cropH = this.fixedNumber[1] * n / this.fixedNumber[0], this.cropOffsertY = this.cropOldH + this.cropChangeY - this.cropH) : u + this.cropOffsertX > s ? (this.cropW = s - this.cropOffsertX, this.cropH = this.cropW / this.fixedNumber[0] * this.fixedNumber[1]) : this.cropW = u;
  574. }
  575. });
  576. },
  577. checkCropLimitSize() {
  578. let { cropW: t, cropH: e, limitMinSize: i } = this, s = new Array();
  579. return Array.isArray(i) ? s = i : s = [i, i], t = parseFloat(s[0]), e = parseFloat(s[1]), [t, e];
  580. },
  581. // 结束改变
  582. changeCropEnd(t) {
  583. window.removeEventListener("mousemove", this.changeCropNow), window.removeEventListener("mouseup", this.changeCropEnd), window.removeEventListener("touchmove", this.changeCropNow), window.removeEventListener("touchend", this.changeCropEnd);
  584. },
  585. // 根据比例x/y,最小宽度,最小高度,现有宽度,现有高度,得到应该有的宽度和高度
  586. calculateSize(t, e, i, s, r, o) {
  587. const h = t / e;
  588. let n = r, l = o;
  589. return n < i && (n = i, l = Math.ceil(n / h)), l < s && (l = s, n = Math.ceil(l * h), n < i && (n = i, l = Math.ceil(n / h))), n < r && (n = r, l = Math.ceil(n / h)), l < o && (l = o, n = Math.ceil(l * h)), { width: n, height: l };
  590. },
  591. // 创建完成
  592. endCrop() {
  593. this.cropW === 0 && this.cropH === 0 && (this.cropping = !1);
  594. let [t, e] = this.checkCropLimitSize();
  595. const { width: i, height: s } = this.fixed ? this.calculateSize(
  596. this.fixedNumber[0],
  597. this.fixedNumber[1],
  598. t,
  599. e,
  600. this.cropW,
  601. this.cropH
  602. ) : { width: t, height: e };
  603. i > this.cropW && (this.cropW = i, this.cropOffsertX + i > this.w && (this.cropOffsertX = this.w - i)), s > this.cropH && (this.cropH = s, this.cropOffsertY + s > this.h && (this.cropOffsertY = this.h - s)), window.removeEventListener("mousemove", this.createCrop), window.removeEventListener("mouseup", this.endCrop), window.removeEventListener("touchmove", this.createCrop), window.removeEventListener("touchend", this.endCrop);
  604. },
  605. // 开始截图
  606. startCrop() {
  607. this.crop = !0;
  608. },
  609. // 停止截图
  610. stopCrop() {
  611. this.crop = !1;
  612. },
  613. // 清除截图
  614. clearCrop() {
  615. this.cropping = !1, this.cropW = 0, this.cropH = 0;
  616. },
  617. // 截图移动
  618. cropMove(t) {
  619. if (t.preventDefault(), !this.canMoveBox)
  620. return this.crop = !1, this.startMove(t), !1;
  621. if (t.touches && t.touches.length === 2)
  622. return this.crop = !1, this.startMove(t), this.leaveCrop(), !1;
  623. window.addEventListener("mousemove", this.moveCrop), window.addEventListener("mouseup", this.leaveCrop), window.addEventListener("touchmove", this.moveCrop), window.addEventListener("touchend", this.leaveCrop);
  624. let e = "clientX" in t ? t.clientX : t.touches[0].clientX, i = "clientY" in t ? t.clientY : t.touches[0].clientY, s, r;
  625. s = e - this.cropOffsertX, r = i - this.cropOffsertY, this.cropX = s, this.cropY = r, this.$emit("crop-moving", {
  626. moving: !0,
  627. axis: this.getCropAxis()
  628. });
  629. },
  630. moveCrop(t, e) {
  631. let i = 0, s = 0;
  632. t && (t.preventDefault(), i = "clientX" in t ? t.clientX : t.touches[0].clientX, s = "clientY" in t ? t.clientY : t.touches[0].clientY), this.$nextTick(() => {
  633. let r, o, h = i - this.cropX, n = s - this.cropY;
  634. if (e && (h = this.cropOffsertX, n = this.cropOffsertY), h <= 0 ? r = 0 : h + this.cropW > this.w ? r = this.w - this.cropW : r = h, n <= 0 ? o = 0 : n + this.cropH > this.h ? o = this.h - this.cropH : o = n, this.centerBox) {
  635. let l = this.getImgAxis();
  636. r <= l.x1 && (r = l.x1), r + this.cropW > l.x2 && (r = l.x2 - this.cropW), o <= l.y1 && (o = l.y1), o + this.cropH > l.y2 && (o = l.y2 - this.cropH);
  637. }
  638. this.cropOffsertX = r, this.cropOffsertY = o, this.$emit("crop-moving", {
  639. moving: !0,
  640. axis: this.getCropAxis()
  641. });
  642. });
  643. },
  644. // 算出不同场景下面 图片相对于外层容器的坐标轴
  645. getImgAxis(t, e, i) {
  646. t = t || this.x, e = e || this.y, i = i || this.scale;
  647. let s = {
  648. x1: 0,
  649. x2: 0,
  650. y1: 0,
  651. y2: 0
  652. }, r = this.trueWidth * i, o = this.trueHeight * i;
  653. switch (this.rotate) {
  654. case 0:
  655. s.x1 = t + this.trueWidth * (1 - i) / 2, s.x2 = s.x1 + this.trueWidth * i, s.y1 = e + this.trueHeight * (1 - i) / 2, s.y2 = s.y1 + this.trueHeight * i;
  656. break;
  657. case 1:
  658. case -1:
  659. case 3:
  660. case -3:
  661. s.x1 = t + this.trueWidth * (1 - i) / 2 + (r - o) / 2, s.x2 = s.x1 + this.trueHeight * i, s.y1 = e + this.trueHeight * (1 - i) / 2 + (o - r) / 2, s.y2 = s.y1 + this.trueWidth * i;
  662. break;
  663. default:
  664. s.x1 = t + this.trueWidth * (1 - i) / 2, s.x2 = s.x1 + this.trueWidth * i, s.y1 = e + this.trueHeight * (1 - i) / 2, s.y2 = s.y1 + this.trueHeight * i;
  665. break;
  666. }
  667. return s;
  668. },
  669. // 获取截图框的坐标轴
  670. getCropAxis() {
  671. let t = {
  672. x1: 0,
  673. x2: 0,
  674. y1: 0,
  675. y2: 0
  676. };
  677. return t.x1 = this.cropOffsertX, t.x2 = t.x1 + this.cropW, t.y1 = this.cropOffsertY, t.y2 = t.y1 + this.cropH, t;
  678. },
  679. leaveCrop(t) {
  680. window.removeEventListener("mousemove", this.moveCrop), window.removeEventListener("mouseup", this.leaveCrop), window.removeEventListener("touchmove", this.moveCrop), window.removeEventListener("touchend", this.leaveCrop), this.$emit("crop-moving", {
  681. moving: !1,
  682. axis: this.getCropAxis()
  683. });
  684. },
  685. getCropChecked(t) {
  686. let e = document.createElement("canvas"), i = new Image(), s = this.rotate, r = this.trueWidth, o = this.trueHeight, h = this.cropOffsertX, n = this.cropOffsertY;
  687. i.onload = () => {
  688. if (this.cropW !== 0) {
  689. let a = e.getContext("2d"), p = 1;
  690. this.high & !this.full && (p = window.devicePixelRatio), this.enlarge !== 1 & !this.full && (p = Math.abs(Number(this.enlarge)));
  691. let u = this.cropW * p, w = this.cropH * p, f = r * this.scale * p, d = o * this.scale * p, g = (this.x - h + this.trueWidth * (1 - this.scale) / 2) * p, m = (this.y - n + this.trueHeight * (1 - this.scale) / 2) * p;
  692. switch (c(u, w), a.save(), s) {
  693. case 0:
  694. this.full ? (c(u / this.scale, w / this.scale), a.drawImage(
  695. i,
  696. g / this.scale,
  697. m / this.scale,
  698. f / this.scale,
  699. d / this.scale
  700. )) : a.drawImage(i, g, m, f, d);
  701. break;
  702. case 1:
  703. case -3:
  704. this.full ? (c(u / this.scale, w / this.scale), g = g / this.scale + (f / this.scale - d / this.scale) / 2, m = m / this.scale + (d / this.scale - f / this.scale) / 2, a.rotate(s * 90 * Math.PI / 180), a.drawImage(
  705. i,
  706. m,
  707. -g - d / this.scale,
  708. f / this.scale,
  709. d / this.scale
  710. )) : (g = g + (f - d) / 2, m = m + (d - f) / 2, a.rotate(s * 90 * Math.PI / 180), a.drawImage(i, m, -g - d, f, d));
  711. break;
  712. case 2:
  713. case -2:
  714. this.full ? (c(u / this.scale, w / this.scale), a.rotate(s * 90 * Math.PI / 180), g = g / this.scale, m = m / this.scale, a.drawImage(
  715. i,
  716. -g - f / this.scale,
  717. -m - d / this.scale,
  718. f / this.scale,
  719. d / this.scale
  720. )) : (a.rotate(s * 90 * Math.PI / 180), a.drawImage(i, -g - f, -m - d, f, d));
  721. break;
  722. case 3:
  723. case -1:
  724. this.full ? (c(u / this.scale, w / this.scale), g = g / this.scale + (f / this.scale - d / this.scale) / 2, m = m / this.scale + (d / this.scale - f / this.scale) / 2, a.rotate(s * 90 * Math.PI / 180), a.drawImage(
  725. i,
  726. -m - f / this.scale,
  727. g,
  728. f / this.scale,
  729. d / this.scale
  730. )) : (g = g + (f - d) / 2, m = m + (d - f) / 2, a.rotate(s * 90 * Math.PI / 180), a.drawImage(i, -m - f, g, f, d));
  731. break;
  732. default:
  733. this.full ? (c(u / this.scale, w / this.scale), a.drawImage(
  734. i,
  735. g / this.scale,
  736. m / this.scale,
  737. f / this.scale,
  738. d / this.scale
  739. )) : a.drawImage(i, g, m, f, d);
  740. }
  741. a.restore();
  742. } else {
  743. let a = r * this.scale, p = o * this.scale, u = e.getContext("2d");
  744. switch (u.save(), s) {
  745. case 0:
  746. c(a, p), u.drawImage(i, 0, 0, a, p);
  747. break;
  748. case 1:
  749. case -3:
  750. c(p, a), u.rotate(s * 90 * Math.PI / 180), u.drawImage(i, 0, -p, a, p);
  751. break;
  752. case 2:
  753. case -2:
  754. c(a, p), u.rotate(s * 90 * Math.PI / 180), u.drawImage(i, -a, -p, a, p);
  755. break;
  756. case 3:
  757. case -1:
  758. c(p, a), u.rotate(s * 90 * Math.PI / 180), u.drawImage(i, -a, 0, a, p);
  759. break;
  760. default:
  761. c(a, p), u.drawImage(i, 0, 0, a, p);
  762. }
  763. u.restore();
  764. }
  765. t(e);
  766. };
  767. var l = this.img.substr(0, 4);
  768. l !== "data" && (i.crossOrigin = "Anonymous"), i.src = this.imgs;
  769. function c(a, p) {
  770. e.width = Math.round(a), e.height = Math.round(p);
  771. }
  772. },
  773. // 获取转换成base64 的图片信息
  774. getCropData(t) {
  775. this.getCropChecked((e) => {
  776. t(e.toDataURL("image/" + this.outputType, this.outputSize));
  777. });
  778. },
  779. //canvas获取为blob对象
  780. getCropBlob(t) {
  781. this.getCropChecked((e) => {
  782. e.toBlob(
  783. (i) => t(i),
  784. "image/" + this.outputType,
  785. this.outputSize
  786. );
  787. });
  788. },
  789. // 自动预览函数
  790. showPreview() {
  791. if (this.isCanShow)
  792. this.isCanShow = !1, setTimeout(() => {
  793. this.isCanShow = !0;
  794. }, 16);
  795. else
  796. return !1;
  797. let t = this.cropW, e = this.cropH, i = this.scale;
  798. var s = {};
  799. s.div = {
  800. width: `${t}px`,
  801. height: `${e}px`
  802. };
  803. let r = (this.x - this.cropOffsertX) / i, o = (this.y - this.cropOffsertY) / i, h = 0;
  804. s.w = t, s.h = e, s.url = this.imgs, s.img = {
  805. width: `${this.trueWidth}px`,
  806. height: `${this.trueHeight}px`,
  807. transform: `scale(${i})translate3d(${r}px, ${o}px, ${h}px)rotateZ(${this.rotate * 90}deg)`
  808. }, s.html = `
  809. <div class="show-preview" style="width: ${s.w}px; height: ${s.h}px,; overflow: hidden">
  810. <div style="width: ${t}px; height: ${e}px">
  811. <img src=${s.url} style="width: ${this.trueWidth}px; height: ${this.trueHeight}px; transform:
  812. scale(${i})translate3d(${r}px, ${o}px, ${h}px)rotateZ(${this.rotate * 90}deg)">
  813. </div>
  814. </div>`, this.$emit("real-time", s);
  815. },
  816. // reload 图片布局函数
  817. reload() {
  818. let t = new Image();
  819. t.onload = () => {
  820. this.w = parseFloat(window.getComputedStyle(this.$refs.cropper).width), this.h = parseFloat(window.getComputedStyle(this.$refs.cropper).height), this.trueWidth = t.width, this.trueHeight = t.height, this.original ? this.scale = 1 : this.scale = this.checkedMode(), this.$nextTick(() => {
  821. this.x = -(this.trueWidth - this.trueWidth * this.scale) / 2 + (this.w - this.trueWidth * this.scale) / 2, this.y = -(this.trueHeight - this.trueHeight * this.scale) / 2 + (this.h - this.trueHeight * this.scale) / 2, this.loading = !1, this.autoCrop && this.goAutoCrop(), this.$emit("img-load", "success"), setTimeout(() => {
  822. this.showPreview();
  823. }, 20);
  824. });
  825. }, t.onerror = () => {
  826. this.$emit("img-load", "error");
  827. }, t.src = this.imgs;
  828. },
  829. // 背景布局的函数
  830. checkedMode() {
  831. let t = 1, e = this.trueWidth, i = this.trueHeight;
  832. const s = this.mode.split(" ");
  833. switch (s[0]) {
  834. case "contain":
  835. this.trueWidth > this.w && (t = this.w / this.trueWidth), this.trueHeight * t > this.h && (t = this.h / this.trueHeight);
  836. break;
  837. case "cover":
  838. e = this.w, t = e / this.trueWidth, i = i * t, i < this.h && (i = this.h, t = i / this.trueHeight);
  839. break;
  840. default:
  841. try {
  842. let r = s[0];
  843. if (r.search("px") !== -1) {
  844. r = r.replace("px", ""), e = parseFloat(r);
  845. const o = e / this.trueWidth;
  846. let h = 1, n = s[1];
  847. n.search("px") !== -1 && (n = n.replace("px", ""), i = parseFloat(n), h = i / this.trueHeight), t = Math.min(o, h);
  848. }
  849. if (r.search("%") !== -1 && (r = r.replace("%", ""), e = parseFloat(r) / 100 * this.w, t = e / this.trueWidth), s.length === 2 && r === "auto") {
  850. let o = s[1];
  851. o.search("px") !== -1 && (o = o.replace("px", ""), i = parseFloat(o), t = i / this.trueHeight), o.search("%") !== -1 && (o = o.replace("%", ""), i = parseFloat(o) / 100 * this.h, t = i / this.trueHeight);
  852. }
  853. } catch {
  854. t = 1;
  855. }
  856. }
  857. return t;
  858. },
  859. // 自动截图函数
  860. goAutoCrop(t, e) {
  861. if (this.imgs === "" || this.imgs === null)
  862. return;
  863. this.clearCrop(), this.cropping = !0;
  864. let i = this.w, s = this.h;
  865. if (this.centerBox) {
  866. const h = Math.abs(this.rotate) % 2 > 0;
  867. let n = (h ? this.trueHeight : this.trueWidth) * this.scale, l = (h ? this.trueWidth : this.trueHeight) * this.scale;
  868. i = n < i ? n : i, s = l < s ? l : s;
  869. }
  870. var r = t || parseFloat(this.autoCropWidth), o = e || parseFloat(this.autoCropHeight);
  871. (r === 0 || o === 0) && (r = i * 0.8, o = s * 0.8), r = r > i ? i : r, o = o > s ? s : o, this.fixed && (o = r / this.fixedNumber[0] * this.fixedNumber[1]), o > this.h && (o = this.h, r = o / this.fixedNumber[1] * this.fixedNumber[0]), this.changeCrop(r, o);
  872. },
  873. // 手动改变截图框大小函数
  874. changeCrop(t, e) {
  875. if (this.centerBox) {
  876. let i = this.getImgAxis();
  877. t > i.x2 - i.x1 && (t = i.x2 - i.x1, e = t / this.fixedNumber[0] * this.fixedNumber[1]), e > i.y2 - i.y1 && (e = i.y2 - i.y1, t = e / this.fixedNumber[1] * this.fixedNumber[0]);
  878. }
  879. this.cropW = t, this.cropH = e, this.checkCropLimitSize(), this.$nextTick(() => {
  880. this.cropOffsertX = (this.w - this.cropW) / 2, this.cropOffsertY = (this.h - this.cropH) / 2, this.centerBox && this.moveCrop(null, !0);
  881. });
  882. },
  883. // 重置函数, 恢复组件置初始状态
  884. refresh() {
  885. this.img, this.imgs = "", this.scale = 1, this.crop = !1, this.rotate = 0, this.w = 0, this.h = 0, this.trueWidth = 0, this.trueHeight = 0, this.clearCrop(), this.$nextTick(() => {
  886. this.checkedImg();
  887. });
  888. },
  889. // 向左边旋转
  890. rotateLeft() {
  891. this.rotate = this.rotate <= -3 ? 0 : this.rotate - 1;
  892. },
  893. // 向右边旋转
  894. rotateRight() {
  895. this.rotate = this.rotate >= 3 ? 0 : this.rotate + 1;
  896. },
  897. // 清除旋转
  898. rotateClear() {
  899. this.rotate = 0;
  900. },
  901. // 图片坐标点校验
  902. checkoutImgAxis(t, e, i) {
  903. t = t || this.x, e = e || this.y, i = i || this.scale;
  904. let s = !0;
  905. if (this.centerBox) {
  906. let r = this.getImgAxis(t, e, i), o = this.getCropAxis();
  907. r.x1 >= o.x1 && (s = !1), r.x2 <= o.x2 && (s = !1), r.y1 >= o.y1 && (s = !1), r.y2 <= o.y2 && (s = !1);
  908. }
  909. return s;
  910. }
  911. },
  912. mounted() {
  913. this.support = "onwheel" in document.createElement("div") ? "wheel" : document.onmousewheel !== void 0 ? "mousewheel" : "DOMMouseScroll";
  914. let t = this;
  915. var e = navigator.userAgent;
  916. this.isIOS = !!e.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), HTMLCanvasElement.prototype.toBlob || Object.defineProperty(HTMLCanvasElement.prototype, "toBlob", {
  917. value: function(i, s, r) {
  918. for (var o = atob(this.toDataURL(s, r).split(",")[1]), h = o.length, n = new Uint8Array(h), l = 0; l < h; l++)
  919. n[l] = o.charCodeAt(l);
  920. i(new Blob([n], { type: t.type || "image/png" }));
  921. }
  922. }), this.showPreview(), this.checkedImg();
  923. },
  924. unmounted() {
  925. window.removeEventListener("mousemove", this.moveCrop), window.removeEventListener("mouseup", this.leaveCrop), window.removeEventListener("touchmove", this.moveCrop), window.removeEventListener("touchend", this.leaveCrop), this.cancelScale();
  926. }
  927. }), $ = {
  928. key: 0,
  929. class: "cropper-box"
  930. }, z = ["src"], B = { class: "cropper-view-box" }, P = ["src"], D = { key: 1 };
  931. function U(t, e, i, s, r, o) {
  932. return C(), x("div", {
  933. class: "vue-cropper",
  934. ref: "cropper",
  935. onMouseover: e[28] || (e[28] = (...h) => t.scaleImg && t.scaleImg(...h)),
  936. onMouseout: e[29] || (e[29] = (...h) => t.cancelScale && t.cancelScale(...h))
  937. }, [
  938. t.imgs ? (C(), x("div", $, [
  939. O(v("div", {
  940. class: "cropper-box-canvas",
  941. style: y({
  942. width: t.trueWidth + "px",
  943. height: t.trueHeight + "px",
  944. transform: "scale(" + t.scale + "," + t.scale + ") translate3d(" + t.x / t.scale + "px," + t.y / t.scale + "px,0)rotateZ(" + t.rotate * 90 + "deg)"
  945. })
  946. }, [
  947. v("img", {
  948. src: t.imgs,
  949. alt: "cropper-img",
  950. ref: "cropperImg"
  951. }, null, 8, z)
  952. ], 4), [
  953. [X, !t.loading]
  954. ])
  955. ])) : b("", !0),
  956. v("div", {
  957. class: S(["cropper-drag-box", { "cropper-move": t.move && !t.crop, "cropper-crop": t.crop, "cropper-modal": t.cropping }]),
  958. onMousedown: e[0] || (e[0] = (...h) => t.startMove && t.startMove(...h)),
  959. onTouchstart: e[1] || (e[1] = (...h) => t.startMove && t.startMove(...h))
  960. }, null, 34),
  961. O(v("div", {
  962. class: "cropper-crop-box",
  963. style: y({
  964. width: t.cropW + "px",
  965. height: t.cropH + "px",
  966. transform: "translate3d(" + t.cropOffsertX + "px," + t.cropOffsertY + "px,0)"
  967. })
  968. }, [
  969. v("span", B, [
  970. v("img", {
  971. style: y({
  972. width: t.trueWidth + "px",
  973. height: t.trueHeight + "px",
  974. transform: "scale(" + t.scale + "," + t.scale + ") translate3d(" + (t.x - t.cropOffsertX) / t.scale + "px," + (t.y - t.cropOffsertY) / t.scale + "px,0)rotateZ(" + t.rotate * 90 + "deg)"
  975. }),
  976. src: t.imgs,
  977. alt: "cropper-img"
  978. }, null, 12, P)
  979. ]),
  980. v("span", {
  981. class: "cropper-face cropper-move",
  982. onMousedown: e[2] || (e[2] = (...h) => t.cropMove && t.cropMove(...h)),
  983. onTouchstart: e[3] || (e[3] = (...h) => t.cropMove && t.cropMove(...h))
  984. }, null, 32),
  985. t.info ? (C(), x("span", {
  986. key: 0,
  987. class: "crop-info",
  988. style: y({ top: t.cropInfo.top })
  989. }, H(t.cropInfo.width) + " × " + H(t.cropInfo.height), 5)) : b("", !0),
  990. t.fixedBox ? b("", !0) : (C(), x("span", D, [
  991. v("span", {
  992. class: "crop-line line-w",
  993. onMousedown: e[4] || (e[4] = (h) => t.changeCropSize(h, !1, !0, 0, 1)),
  994. onTouchstart: e[5] || (e[5] = (h) => t.changeCropSize(h, !1, !0, 0, 1))
  995. }, null, 32),
  996. v("span", {
  997. class: "crop-line line-a",
  998. onMousedown: e[6] || (e[6] = (h) => t.changeCropSize(h, !0, !1, 1, 0)),
  999. onTouchstart: e[7] || (e[7] = (h) => t.changeCropSize(h, !0, !1, 1, 0))
  1000. }, null, 32),
  1001. v("span", {
  1002. class: "crop-line line-s",
  1003. onMousedown: e[8] || (e[8] = (h) => t.changeCropSize(h, !1, !0, 0, 2)),
  1004. onTouchstart: e[9] || (e[9] = (h) => t.changeCropSize(h, !1, !0, 0, 2))
  1005. }, null, 32),
  1006. v("span", {
  1007. class: "crop-line line-d",
  1008. onMousedown: e[10] || (e[10] = (h) => t.changeCropSize(h, !0, !1, 2, 0)),
  1009. onTouchstart: e[11] || (e[11] = (h) => t.changeCropSize(h, !0, !1, 2, 0))
  1010. }, null, 32),
  1011. v("span", {
  1012. class: "crop-point point1",
  1013. onMousedown: e[12] || (e[12] = (h) => t.changeCropSize(h, !0, !0, 1, 1)),
  1014. onTouchstart: e[13] || (e[13] = (h) => t.changeCropSize(h, !0, !0, 1, 1))
  1015. }, null, 32),
  1016. v("span", {
  1017. class: "crop-point point2",
  1018. onMousedown: e[14] || (e[14] = (h) => t.changeCropSize(h, !1, !0, 0, 1)),
  1019. onTouchstart: e[15] || (e[15] = (h) => t.changeCropSize(h, !1, !0, 0, 1))
  1020. }, null, 32),
  1021. v("span", {
  1022. class: "crop-point point3",
  1023. onMousedown: e[16] || (e[16] = (h) => t.changeCropSize(h, !0, !0, 2, 1)),
  1024. onTouchstart: e[17] || (e[17] = (h) => t.changeCropSize(h, !0, !0, 2, 1))
  1025. }, null, 32),
  1026. v("span", {
  1027. class: "crop-point point4",
  1028. onMousedown: e[18] || (e[18] = (h) => t.changeCropSize(h, !0, !1, 1, 0)),
  1029. onTouchstart: e[19] || (e[19] = (h) => t.changeCropSize(h, !0, !1, 1, 0))
  1030. }, null, 32),
  1031. v("span", {
  1032. class: "crop-point point5",
  1033. onMousedown: e[20] || (e[20] = (h) => t.changeCropSize(h, !0, !1, 2, 0)),
  1034. onTouchstart: e[21] || (e[21] = (h) => t.changeCropSize(h, !0, !1, 2, 0))
  1035. }, null, 32),
  1036. v("span", {
  1037. class: "crop-point point6",
  1038. onMousedown: e[22] || (e[22] = (h) => t.changeCropSize(h, !0, !0, 1, 2)),
  1039. onTouchstart: e[23] || (e[23] = (h) => t.changeCropSize(h, !0, !0, 1, 2))
  1040. }, null, 32),
  1041. v("span", {
  1042. class: "crop-point point7",
  1043. onMousedown: e[24] || (e[24] = (h) => t.changeCropSize(h, !1, !0, 0, 2)),
  1044. onTouchstart: e[25] || (e[25] = (h) => t.changeCropSize(h, !1, !0, 0, 2))
  1045. }, null, 32),
  1046. v("span", {
  1047. class: "crop-point point8",
  1048. onMousedown: e[26] || (e[26] = (h) => t.changeCropSize(h, !0, !0, 2, 2)),
  1049. onTouchstart: e[27] || (e[27] = (h) => t.changeCropSize(h, !0, !0, 2, 2))
  1050. }, null, 32)
  1051. ]))
  1052. ], 4), [
  1053. [X, t.cropping]
  1054. ])
  1055. ], 544);
  1056. }
  1057. const W = /* @__PURE__ */ N(A, [["render", U], ["__scopeId", "data-v-49e90ec5"]]), F = function(t) {
  1058. t.component("VueCropper", W);
  1059. }, j = {
  1060. version: "1.0.8",
  1061. install: F,
  1062. VueCropper: W
  1063. };
  1064. export {
  1065. W as VueCropper,
  1066. j as default,
  1067. j as globalCropper
  1068. };