tui-cropper.wxs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. var cropper = {
  2. cutX: 0, //画布x轴起点
  3. cutY: 0, //画布y轴起点0
  4. touchRelative: [{
  5. x: 0,
  6. y: 0
  7. }], //手指或鼠标和图片中心的相对位置
  8. hypotenuseLength: 0, //双指触摸时斜边长度
  9. flagEndTouch: false, //是否结束触摸
  10. canvasWidth: 0,
  11. canvasHeight: 0,
  12. imgWidth: 0, //图片宽度
  13. imgHeight: 0, //图片高度
  14. scale: 1, //图片缩放比
  15. angle: 0, //图片旋转角度
  16. imgTop: 0, //图片上边距
  17. imgLeft: 0, //图片左边距
  18. windowHeight: 0,
  19. windowWidth: 0,
  20. init: true
  21. }
  22. function bool(str) {
  23. return str === 'true' || str == true ? true : false
  24. }
  25. function touchstart(e, ins) {
  26. var touch = e.touches || e.changedTouches;
  27. cropper.flagEndTouch = false;
  28. if (touch.length == 1) {
  29. cropper.touchRelative[0] = {
  30. x: touch[0].pageX - cropper.imgLeft,
  31. y: touch[0].pageY - cropper.imgTop
  32. };
  33. } else {
  34. var width = Math.abs(touch[0].pageX - touch[1].pageX);
  35. var height = Math.abs(touch[0].pageY - touch[1].pageY);
  36. cropper.touchRelative = [{
  37. x: touch[0].pageX - cropper.imgLeft,
  38. y: touch[0].pageY - cropper.imgTop
  39. },
  40. {
  41. x: touch[1].pageX - cropper.imgLeft,
  42. y: touch[1].pageY - cropper.imgTop
  43. }
  44. ];
  45. cropper.hypotenuseLength = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));
  46. }
  47. }
  48. function moveDuring(ins) {
  49. if (!ins) return;
  50. ins.callMethod('moveDuring')
  51. }
  52. function moveStop(ins) {
  53. if (!ins) return;
  54. ins.callMethod('moveStop')
  55. };
  56. function setCutCenter(ins) {
  57. var cutY = (cropper.windowHeight - cropper.canvasHeight) * 0.5;
  58. var cutX = (cropper.windowWidth - cropper.canvasWidth) * 0.5;
  59. //顺序不能变
  60. cropper.imgTop = cropper.imgTop - cropper.cutY + cutY;
  61. cropper.cutY = cutY; //截取的框上边距
  62. cropper.imgLeft = cropper.imgLeft - cropper.cutX + cutX;
  63. cropper.cutX = cutX; //截取的框左边距
  64. cutDetectionPosition(ins)
  65. imgTransform(ins)
  66. updateData(ins)
  67. }
  68. function touchmove(e, ins) {
  69. var touch = e.touches || e.changedTouches;
  70. if (cropper.flagEndTouch) return;
  71. moveDuring(ins);
  72. if (e.touches.length == 1) {
  73. var left = touch[0].pageX - cropper.touchRelative[0].x,
  74. top = touch[0].pageY - cropper.touchRelative[0].y;
  75. cropper.imgLeft = left;
  76. cropper.imgTop = top;
  77. imgTransform(ins);
  78. imgMarginDetectionPosition(ins);
  79. } else {
  80. var res = e.instance.getDataset();
  81. var minScale = +res.minscale;
  82. var maxScale = +res.maxscale;
  83. var width = Math.abs(touch[0].pageX - touch[1].pageX),
  84. height = Math.abs(touch[0].pageY - touch[1].pageY),
  85. hypotenuse = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)),
  86. scale = cropper.scale * (hypotenuse / cropper.hypotenuseLength),
  87. current_deg = 0;
  88. scale = scale <= minScale ? minScale : scale;
  89. scale = scale >= maxScale ? maxScale : scale;
  90. cropper.scale = scale;
  91. imgMarginDetectionScale(ins, true);
  92. var touchRelative = [{
  93. x: touch[0].pageX - cropper.imgLeft,
  94. y: touch[0].pageY - cropper.imgTop
  95. },
  96. {
  97. x: touch[1].pageX - cropper.imgLeft,
  98. y: touch[1].pageY - cropper.imgTop
  99. }
  100. ];
  101. cropper.touchRelative = touchRelative;
  102. cropper.hypotenuseLength = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));
  103. //更新视图
  104. cropper.angle = cropper.angle + current_deg;
  105. imgTransform(ins);
  106. }
  107. }
  108. function touchend(e, ins) {
  109. cropper.flagEndTouch = true;
  110. moveStop(ins);
  111. updateData(ins)
  112. }
  113. //检测剪裁框位置是否在允许的范围内(屏幕内)
  114. function cutDetectionPosition(ins) {
  115. var windowHeight = cropper.windowHeight,
  116. windowWidth = cropper.windowWidth;
  117. var cutDetectionPositionTop = function() {
  118. //检测上边距是否在范围内
  119. if (cropper.cutY < 0) {
  120. cropper.cutY = 0;
  121. }
  122. if (cropper.cutY > windowHeight - cropper.canvasHeight) {
  123. cropper.cutY = windowHeight - cropper.canvasHeight;
  124. }
  125. }
  126. var cutDetectionPositionLeft = function() {
  127. //检测左边距是否在范围内
  128. if (cropper.cutX < 0) {
  129. cropper.cutX = 0;
  130. }
  131. if (cropper.cutX > windowWidth - cropper.canvasWidth) {
  132. cropper.cutX = windowWidth - cropper.canvasWidth;
  133. }
  134. }
  135. //裁剪框坐标处理(如果只写一个参数则另一个默认为0,都不写默认居中)
  136. if (cropper.cutY == null && cropper.cutX == null) {
  137. var cutY = (windowHeight - cropper.canvasHeight) * 0.5;
  138. var cutX = (windowWidth - cropper.canvasWidth) * 0.5;
  139. cropper.cutY = cutY; //截取的框上边距
  140. cropper.cutX = cutX; //截取的框左边距
  141. } else if (cropper.cutY != null && cropper.cutX != null) {
  142. cutDetectionPositionTop();
  143. cutDetectionPositionLeft();
  144. } else if (cropper.cutY != null && cropper.cutX == null) {
  145. cutDetectionPositionTop();
  146. cropper.cutX = (windowWidth - cropper.canvasWidth) / 2;
  147. } else if (cropper.cutY == null && cropper.cutX != null) {
  148. cutDetectionPositionLeft();
  149. cropper.cutY = (windowHeight - cropper.canvasHeight) / 2;
  150. }
  151. }
  152. /**
  153. * 图片边缘检测-缩放
  154. */
  155. function imgMarginDetectionScale(ins, delay) {
  156. var scale = cropper.scale;
  157. var imgWidth = cropper.imgWidth;
  158. var imgHeight = cropper.imgHeight;
  159. if ((cropper.angle / 90) % 2) {
  160. imgWidth = cropper.imgHeight;
  161. imgHeight = cropper.imgWidth;
  162. }
  163. if (imgWidth * scale < cropper.canvasWidth) {
  164. scale = cropper.canvasWidth / imgWidth;
  165. }
  166. if (imgHeight * scale < cropper.canvasHeight) {
  167. scale = Math.max(scale, cropper.canvasHeight / imgHeight);
  168. }
  169. imgMarginDetectionPosition(ins, scale, delay);
  170. }
  171. /**
  172. * 图片边缘检测-位置
  173. */
  174. function imgMarginDetectionPosition(ins, scale, delay) {
  175. var left = cropper.imgLeft;
  176. var top = cropper.imgTop;
  177. scale = scale || cropper.scale;
  178. var imgWidth = cropper.imgWidth;
  179. var imgHeight = cropper.imgHeight;
  180. if ((cropper.angle / 90) % 2) {
  181. imgWidth = cropper.imgHeight;
  182. imgHeight = cropper.imgWidth;
  183. }
  184. left = cropper.cutX + (imgWidth * scale) / 2 >= left ? left : cropper.cutX + (imgWidth * scale) / 2;
  185. left = cropper.cutX + cropper.canvasWidth - (imgWidth * scale) / 2 <= left ? left : cropper.cutX + cropper.canvasWidth -
  186. (imgWidth * scale) / 2;
  187. top = cropper.cutY + (imgHeight * scale) / 2 >= top ? top : cropper.cutY + (imgHeight * scale) / 2;
  188. top = cropper.cutY + cropper.canvasHeight - (imgHeight * scale) / 2 <= top ? top : cropper.cutY + cropper.canvasHeight -
  189. (imgHeight * scale) / 2;
  190. cropper.imgLeft = left;
  191. cropper.imgTop = top;
  192. cropper.scale = scale;
  193. if (!delay || delay === 'null') {
  194. imgTransform(ins);
  195. }
  196. }
  197. //改变截取框大小
  198. function computeCutSize(ins) {
  199. if (cropper.canvasWidth > cropper.windowWidth) {
  200. cropper.canvasWidth = cropper.windowWidth;
  201. } else if (cropper.canvasWidth + cropper.cutX > cropper.windowWidth) {
  202. cropper.cutX = cropper.windowWidth - cropper.cutX;
  203. }
  204. if (cropper.canvasHeight > cropper.windowHeight) {
  205. cropper.canvasHeight = cropper.windowHeight;
  206. } else if (cropper.canvasHeight + cropper.cutY > cropper.windowHeight) {
  207. cropper.cutY = cropper.windowHeight - cropper.cutY;
  208. }
  209. }
  210. function imgTransform(ins) {
  211. var owner = ins.selectComponent('.tui-cropper__image')
  212. if (!owner) return
  213. var x = cropper.imgLeft - cropper.imgWidth / 2;
  214. var y = cropper.imgTop - cropper.imgHeight / 2;
  215. owner.setStyle({
  216. 'transform': 'translate3d(' + x + 'px,' + y + 'px,0) scale(' + cropper.scale + ') rotate(' + cropper.angle + 'deg)'
  217. })
  218. }
  219. function imageReset(ins) {
  220. cropper.scale = 1;
  221. cropper.angle = 0;
  222. imgTransform(ins);
  223. }
  224. //监听截取框宽高变化
  225. function canvasWidth(ins) {
  226. if (!ins) return;
  227. computeCutSize(ins);
  228. }
  229. function canvasHeight(ins) {
  230. if (!ins) return;
  231. computeCutSize(ins);
  232. }
  233. function updateData(ins) {
  234. if (!ins) return;
  235. ins.callMethod('change', {
  236. cutX: cropper.cutX,
  237. cutY: cropper.cutY,
  238. imgWidth: cropper.imgWidth,
  239. imgHeight: cropper.imgHeight,
  240. scale: cropper.scale,
  241. angle: cropper.angle,
  242. imgTop: cropper.imgTop,
  243. imgLeft: cropper.imgLeft
  244. })
  245. }
  246. function propsChange(prop, oldProp, ownerInstance, ins) {
  247. if (prop && prop !== 'null') {
  248. var params = prop.split(',')
  249. var type = +params[0]
  250. var dataset = ins.getDataset();
  251. if (cropper.init || type == 4) {
  252. cropper.canvasWidth = +dataset.width;
  253. cropper.canvasHeight = +dataset.height;
  254. cropper.imgTop = dataset.windowheight / 2;
  255. cropper.imgLeft = dataset.windowwidth / 2;
  256. cropper.imgWidth = +dataset.imgwidth;
  257. cropper.imgHeight = +dataset.imgheight;
  258. cropper.windowHeight = +dataset.windowheight;
  259. cropper.windowWidth = +dataset.windowwidth;
  260. cropper.init = false
  261. } else if (type == 2 || type == 3) {
  262. cropper.imgWidth = +dataset.imgwidth;
  263. cropper.imgHeight = +dataset.imgheight;
  264. }
  265. cropper.angle = +dataset.angle;
  266. if (type == 3) {
  267. imgTransform(ownerInstance);
  268. }
  269. switch (type) {
  270. case 1:
  271. setCutCenter(ownerInstance);
  272. //设置裁剪框大小>设置图片尺寸>绘制canvas
  273. computeCutSize(ownerInstance);
  274. //检查裁剪框是否在范围内
  275. cutDetectionPosition(ownerInstance);
  276. break;
  277. case 2:
  278. setCutCenter(ownerInstance);
  279. break;
  280. case 3:
  281. imgMarginDetectionScale(ownerInstance)
  282. break;
  283. case 4:
  284. imageReset(ownerInstance);
  285. break;
  286. case 5:
  287. setCutCenter(ownerInstance);
  288. break;
  289. default:
  290. break;
  291. }
  292. }
  293. }
  294. module.exports = {
  295. touchstart: touchstart,
  296. touchmove: touchmove,
  297. touchend: touchend,
  298. propsChange: propsChange
  299. }