CropperModal.js 51 KB

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