index.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. // cropper/cropper.js
  2. Component({
  3. /**
  4. * 组件的属性列表
  5. */
  6. properties: {
  7. /**
  8. * @type number
  9. * @description 组件裁剪显示区域的最大比例,如果裁剪的图片过长,则做限制,默认最大宽高比例为 宽640 / 高960 (宽高比例)
  10. * @example 1 如果CROPPER_WIDTH宽度是720px,那么裁剪区域的高度也就是 CROPPER_WIDTH / cropperRatio 为 720px;
  11. */
  12. cropperRatio: {
  13. type: Number,
  14. value: 1
  15. },
  16. /**
  17. * @type number
  18. * @description 初始化的裁剪比例
  19. * @example 0 默认初始化的裁剪区域宽高为图片的宽高,且裁剪比例不固定
  20. * @example 0.5 宽高比例固定,且宽和高的比例为 1 : 2 的比例
  21. * @example 2 宽高比例固定,且宽和高的比例为 2 : 1 的比例
  22. */
  23. cutRatio: {
  24. type: Number,
  25. value: 1
  26. },
  27. /**
  28. * @type string
  29. * @description 需要裁剪的图片地址
  30. */
  31. imageSrc: {
  32. type: String,
  33. value: ''
  34. },
  35. /**
  36. * @type number
  37. * @description 裁剪区域的宽度
  38. */
  39. cropperWidth: {
  40. type: Number,
  41. value: 720
  42. },
  43. /**
  44. * @type number
  45. * @description 最小裁剪的范围
  46. */
  47. minCropperW: {
  48. type: Number,
  49. value: 100
  50. }
  51. },
  52. /**
  53. * 组件的初始数据
  54. */
  55. data: {
  56. /**
  57. * @type boolean
  58. * @description 图片在进行网络请求完成之后显示,showImg用于控制图片显示时机
  59. */
  60. showImg: false,
  61. /**
  62. * @
  63. */
  64. // 动态的宽高
  65. cropperW: null,
  66. cropperH: null,
  67. // 图片缩放值
  68. scaleP: 0,
  69. // 裁剪框 宽高
  70. cutL: 0,
  71. cutT: 0,
  72. cutB: 0,
  73. cutR: 0,
  74. qualityWidth: null,
  75. innerAspectRadio: null,
  76. filePath: null
  77. },
  78. /**
  79. * 组件的方法列表
  80. */
  81. methods: {
  82. close() {
  83. wx.hideLoading()
  84. this.triggerEvent('close')
  85. },
  86. /**
  87. * 初始化变量信息
  88. */
  89. initStaticData() {
  90. this.drag = {
  91. CUT_L: null, // 初始化拖拽元素的left值
  92. CUT_T: null, // ...top值
  93. CUT_R: null, // ...right值
  94. CUT_B: null, // ...bottom值
  95. CUT_W: null, // 初始化拖拽元素的宽度
  96. CUT_H: null, // 初始化拖拽元素的高度
  97. IS_TOUCH_CONTENT: false, // 是否是可拖动的状态(拖拽裁剪框)
  98. IS_TOUCH_SIDE: false, // 是否可以拖拽边框
  99. IS_NO_DRAG: false,
  100. // 拖拽区域的时候设置
  101. TOUCH_OFFSET_X: null, // 手按下相对于裁剪框左边的距离
  102. TOUCH_OFFSET_Y: null, // 手按下相对于裁剪框上边的距离
  103. TOUCH_MAX_MOVE_SECTION_X: null, // 移动区域的时候移动的x方向最大区间
  104. TOUCH_MAX_MOVE_SECTION_Y: null, // 移动区域的时候移动的y方向最大区间
  105. MOVE_PAGE_X: null, // 手移动的时候x的位置
  106. MOVE_PAGE_Y: null, // 手移动的时候Y的位置
  107. SPACE_TOP_POSITION: null,
  108. SPACE_LEFT_POSITION: null,
  109. SPACE_RIGHT_POSITION: null,
  110. SPACE_BOTTOM_POSITION: null
  111. }
  112. this.conf = {
  113. // 图片比例
  114. IMG_RATIO: null,
  115. // 图片实际宽高
  116. IMG_REAL_W: null, // 图片实际的宽度
  117. IMG_REAL_H: null, // 图片实际的高度
  118. // 裁剪除黑色区域以内的高度
  119. CROPPER_HEIGHT: null, // 图片背景区域宽度
  120. CROPPER_WIDTH: null, // 图标背景区域高度
  121. // 设置最小裁剪宽度高度
  122. CUT_MIN_W: null, // 最小限制多宽
  123. CUT_MIN_H: null, // 最小限制多高
  124. // 裁剪图片区域的信息
  125. // CROPPER_IMG_W: null, // 也就是 data.cropperW
  126. // CROPPER_IMG_H: null, // 也就是 data.cropperH
  127. // 移动的比例
  128. DRAG_MOVE_RATIO: 750 / wx.getSystemInfoSync().windowWidth, //移动时候的比例,
  129. INIT_DRAG_POSITION: 0, // 初始化屏幕宽度和裁剪区域的宽度之差,用于设置初始化裁剪的宽度
  130. DRAW_IMAGE_W: null, // 设置生成的图片宽度
  131. // 最大可显示得图片宽度,需要设定最大值,否则安卓部分机器会闪退, 控制qualityWidth的最大值
  132. MAX_QW: 2550,
  133. /**
  134. * 最小裁剪宽度 由于设置了裁剪的UI样式,裁剪的宽高必须要有最小宽度,这个宽度是裁剪长或者宽的最短一方的宽度
  135. * 如 400 200
  136. * 那么如果只能设置为100的时候
  137. * 那么最小缩放到200 100的效果,之后只能放大不能缩小
  138. */
  139. MIN_CROPPER_DIS: 100
  140. }
  141. },
  142. /**
  143. * 选择本地图片
  144. * 基于底部中间的按钮的点击事件
  145. */
  146. getImage() {
  147. const _this = this
  148. wx.chooseMedia({
  149. count: 1,
  150. mediaType: ['image'],
  151. sourceType: ['album'],
  152. success(res) {
  153. _this.setData({
  154. isShowImg: false,
  155. filePath: res.tempFiles[0].tempFilePath,
  156. })
  157. _this.loadImage(_this.data.filePath)
  158. },
  159. })
  160. },
  161. /**
  162. * 初始化加载图片
  163. */
  164. loadImage(src) {
  165. const _this = this
  166. wx.showLoading({
  167. title: '图片加载中...',
  168. })
  169. wx.getImageInfo({
  170. src: src ? src : this.properties.imageSrc,
  171. success: function (res) {
  172. /**
  173. * 获取图片真实宽高
  174. * 设置DRAW_IMAGE_W
  175. */
  176. _this.conf.DRAW_IMAGE_W = _this.conf.IMG_REAL_W = res.width
  177. _this.conf.IMG_REAL_H = res.height
  178. _this.conf.IMG_RATIO = Number((_this.conf.IMG_REAL_W / _this.conf.IMG_REAL_H).toFixed(5))
  179. _this.conf.CROPPER_HEIGHT = Math.ceil(_this.properties.cropperWidth / _this.conf.IMG_RATIO)
  180. const scaleP = Number((_this.conf.IMG_REAL_W / _this.properties.cropperWidth).toFixed(5))
  181. const qualityWidth = _this.conf.DRAW_IMAGE_W > _this.conf.MAX_QW ? _this.conf.MAX_QW : _this.conf.DRAW_IMAGE_W
  182. // const MIN_RANG
  183. const p = _this.initPosition()
  184. // 根据图片的宽高显示不同的效果 保证图片可以正常显示 (横屏)
  185. console.log(_this.conf.IMG_RATIO)
  186. console.log(_this.conf)
  187. console.log(_this.drag)
  188. console.log(_this.data)
  189. console.log(p)
  190. if (_this.conf.IMG_RATIO >= 1) {
  191. _this.conf.CROPPER_WIDTH = _this.properties.cropperWidth
  192. _this.setData({
  193. cropperW: _this.properties.cropperWidth,
  194. cropperH: _this.conf.CROPPER_HEIGHT,
  195. // 初始化left right
  196. cutL: p.left,
  197. cutT: p.top,
  198. cutR: p.right,
  199. cutB: p.bottom,
  200. // 图片缩放值
  201. scaleP,
  202. qualityWidth,
  203. innerAspectRadio: _this.conf.IMG_RATIO,
  204. filePath: res.path
  205. })
  206. } else {
  207. // 竖屏初始化
  208. _this.setData({
  209. cropperW: _this.conf.CROPPER_WIDTH,
  210. cropperH: _this.conf.CROPPER_HEIGHT,
  211. // 初始化left right
  212. cutL: p.left,
  213. cutT: p.top,
  214. cutR: p.right,
  215. cutB: p.bottom,
  216. // 图片缩放值
  217. scaleP,
  218. qualityWidth,
  219. innerAspectRadio: _this.conf.IMG_RATIO,
  220. filePath: res.path
  221. })
  222. }
  223. // 设置裁剪最小限制
  224. _this.setMinCutInfo()
  225. _this.setData({
  226. showImg: true
  227. })
  228. wx.hideLoading()
  229. }
  230. })
  231. },
  232. /**
  233. * 点击完成裁剪图片并返回图片信息
  234. * width 宽度
  235. * height 高度
  236. * url 图片的临时存储地址
  237. */
  238. getImageInfo() {
  239. const _this = this
  240. wx.showLoading({
  241. title: '图片生成中...',
  242. })
  243. this.drag.IS_NO_DRAG = true
  244. // 将图片写入画布
  245. const ctx = wx.createCanvasContext('wxCropperCanvas', _this)
  246. const w = this.data.qualityWidth
  247. const h = Math.ceil(this.data.qualityWidth / this.data.innerAspectRadio)
  248. ctx.drawImage(_this.data.filePath, 0, 0, w, h)
  249. ctx.draw(true, () => {
  250. // 获取画布要裁剪的位置和宽度 均为百分比 * 画布中图片的宽度 保证了在微信小程序中裁剪的图片模糊 位置不对的问题
  251. const canvasW = Math.ceil(((_this.data.cropperW - _this.data.cutL - _this.data.cutR) / _this.data.cropperW) * w)
  252. const canvasH = Math.ceil(((_this.data.cropperH - _this.data.cutT - _this.data.cutB) / _this.data.cropperH) * h)
  253. const canvasL = Math.ceil((_this.data.cutL / _this.data.cropperW) * w)
  254. const canvasT = Math.ceil((_this.data.cutT / _this.data.cropperH) * h)
  255. // console.log(canvasW, canvasH, canvasL, canvasT)
  256. // 生成图片
  257. wx.canvasToTempFilePath({
  258. x: canvasL,
  259. y: canvasT,
  260. width: canvasW,
  261. height: canvasH,
  262. destWidth: canvasW,
  263. destHeight: canvasH,
  264. quality: 0.9,
  265. canvasId: 'wxCropperCanvas',
  266. success: function (res) {
  267. // console.log(res.tempFilePath)
  268. const img = {
  269. path: res.tempFilePath,
  270. width: canvasW,
  271. height: canvasH
  272. }
  273. _this.triggerEvent('close', img)
  274. },
  275. complete: function () {
  276. // 结束之后可拖拽放大缩小
  277. // 关闭loading
  278. wx.hideLoading()
  279. _this.drag.IS_NO_DRAG = false
  280. }
  281. }, _this)
  282. })
  283. },
  284. /**
  285. * 设置最小裁剪宽度高度限制
  286. */
  287. setMinCutInfo() {
  288. this.conf.CUT_MIN_W = this.properties.minCropperW
  289. if (this.properties.cutRatio) {
  290. this.conf.CUT_MIN_H = this.conf.CUT_MIN_W / this.properties.cutRatio
  291. // console.log('this.conf.CUT_MIN_H', this.conf.CUT_MIN_H)
  292. return
  293. }
  294. this.conf.CUT_MIN_H = this.conf.CUT_MIN_W
  295. // console.log('this.conf.CUT_MIN_H', this.conf.CUT_MIN_H)
  296. },
  297. /**
  298. * 初始化裁剪位置
  299. * 需要 cutRatio 来判断
  300. * @return 返回裁剪的left, right, top bottom的值
  301. */
  302. initPosition() {
  303. // 定义返回的对象
  304. const left = 0,
  305. right = 0,
  306. top = 0,
  307. bottom = 0
  308. // cutRatio为0 且为横行 则为不等比裁剪
  309. if (this.properties.cutRatio === 0 && this.conf.IMG_RATIO >= 1) {
  310. return { left, right, top, bottom }
  311. }
  312. // 如果图片宽度大于等于高度(横向)
  313. if (this.conf.IMG_RATIO >= 1) {
  314. // 获取基本宽度
  315. // 图片显示区域比裁剪比例大的时候
  316. if (this.conf.IMG_RATIO >= this.properties.cutRatio) {
  317. // left的值
  318. let leftRight = Math.ceil((this.properties.cropperWidth - (this.conf.CROPPER_HEIGHT * this.properties.cutRatio)) / 2)
  319. return {
  320. left: leftRight,
  321. right: leftRight,
  322. top: 0,
  323. bottom: 0
  324. }
  325. }
  326. // 否则
  327. const bottomTop = Math.ceil((this.conf.CROPPER_HEIGHT - (this.properties.cropperWidth / this.properties.cutRatio)) / 2)
  328. return {
  329. left: 0,
  330. right: 0,
  331. top: bottomTop,
  332. bottom: bottomTop
  333. }
  334. }
  335. // 如果图片宽度小于高度 (竖向)
  336. // const r = _this.properties.cropperRatio > _this.conf.IMG_RATIO ? _this.properties.cropperRatio : _this.conf.IMG_RATIO
  337. if (this.properties.cropperRatio > this.conf.IMG_RATIO) {
  338. this.conf.CROPPER_WIDTH = this.properties.cropperWidth / this.properties.cropperRatio * this.conf.IMG_RATIO
  339. this.conf.CROPPER_HEIGHT = this.properties.cropperWidth / this.properties.cropperRatio
  340. } else {
  341. this.conf.CROPPER_WIDTH = this.properties.cropperWidth
  342. this.conf.CROPPER_HEIGHT = this.properties.cropperWidth / this.conf.IMG_RATIO
  343. }
  344. // 定义四个位置 如果不比例裁剪
  345. if (this.properties.cutRatio === 0) return { left, right, top, bottom }
  346. // 否则
  347. if (this.conf.IMG_RATIO >= this.properties.cutRatio) {
  348. const leftRight = Math.ceil((this.conf.CROPPER_WIDTH - (this.conf.CROPPER_HEIGHT * this.properties.cutRatio)) / 2)
  349. return {
  350. left: leftRight,
  351. right: leftRight,
  352. top: 0,
  353. bottom: 0
  354. }
  355. }
  356. const bottomTop = Math.ceil((this.conf.CROPPER_HEIGHT - (this.conf.CROPPER_WIDTH / this.properties.cutRatio)) / 2)
  357. return {
  358. left: 0,
  359. right: 0,
  360. top: bottomTop,
  361. bottom: bottomTop
  362. }
  363. },
  364. /**
  365. * 裁剪框的拖动事件
  366. */
  367. contentDragStart(e) {
  368. if (this.drag.IS_NO_DRAG) return
  369. this.drag.IS_TOUCH_CONTENT = true
  370. this.drag.TOUCH_OFFSET_X = (e.touches[0].pageX * this.conf.DRAG_MOVE_RATIO - this.data.cutL)
  371. this.drag.TOUCH_OFFSET_Y = (e.touches[0].pageY * this.conf.DRAG_MOVE_RATIO - this.data.cutT)
  372. /**
  373. * 获取可移动的最大值 xy方向
  374. */
  375. const cc = this.cropperCurrentInfo()
  376. this.drag.TOUCH_MAX_MOVE_SECTION_X = cc.x
  377. this.drag.TOUCH_MAX_MOVE_SECTION_Y = cc.y
  378. },
  379. /**
  380. * 获取裁剪区域信息
  381. */
  382. cropperCurrentInfo() {
  383. const x = this.data.cutL + this.data.cutR
  384. const y = this.data.cutT + this.data.cutB
  385. // 获取拖拽元素的宽高
  386. this.drag.CUT_W = this.data.cropperW - x
  387. this.drag.CUT_H = this.data.cropperH - y
  388. // 返回x, y
  389. return {
  390. x,
  391. y
  392. }
  393. },
  394. /**
  395. * 裁剪框拖动
  396. */
  397. contentDragMove(e) {
  398. if (this.drag.IS_NO_DRAG) return
  399. if (!this.drag.IS_TOUCH_CONTENT) return
  400. const MOVE_X = e.touches[0].pageX * this.conf.DRAG_MOVE_RATIO - this.drag.TOUCH_OFFSET_X
  401. const MOVE_Y = e.touches[0].pageY * this.conf.DRAG_MOVE_RATIO - this.drag.TOUCH_OFFSET_Y
  402. const drag_x = Math.min(this.drag.TOUCH_MAX_MOVE_SECTION_X, Math.max(0, MOVE_X))
  403. const drag_y = Math.min(this.drag.TOUCH_MAX_MOVE_SECTION_Y, Math.max(0, MOVE_Y))
  404. this.setData({
  405. cutL: Math.ceil(drag_x),
  406. cutR: Math.ceil(this.data.cropperW - this.drag.CUT_W - drag_x),
  407. cutT: Math.ceil(drag_y),
  408. cutB: Math.ceil((this.data.cropperH - this.drag.CUT_H - drag_y))
  409. })
  410. // 需要初始化
  411. this.drag.TOUCH_OFFSET_X = (e.touches[0].pageX * this.conf.DRAG_MOVE_RATIO - this.data.cutL)
  412. this.drag.TOUCH_OFFSET_Y = (e.touches[0].pageY * this.conf.DRAG_MOVE_RATIO - this.data.cutT)
  413. },
  414. /**
  415. * 裁剪框拖动结束
  416. */
  417. contentTouchEnd() {
  418. this.drag.IS_TOUCH_CONTENT = false
  419. },
  420. /**
  421. * 裁剪框4个方向的拖拽
  422. */
  423. sideDragStart(e) {
  424. if (this.drag.IS_NO_DRAG) return
  425. this.drag.IS_TOUCH_SIDE = true
  426. this.drag.MOVE_PAGE_X = e.touches[0].pageX
  427. this.drag.MOVE_PAGE_Y = e.touches[0].pageY
  428. // 初始化设置
  429. this.conf.CUT_T = this.data.cutT
  430. this.conf.CUT_L = this.data.cutL
  431. this.conf.CUT_R = this.data.cutR
  432. this.conf.CUT_B = this.data.cutB
  433. // 初始化最大移动区域
  434. this.drag.SPACE_TOP_POSITION = this.conf.CROPPER_HEIGHT - this.conf.CUT_B - this.conf.CUT_MIN_H
  435. this.drag.SPACE_BOTTOM_POSITION = this.conf.CROPPER_HEIGHT - this.conf.CUT_T - this.conf.CUT_MIN_H
  436. this.drag.SPACE_RIGHT_POSITION = this.conf.CROPPER_WIDTH - this.conf.CUT_L - this.conf.CUT_MIN_W
  437. this.drag.SPACE_LEFT_POSITION = this.conf.CROPPER_WIDTH - this.conf.CUT_R - this.conf.CUT_MIN_W
  438. },
  439. /**
  440. * 拖拽中
  441. */
  442. sideDragMove(e) {
  443. if (this.drag.IS_NO_DRAG) return
  444. if (!this.drag.IS_TOUCH_SIDE) return
  445. const type = e.target.dataset.drag
  446. if (this.properties.cutRatio === 0) {
  447. this.sideDragMoveDefault(e, type)
  448. } else {
  449. this.sideDragMoveConst(e, type)
  450. }
  451. },
  452. /**
  453. * 拖拽结束
  454. */
  455. sideDragEnd() {
  456. this.drag.IS_TOUCH_SIDE = false
  457. // console.log('sideDragEnd')
  458. },
  459. /**
  460. * 开始拖拽
  461. * 等比例的拖拽方式
  462. */
  463. sideDragMoveConst(e, type) {
  464. const xLength = (e.touches[0].pageX - this.drag.MOVE_PAGE_X) * this.conf.DRAG_MOVE_RATIO
  465. const yLength = (e.touches[0].pageY - this.drag.MOVE_PAGE_Y) * this.conf.DRAG_MOVE_RATIO
  466. switch (type) {
  467. case 'top':
  468. let top = this.conf.CUT_T + yLength
  469. top = Math.ceil(top >= this.drag.SPACE_TOP_POSITION ? this.drag.SPACE_TOP_POSITION : top)
  470. let topL = this.conf.CUT_L + yLength * this.properties.cutRatio
  471. topL = Math.ceil(topL >= this.drag.SPACE_LEFT_POSITION ? this.drag.SPACE_LEFT_POSITION : topL)
  472. if (topL < 0) {
  473. if (this.data.cutT <= 0) return
  474. if (this.data.cutL >= 0) return
  475. this.setData({
  476. cutL: 0
  477. })
  478. return
  479. }
  480. if (top <= 0) {
  481. this.setData({
  482. cutT: 0
  483. })
  484. return
  485. }
  486. this.setData({
  487. cutT: top,
  488. cutL: topL
  489. })
  490. break
  491. case 'left':
  492. let left = this.conf.CUT_L + xLength
  493. left = Math.ceil(left >= this.drag.SPACE_LEFT_POSITION ? this.drag.SPACE_LEFT_POSITION : left)
  494. let leftB = this.conf.CUT_B + xLength / this.properties.cutRatio
  495. leftB = Math.ceil(leftB >= this.drag.SPACE_BOTTOM_POSITION ? this.drag.SPACE_BOTTOM_POSITION : leftB)
  496. // console.log(leftB)
  497. // console.log(left)
  498. if (leftB < 0) {
  499. if (this.data.cutL <= 0) return
  500. if (this.data.cutB >= 0) return
  501. this.setData({
  502. cutB: 0
  503. })
  504. return
  505. }
  506. if (left <= 0) {
  507. this.setData({
  508. cutL: 0
  509. })
  510. return
  511. }
  512. this.setData({
  513. cutL: left,
  514. cutB: leftB
  515. })
  516. break
  517. case 'bottom':
  518. let bottom = this.conf.CUT_B - yLength
  519. bottom = Math.ceil(bottom >= this.drag.SPACE_BOTTOM_POSITION ? this.drag.SPACE_BOTTOM_POSITION : bottom)
  520. let bottomR = this.conf.CUT_R - yLength * this.properties.cutRatio
  521. bottomR = Math.ceil(bottomR >= this.drag.SPACE_RIGHT_POSITION ? this.drag.SPACE_RIGHT_POSITION : bottomR)
  522. if (bottomR < 0) {
  523. if (this.data.cutB <= 0) return
  524. if (this.data.cutR >= 0) return
  525. this.setData({
  526. cutR: 0
  527. })
  528. return
  529. }
  530. if (bottom <= 0) {
  531. this.setData({
  532. cutB: 0
  533. })
  534. return
  535. }
  536. this.setData({
  537. cutR: bottomR,
  538. cutB: bottom
  539. })
  540. break
  541. case 'right':
  542. let right = this.conf.CUT_R - xLength
  543. right = Math.ceil(right >= this.drag.SPACE_RIGHT_POSITION ? this.drag.SPACE_RIGHT_POSITION : right)
  544. let rightT = this.conf.CUT_T - xLength / this.properties.cutRatio
  545. rightT = Math.ceil(rightT >= this.drag.SPACE_TOP_POSITION ? this.drag.SPACE_TOP_POSITION : rightT)
  546. if (rightT < 0) {
  547. if (this.data.cutR <= 0) return
  548. if (this.data.cutT >= 0) return
  549. this.setData({
  550. cutT: 0
  551. })
  552. return
  553. }
  554. if (right <= 0) {
  555. this.setData({
  556. cutR: 0
  557. })
  558. return
  559. }
  560. this.setData({
  561. cutR: right,
  562. cutT: rightT
  563. })
  564. break
  565. }
  566. },
  567. /**
  568. * 非等比例拖拽的操作
  569. */
  570. sideDragMoveDefault(e, type) {
  571. const xLength = (e.touches[0].pageX - this.drag.MOVE_PAGE_X) * this.conf.DRAG_MOVE_RATIO
  572. const yLength = (e.touches[0].pageY - this.drag.MOVE_PAGE_Y) * this.conf.DRAG_MOVE_RATIO
  573. switch (type) {
  574. case 'top':
  575. let top = this.conf.CUT_T + yLength
  576. top = top <= 0 ? 0 : top
  577. top = Math.ceil(top >= this.drag.SPACE_TOP_POSITION ? this.drag.SPACE_TOP_POSITION : top)
  578. this.setData({
  579. cutT: top
  580. })
  581. break
  582. case 'bottom':
  583. let bottom = this.conf.CUT_B - yLength
  584. bottom = bottom <= 0 ? 0 : bottom
  585. bottom = Math.ceil(bottom >= this.drag.SPACE_BOTTOM_POSITION ? this.drag.SPACE_BOTTOM_POSITION : bottom)
  586. this.setData({
  587. cutB: bottom
  588. })
  589. break
  590. case 'right':
  591. let right = this.conf.CUT_R - xLength
  592. right = right <= 0 ? 0 : right
  593. right = Math.ceil(right >= this.drag.SPACE_RIGHT_POSITION ? this.drag.SPACE_RIGHT_POSITION : right)
  594. this.setData({
  595. cutR: right
  596. })
  597. break
  598. case 'left':
  599. let left = this.conf.CUT_L + xLength
  600. left = left <= 0 ? 0 : left
  601. left = Math.ceil(left >= this.drag.SPACE_LEFT_POSITION ? this.drag.SPACE_LEFT_POSITION : left)
  602. this.setData({
  603. cutL: left
  604. })
  605. break
  606. case 'rightBottom':
  607. let rightBottomR = this.conf.CUT_R - xLength
  608. rightBottomR = rightBottomR <= 0 ? 0 : rightBottomR
  609. rightBottomR = Math.ceil(rightBottomR >= this.drag.SPACE_RIGHT_POSITION ? this.drag.SPACE_RIGHT_POSITION : rightBottomR)
  610. let rightBottomB = this.conf.CUT_B - yLength
  611. rightBottomB = rightBottomB <= 0 ? 0 : rightBottomB
  612. rightBottomB = Math.ceil(rightBottomB >= this.drag.SPACE_BOTTOM_POSITION ? this.drag.SPACE_BOTTOM_POSITION : rightBottomB)
  613. this.setData({
  614. cutB: rightBottomB,
  615. cutR: rightBottomR
  616. })
  617. break
  618. default:
  619. break
  620. }
  621. },
  622. },
  623. created: function () {
  624. this.initStaticData()
  625. // console.log(this.drag)
  626. // console.log(this.conf)
  627. // console.log(this.data)
  628. // console.log(this.conf.DRAG_MOVE_RATIO)
  629. },
  630. attached: function () {
  631. // console.log('attached')
  632. this.loadImage()
  633. },
  634. ready: function () {
  635. // console.log('ready')
  636. },
  637. moved: function () {
  638. // console.log('moved')
  639. },
  640. detached: function () {
  641. // console.log('detached')
  642. }
  643. })