welCropper.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872
  1. let cropperUtil = require('./welCropperUtil.js')
  2. var init = function (W, H) {
  3. let that = this
  4. that.setData({
  5. cropperData: {
  6. drawSign: 0,
  7. hidden: true,
  8. left: 0,
  9. top: 0,
  10. width: W,
  11. height: H,
  12. W: W,
  13. H: H,
  14. itemLength: 50,
  15. imageInfo: {
  16. path: '',
  17. width: 0,
  18. height: 0
  19. },
  20. scaleInfo: {
  21. x: 1,
  22. y: 1
  23. },
  24. cropCallback: null,
  25. sizeType: ['original', 'compressed'], //'original'(default) | 'compressed'
  26. original: false, // 默认压缩,压缩比例为截图的0.4
  27. mode: 'rectangle', //默认矩形
  28. },
  29. cropperMovableItems: {
  30. topleft: {
  31. x: 50,
  32. y: 50
  33. },
  34. topright: {
  35. x: W - 50,
  36. y: 50
  37. },
  38. bottomleft: {
  39. x: 50,
  40. y: H - 50
  41. },
  42. bottomright: {
  43. x: W - 50,
  44. y: H - 50
  45. }
  46. },
  47. cropperMainItem:{
  48. x:110,
  49. y:110,
  50. w:50,
  51. h:50
  52. },
  53. cropperChangableData: {
  54. canCrop: true,
  55. rotateDegree: 0,
  56. originalSize: {
  57. width: 0,
  58. height: 0
  59. },
  60. scaleSize: {
  61. width: 0,
  62. height: 0
  63. },
  64. shape: {
  65. },
  66. previewImageInfo: {
  67. x: 0,
  68. y: 0,
  69. w: 0,
  70. h: 0
  71. }
  72. }
  73. })
  74. // 显示cropper,如果有图片则载入
  75. that.showCropper = (options) => {
  76. console.log(options)
  77. let z = this
  78. let cropperData = z.data.cropperData
  79. let src = options.src
  80. let callback = options.callback
  81. let sizeType = options.sizeType
  82. let mode = options.mode
  83. let filterType = []
  84. if (sizeType.indexOf('original') > -1) {
  85. filterType.push('original')
  86. }
  87. if (sizeType.indexOf('compressed') > -1) {
  88. filterType.push('compressed')
  89. }
  90. if (filterType.length == 1 && filterType.indexOf('original') > -1) {
  91. cropperData.original = true
  92. }
  93. if (mode) {
  94. cropperData.mode = mode
  95. }
  96. cropperData.hidden = false
  97. cropperData.hash = Math.random()
  98. cropperData.cropCallback = callback
  99. cropperData.sizeType = filterType
  100. // z.setData({
  101. // cropperData: cropperData,
  102. // })
  103. if (src) {
  104. console.log(src)
  105. wx.getImageInfo({
  106. src: src,
  107. success: function (res) {
  108. var w = res.width, h = res.height
  109. // let cropperData = z.data.cropperData
  110. cropperData.imageInfo = {
  111. path: src,
  112. width: w,
  113. height: h
  114. }
  115. z.setData({
  116. cropperData: cropperData,
  117. // cropperMainItem: {
  118. // x: 210,
  119. // y: 110,
  120. // w: 50,
  121. // h: 50
  122. // }
  123. })
  124. console.log('cropperData1')
  125. z.loadImage(src, w, h, false)
  126. }
  127. })
  128. }
  129. }
  130. // 隐藏cropper
  131. that.hideCropper = () => {
  132. let that = this
  133. that.data.cropperData.hidden = true
  134. that.data.cropperData.cropCallback = null
  135. that.setData({
  136. cropperData: that.data.cropperData,
  137. cropperMovableItems: {
  138. topleft: {
  139. x: -1,
  140. y: -1
  141. },
  142. topright: {
  143. x: -1,
  144. y: -1
  145. },
  146. bottomleft: {
  147. x: -1,
  148. y: -1
  149. },
  150. bottomright: {
  151. x: -1,
  152. y: -1
  153. }
  154. },
  155. cropperChangableData: {
  156. canCrop: true,
  157. rotateDegree: 0,
  158. previewImageInfo: {
  159. x: 0,
  160. y: 0,
  161. w: 0,
  162. h: 0,
  163. }
  164. }
  165. })
  166. that.clearCanvas(that.data.cropperData.imageInfo)
  167. }
  168. // 原图按钮被点击
  169. that.originalChange = () => {
  170. let that = this
  171. let imageInfo = that.data.cropperData.imageInfo
  172. let originalSize = that.data.cropperChangableData.originalSize
  173. let width = originalSize.width
  174. let height = originalSize.height
  175. let original = !that.data.cropperData.original
  176. let compressedScale = original ? 1.0 : 0.4
  177. let size = cropperUtil.getAdjustSize(W, H, width, height)
  178. console.log("change original=" + original)
  179. that.data.cropperData.original = original
  180. that.data.cropperData.scaleInfo = {
  181. x: width * compressedScale / size.width,
  182. y: height * compressedScale / size.height
  183. }
  184. // 之所以要设置cropperMovableItems,然后延时在设置一次,是因为改变cropperData后,movable-view会莫名其妙移动到左上角
  185. let cropperMovableItemsCopy = that.data.cropperMovableItems
  186. let cropperMovableItems = {
  187. topleft: {
  188. x: 0,
  189. y: 0
  190. },
  191. topright: {
  192. x: 0,
  193. y: 0
  194. },
  195. bottomleft: {
  196. x: 0,
  197. y: 0
  198. },
  199. bottomright: {
  200. x: 0,
  201. y: 0
  202. }
  203. }
  204. that.setData({
  205. cropperData: that.data.cropperData,
  206. cropperMovableItems: cropperMovableItems
  207. })
  208. setTimeout(() => {
  209. that.setData({
  210. cropperMovableItems: cropperMovableItemsCopy
  211. })
  212. }, 100)
  213. that.drawOriginalImage()
  214. }
  215. // 截取选中图片,如果有回调,则调用
  216. that.cropImage = () => {
  217. let that = this
  218. let cropperData = that.data.cropperData
  219. let mode = cropperData.mode
  220. let scaleInfo = cropperData.scaleInfo
  221. let width = cropperData.width
  222. let height = cropperData.height
  223. let cropperMovableItems = that.data.cropperMovableItems
  224. if (mode == 'rectangle') {
  225. let maxX = 0, maxY = 0
  226. for (let key in cropperMovableItems) {
  227. let item = cropperMovableItems[key]
  228. maxX = item.x > maxX ? item.x : maxX
  229. maxY = item.y > maxY ? item.y : maxY
  230. }
  231. let minX = maxX, minY = maxY
  232. for (let key in cropperMovableItems) {
  233. let item = cropperMovableItems[key]
  234. minX = item.x < minX ? item.x : minX
  235. minY = item.y < minY ? item.y : minY
  236. }
  237. let w = maxX - minX, h = maxY - minY
  238. w *= scaleInfo.x
  239. h *= scaleInfo.y
  240. let x = minX * scaleInfo.x, y = minY * scaleInfo.y
  241. console.log('crop rect: x=' + x + ',y=' + y + ',w=' + w + ',h=' + h)
  242. let ctx = wx.createCanvasContext("originalCanvas")
  243. wx.showLoading({
  244. title: '正在截取...',
  245. })
  246. wx.canvasToTempFilePath({
  247. x: x,
  248. y: y,
  249. width: w,
  250. height: h,
  251. destWidth: w,
  252. destHeight: h,
  253. canvasId: 'originalCanvas',
  254. success: (res) => {
  255. let tempFilePath = res.tempFilePath
  256. wx.hideLoading()
  257. // wx.saveImageToPhotosAlbum({
  258. // filePath: tempFilePath,
  259. // success(res) {
  260. // }
  261. // })
  262. //console.log('截取成功', res);
  263. if (that.data.cropperData.cropCallback) {
  264. that.data.cropperData.cropCallback(tempFilePath)
  265. }
  266. },
  267. fail(res) {
  268. wx.hideLoading()
  269. wx.showModal({
  270. title: '截取失败',
  271. content: res.errMsg
  272. })
  273. console.log("fail res:")
  274. console.log(res)
  275. }
  276. })
  277. }
  278. else {
  279. let res = [[0, 0], [0, 0], [0, 0], [0, 0]]
  280. let points = []
  281. for (let key in cropperMovableItems) {
  282. let x = Math.ceil(cropperMovableItems[key].x * scaleInfo.x)
  283. let y = Math.ceil(cropperMovableItems[key].y * scaleInfo.y)
  284. let index = 0
  285. if (key == 'topleft') {
  286. index = 0
  287. }
  288. else if (key == 'bottomleft') {
  289. index = 1
  290. }
  291. else if (key == 'bottomright') {
  292. index = 2
  293. }
  294. else if (key == 'topright') {
  295. index = 3
  296. }
  297. res[index] = [x, y]
  298. points.push({ x, y })
  299. }
  300. cropperUtil.convexHull(points, points.length)
  301. if (that.data.cropperData.cropCallback) {
  302. that.data.cropperData.cropCallback(res)
  303. }
  304. }
  305. }
  306. // 测试
  307. // 截取形状
  308. // that.changeCropShapeHandler = () => {
  309. // const map = [
  310. // 'no',
  311. // 'square'
  312. // ]
  313. // wx.showActionSheet({
  314. // itemList: ['不定形状', '正方形'],
  315. // success: function (res) {
  316. // console.log(res.tapIndex)
  317. // },
  318. // fail: function (res) {
  319. // console.log(res.errMsg)
  320. // }
  321. // })
  322. // }
  323. // 旋转图片
  324. that.rotateImage = () => {
  325. console.log("rotate image")
  326. let that = this
  327. let imageInfo = that.data.cropperData.imageInfo
  328. let width = imageInfo.width
  329. let height = imageInfo.height
  330. let rotateDegree = that.data.cropperChangableData.rotateDegree
  331. rotateDegree = rotateDegree == 360 ? 90 : rotateDegree + 90
  332. // 判断是否为垂直方向
  333. let isVertical = rotateDegree % 180 > 0
  334. let rotateWidth = isVertical ? height : width
  335. let rotateHeight = isVertical ? width : height
  336. let size = cropperUtil.getAdjustSize(W, H, rotateWidth, rotateHeight)
  337. // 适应屏幕的位置
  338. let left = (W - size.width) / 2
  339. let top = (H - size.height) / 2
  340. let cropperData = that.data.cropperData
  341. cropperData.left = left
  342. cropperData.top = top
  343. let cropperChangableData = that.data.cropperChangableData
  344. cropperChangableData.originalSize = {
  345. width: rotateWidth,
  346. height: rotateHeight
  347. }
  348. cropperChangableData.scaleSize = {
  349. width: size.width,
  350. height: size.height
  351. }
  352. cropperChangableData.rotateDegree = rotateDegree
  353. that.setData({
  354. cropperChangableData: cropperChangableData,
  355. cropperData: cropperData
  356. })
  357. console.log(cropperChangableData)
  358. let cropperMovableItemsCopy = that.data.cropperMovableItems
  359. let cropperMovableItems = {
  360. topleft: {
  361. x: 0,
  362. y: 0
  363. },
  364. topright: {
  365. x: 0,
  366. y: 0
  367. },
  368. bottomleft: {
  369. x: 0,
  370. y: 0
  371. },
  372. bottomright: {
  373. x: 0,
  374. y: 0
  375. }
  376. }
  377. that.setData({
  378. cropperMovableItems: cropperMovableItems
  379. })
  380. setTimeout(() => {
  381. that.loadImage(imageInfo.path, rotateWidth, rotateHeight, true)
  382. // that.setData({
  383. // cropperMovableItems: cropperMovableItemsCopy
  384. // })
  385. }, 100)
  386. }
  387. // 根据图片大小设置canvas大小,并绘制图片
  388. that.loadImage = (src, width, height, isRotate) => {
  389. let z = this
  390. let size = cropperUtil.getAdjustSize(W, H, width, height)
  391. // 适应屏幕的位置
  392. let left = (W - size.width) / 2
  393. let top = (H - size.height) / 2
  394. // set data
  395. let updateData = {}
  396. let cropperData = z.data.cropperData
  397. cropperData.drawSign = !cropperData.drawSign
  398. if (!isRotate) {
  399. cropperData.imageInfo = {
  400. path: src,
  401. width: width,
  402. height: height
  403. }
  404. }
  405. cropperData.left = left
  406. cropperData.top = top
  407. cropperData.width = size.width
  408. cropperData.height = size.height
  409. let compressedScale = z.data.cropperData.original ? 1.0 : 0.4
  410. // let scaleSize = cropperUtil.getAdjustSize(W, H, width, height)
  411. cropperData.scaleInfo = {
  412. x: width * compressedScale / size.width,
  413. y: height * compressedScale / size.height
  414. }
  415. updateData.cropperData = cropperData
  416. updateData.cropperMovableItems = {
  417. topleft: {
  418. x: 50,
  419. y: 50
  420. },
  421. topright: {
  422. x: size.width - 50,
  423. y: 50
  424. },
  425. bottomleft: {
  426. x: 50,
  427. y: size.height - 50
  428. },
  429. bottomright: {
  430. x: size.width - 50,
  431. y: size.height - 50
  432. }
  433. }
  434. // updateData.cropperMainItem = {
  435. // x: 100,
  436. // y: 100,
  437. // w: 100,
  438. // h: 100
  439. // }
  440. // setTimeout(()=>{
  441. // console.log('main item')
  442. // z.setData({
  443. // cropperMainItem: {
  444. // x: 100,
  445. // y: 100,
  446. // w: 100,
  447. // h: 100
  448. // }
  449. // })
  450. // }, 2000)
  451. let cropperChangableData = z.data.cropperChangableData
  452. let rotateDegree = cropperChangableData.rotateDegree
  453. // 判断是否为垂直方向
  454. let isVertical = rotateDegree % 180 > 0
  455. let rotateWidth = isVertical ? size.height : size.width
  456. let rotateHeight = isVertical ? size.width : size.height
  457. console.log(size)
  458. console.log('rotateDegree:' + rotateDegree)
  459. console.log('rotateWidth:' + rotateWidth + ', rotateHeight:' + rotateHeight)
  460. cropperChangableData.previewImageInfo.x = (W - rotateWidth) / 2
  461. cropperChangableData.previewImageInfo.y = (H - rotateHeight) / 2
  462. cropperChangableData.previewImageInfo.w = rotateWidth
  463. cropperChangableData.previewImageInfo.h = rotateHeight
  464. cropperChangableData.originalSize = {
  465. width: width,
  466. height: height
  467. }
  468. cropperChangableData.scaleSize = {
  469. width: size.width,
  470. height: size.height
  471. }
  472. updateData.cropperChangableData = cropperChangableData
  473. z.setData(updateData)
  474. console.log('cropperData2')
  475. // console.log("loadImage size:" + width + "*" + height)
  476. z.drawImage({
  477. path: z.data.cropperData.imageInfo.path,
  478. width: width,
  479. height: height
  480. })
  481. // that.drawImage(that.data.cropperData.imageInfo)
  482. z.drawLines(z.data.cropperMovableItems, z.data.cropperData.imageInfo)
  483. }
  484. // 清空canvas上的数据
  485. that.clearCanvas = (imageInfo) => {
  486. let cropperData = that.data.cropperData
  487. let size = cropperUtil.getAdjustSize(W, H, imageInfo.width, imageInfo.height)
  488. if (imageInfo.path != '') {
  489. let compressedScale = that.data.cropperData.original ? 1.0 : 0.4
  490. //清空原图
  491. let ctx = wx.createCanvasContext("originalCanvas")
  492. ctx.clearRect(0, 0, imageInfo.width * compressedScale, imageInfo.height * compressedScale)
  493. ctx.draw()
  494. //清空选择区图片
  495. let canvas = wx.createCanvasContext("canvas")
  496. canvas.clearRect(0, 0, size.width, size.height)
  497. canvas.draw()
  498. // 清空白线框
  499. let moveCanvas = wx.createCanvasContext("moveCanvas")
  500. moveCanvas.clearRect(0, 0, size.width, size.height)
  501. moveCanvas.draw()
  502. }
  503. }
  504. //绘制图片
  505. that.drawImage = (imageInfo) => {
  506. let z = this
  507. let cropperData = z.data.cropperData
  508. let size = cropperUtil.getAdjustSize(W, H, imageInfo.width, imageInfo.height)
  509. if (imageInfo.path != '') {
  510. let path = imageInfo.path
  511. let compressedScale = z.data.cropperData.original ? 1.0 : 0.4
  512. let rotateDegree = z.data.cropperChangableData.rotateDegree
  513. let canvasCtx = wx.createCanvasContext('canvas', z)
  514. let originalCanvasCtx = wx.createCanvasContext('originalCanvas', z)
  515. //绘制原图
  516. cropperUtil.drawImageWithDegree(
  517. originalCanvasCtx,
  518. path,
  519. imageInfo.width * compressedScale,
  520. imageInfo.height * compressedScale,
  521. rotateDegree
  522. )
  523. // let originalCanvas = wx.createCanvasContext("originalCanvas")
  524. // originalCanvas.drawImage(path, 0, 0, imageInfo.width * compressedScale, imageInfo.height * compressedScale)
  525. // originalCanvas.draw()
  526. //绘制选择区图片
  527. cropperUtil.drawImageWithDegree(canvasCtx, path, size.width, size.height, rotateDegree)
  528. // let canvas = wx.createCanvasContext("canvas")
  529. // canvas.drawImage(path, 0, 0, size.width, size.height)
  530. // canvas.draw()
  531. console.log("draw=" + path)
  532. }
  533. }
  534. // 单独绘制原图,当切换原图与非原图时使用
  535. that.drawOriginalImage = () => {
  536. let z = this
  537. let cropperData = z.data.cropperData
  538. let imageInfo = cropperData.imageInfo
  539. let originalSize = z.data.cropperChangableData.originalSize
  540. if (imageInfo.path != '') {
  541. let path = imageInfo.path
  542. let compressedScale = z.data.cropperData.original ? 1.0 : 0.4
  543. let rotateDegree = z.data.cropperChangableData.rotateDegree
  544. let originalCanvasCtx = wx.createCanvasContext('originalCanvas', z)
  545. //绘制原图
  546. cropperUtil.drawImageWithDegree(
  547. originalCanvasCtx,
  548. path,
  549. originalSize.width * compressedScale,
  550. originalSize.height * compressedScale,
  551. rotateDegree
  552. )
  553. // let originalCanvas = wx.createCanvasContext("originalCanvas")
  554. // originalCanvas.drawImage(path, 0, 0, imageInfo.width * compressedScale, imageInfo.height * compressedScale)
  555. // originalCanvas.draw()
  556. }
  557. }
  558. //绘制选框
  559. that.drawLines = function (cropperMovableItems, imageInfo, callback) {
  560. // console.log((new Date()).getTime())
  561. let that = this
  562. let cropperData = that.data.cropperData
  563. let mode = cropperData.mode
  564. let rotateDegree = that.data.cropperChangableData.rotateDegree
  565. let size
  566. if (rotateDegree % 180 > 0) {
  567. size = cropperUtil.getAdjustSize(W, H, imageInfo.height, imageInfo.width)
  568. }
  569. else {
  570. size = cropperUtil.getAdjustSize(W, H, imageInfo.width, imageInfo.height)
  571. }
  572. let convexDots = []
  573. let orderedDots = []
  574. orderedDots.push(cropperMovableItems['topleft'])
  575. orderedDots.push(cropperMovableItems['topright'])
  576. orderedDots.push(cropperMovableItems['bottomright'])
  577. orderedDots.push(cropperMovableItems['bottomleft'])
  578. // 获取凸边形的点
  579. convexDots = cropperUtil.convexHull(orderedDots, orderedDots.length)
  580. // 四个点组成的四边形是不是凸四边形
  581. let canCrop = convexDots.length == 4
  582. if (callback) {
  583. callback(canCrop)
  584. }
  585. let ctx = wx.createCanvasContext("moveCanvas")
  586. //绘制高亮选中区域
  587. let rect = cropperUtil.getCropRect(convexDots)
  588. if (mode == 'rectangle') {
  589. // 绘制半透明遮罩
  590. ctx.setFillStyle('rgba(0,0,0,0.5)')
  591. ctx.fillRect(0, 0, size.width, size.height)
  592. // 清除选中区域的半透明遮罩,使选中区域高亮
  593. ctx.setFillStyle('rgba(0,0,0,0)')
  594. ctx.clearRect(rect.x, rect.y, rect.w, rect.h)
  595. //绘制选中边框
  596. ctx.setStrokeStyle('white')
  597. ctx.setLineWidth(2)
  598. ctx.beginPath()
  599. ctx.moveTo(rect.x, rect.y)
  600. ctx.lineTo(rect.x + rect.w, rect.y)
  601. ctx.lineTo(rect.x + rect.w, rect.y + rect.h)
  602. ctx.lineTo(rect.x, rect.y + rect.h)
  603. ctx.lineTo(rect.x, rect.y)
  604. ctx.stroke()
  605. ctx.closePath()
  606. }
  607. else {
  608. //绘制选中边框
  609. // 如果四个点组成的四边形不是凸四边形,则显示红色,表示不可取
  610. let color = canCrop ? 'white' : 'red'
  611. ctx.setStrokeStyle(color)
  612. ctx.setLineWidth(2)
  613. ctx.beginPath()
  614. for (let i = 0, len = convexDots.length; i < len; i++) {
  615. let dot = convexDots[i]
  616. if (i == 0) {
  617. ctx.moveTo(dot.x, dot.y)
  618. }
  619. else {
  620. ctx.lineTo(dot.x, dot.y)
  621. }
  622. }
  623. let dot = convexDots[0]
  624. ctx.lineTo(dot.x, dot.y)
  625. ctx.stroke()
  626. ctx.closePath()
  627. }
  628. //绘制四个角
  629. let cornerType = mode == 'rectangle' ? 'rect' : 'circle'
  630. ctx.setFillStyle('white')
  631. ctx.setStrokeStyle('white')
  632. // 绘制不同样式的角
  633. if (cornerType == 'circle') {
  634. for (let i = 0, len = orderedDots.length; i < len; i++) {
  635. let dot = orderedDots[i]
  636. ctx.beginPath()
  637. ctx.arc(dot.x, dot.y, 10, 0, 2 * Math.PI, true)
  638. ctx.fill()
  639. ctx.closePath()
  640. }
  641. }
  642. else if (cornerType == 'rect') {
  643. let len = 20, w = 3.0, offset = w / 2.0
  644. ctx.setLineWidth(w)
  645. ctx.beginPath()
  646. ctx.moveTo(rect.x - offset, rect.y - offset + len)
  647. ctx.lineTo(rect.x - offset, rect.y - offset)
  648. ctx.lineTo(rect.x - offset + len, rect.y - offset)
  649. ctx.moveTo(rect.x + offset + rect.w - len, rect.y - offset)
  650. ctx.lineTo(rect.x + offset + rect.w, rect.y - offset)
  651. ctx.lineTo(rect.x + offset + rect.w, rect.y - offset + len)
  652. ctx.moveTo(rect.x + offset + rect.w, rect.y + offset + rect.h - len)
  653. ctx.lineTo(rect.x + offset + rect.w, rect.y + offset + rect.h)
  654. ctx.lineTo(rect.x + offset + rect.w - len, rect.y + offset + rect.h)
  655. ctx.moveTo(rect.x - offset, rect.y + offset + rect.h - len)
  656. ctx.lineTo(rect.x - offset, rect.y + offset + rect.h)
  657. ctx.lineTo(rect.x - offset + len, rect.y + offset + rect.h)
  658. ctx.stroke()
  659. ctx.closePath()
  660. }
  661. ctx.draw()
  662. }
  663. // move events
  664. that.setupMoveItem = (key, changedTouches, imageInfo, callback) => {
  665. let that = this
  666. let cropperData = that.data.cropperData
  667. let cropperMovableItems = that.data.cropperMovableItems
  668. let left = cropperData.left
  669. let top = cropperData.top
  670. let mode = cropperData.mode
  671. let size = cropperUtil.getAdjustSize(W, H, imageInfo.width, imageInfo.height)
  672. if (changedTouches.length == 1) {
  673. let touch = changedTouches[0]
  674. let x = touch.clientX
  675. let y = touch.clientY
  676. // 相对画布的点
  677. x = x - left
  678. y = y - top
  679. cropperMovableItems[key].x = x
  680. cropperMovableItems[key].y = y
  681. // 边界检测,使截图不超出截图区域
  682. x = x < 0 ? 0 : (x > size.width ? size.width : x)
  683. y = y < 0 ? 0 : (y > size.height ? size.height : y)
  684. cropperMovableItems[key].x = x
  685. cropperMovableItems[key].y = y
  686. // 如果是在矩形模式下
  687. if (mode == 'rectangle') {
  688. // 同时设置相连两个点的位置,是相邻的两个点跟随着移动点动,保证选框为矩形
  689. if (key == 'topleft') {
  690. cropperMovableItems['bottomleft'].x = x
  691. cropperMovableItems['topright'].y = y
  692. }
  693. else if (key == 'topright') {
  694. cropperMovableItems['bottomright'].x = x
  695. cropperMovableItems['topleft'].y = y
  696. }
  697. else if (key == 'bottomleft') {
  698. cropperMovableItems['topleft'].x = x
  699. cropperMovableItems['bottomright'].y = y
  700. }
  701. else if (key == 'bottomright') {
  702. cropperMovableItems['topright'].x = x
  703. cropperMovableItems['bottomleft'].y = y
  704. }
  705. }
  706. that.drawLines(cropperMovableItems, imageInfo, function (canCrop) {
  707. if (callback) {
  708. callback(cropperMovableItems, canCrop)
  709. }
  710. })
  711. }
  712. }
  713. // moveable-view touchmove
  714. that.moveEvent = (e) => {
  715. let that = this
  716. let key = e.currentTarget.dataset.key
  717. let originalSize = that.data.cropperChangableData.originalSize
  718. that.setupMoveItem(key, e.changedTouches, {
  719. path: that.data.cropperData.imageInfo.path,
  720. width: originalSize.width,
  721. height: originalSize.height
  722. })
  723. }
  724. // moveable-view touchend,end的时候设置movable-view的位置,如果在move阶段设置位置,选中会不流畅
  725. that.endEvent = (e) => {
  726. console.log("end")
  727. let that = this
  728. let cropperData = that.data.cropperData
  729. let cropperMovableItems = that.data.cropperMovableItems
  730. let cropperChangableData = that.data.cropperChangableData
  731. let originalSize = cropperChangableData.originalSize
  732. let key = e.currentTarget.dataset.key
  733. that.setupMoveItem(key, e.changedTouches, {
  734. path: that.data.cropperData.imageInfo.path,
  735. width: originalSize.width,
  736. height: originalSize.height
  737. }, (cropperMovableItems, canCrop) => {
  738. cropperChangableData.canCrop = canCrop
  739. that.setData({
  740. cropperChangableData: cropperChangableData,
  741. cropperMovableItems: cropperMovableItems
  742. })
  743. })
  744. }
  745. }
  746. module.exports = {
  747. init
  748. }