oxy-uni-ui 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (355) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +13 -0
  3. package/attributes.json +1 -0
  4. package/components/common/AbortablePromise.ts +28 -0
  5. package/components/common/abstracts/_config.scss +7 -0
  6. package/components/common/abstracts/_function.scss +89 -0
  7. package/components/common/abstracts/_mixin.scss +385 -0
  8. package/components/common/abstracts/variable.scss +974 -0
  9. package/components/common/base64.ts +29 -0
  10. package/components/common/canvasHelper.ts +49 -0
  11. package/components/common/clickoutside.ts +25 -0
  12. package/components/common/event.ts +8 -0
  13. package/components/common/interceptor.ts +43 -0
  14. package/components/common/props.ts +51 -0
  15. package/components/common/util.ts +778 -0
  16. package/components/composables/index.ts +11 -0
  17. package/components/composables/useCell.ts +13 -0
  18. package/components/composables/useChildren.ts +113 -0
  19. package/components/composables/useCountDown.ts +138 -0
  20. package/components/composables/useLockScroll.ts +37 -0
  21. package/components/composables/useParent.ts +41 -0
  22. package/components/composables/usePopover.ts +176 -0
  23. package/components/composables/useQueue.ts +52 -0
  24. package/components/composables/useRaf.ts +37 -0
  25. package/components/composables/useTouch.ts +43 -0
  26. package/components/composables/useTranslate.ts +12 -0
  27. package/components/composables/useUpload.ts +364 -0
  28. package/components/oxy-action-sheet/index.scss +204 -0
  29. package/components/oxy-action-sheet/oxy-action-sheet.vue +155 -0
  30. package/components/oxy-action-sheet/types.ts +118 -0
  31. package/components/oxy-backtop/index.scss +25 -0
  32. package/components/oxy-backtop/oxy-backtop.vue +45 -0
  33. package/components/oxy-backtop/types.ts +37 -0
  34. package/components/oxy-badge/index.scss +63 -0
  35. package/components/oxy-badge/oxy-badge.vue +61 -0
  36. package/components/oxy-badge/types.ts +41 -0
  37. package/components/oxy-button/index.scss +336 -0
  38. package/components/oxy-button/oxy-button.vue +195 -0
  39. package/components/oxy-button/types.ts +133 -0
  40. package/components/oxy-calendar/index.scss +158 -0
  41. package/components/oxy-calendar/oxy-calendar.vue +451 -0
  42. package/components/oxy-calendar/types.ts +217 -0
  43. package/components/oxy-calendar-view/index.scss +0 -0
  44. package/components/oxy-calendar-view/month/index.scss +162 -0
  45. package/components/oxy-calendar-view/month/month.vue +389 -0
  46. package/components/oxy-calendar-view/month/types.ts +20 -0
  47. package/components/oxy-calendar-view/monthPanel/index.scss +89 -0
  48. package/components/oxy-calendar-view/monthPanel/month-panel.vue +374 -0
  49. package/components/oxy-calendar-view/monthPanel/types.ts +48 -0
  50. package/components/oxy-calendar-view/oxy-calendar-view.vue +111 -0
  51. package/components/oxy-calendar-view/types.ts +109 -0
  52. package/components/oxy-calendar-view/utils.ts +429 -0
  53. package/components/oxy-calendar-view/year/index.scss +153 -0
  54. package/components/oxy-calendar-view/year/types.ts +20 -0
  55. package/components/oxy-calendar-view/year/year.vue +202 -0
  56. package/components/oxy-calendar-view/yearPanel/index.scss +24 -0
  57. package/components/oxy-calendar-view/yearPanel/types.ts +38 -0
  58. package/components/oxy-calendar-view/yearPanel/year-panel.vue +135 -0
  59. package/components/oxy-card/index.scss +71 -0
  60. package/components/oxy-card/oxy-card.vue +37 -0
  61. package/components/oxy-card/types.ts +30 -0
  62. package/components/oxy-cell/index.scss +206 -0
  63. package/components/oxy-cell/oxy-cell.vue +140 -0
  64. package/components/oxy-cell/types.ts +111 -0
  65. package/components/oxy-cell-group/index.scss +56 -0
  66. package/components/oxy-cell-group/oxy-cell-group.vue +45 -0
  67. package/components/oxy-cell-group/types.ts +32 -0
  68. package/components/oxy-checkbox/index.scss +285 -0
  69. package/components/oxy-checkbox/oxy-checkbox.vue +177 -0
  70. package/components/oxy-checkbox/types.ts +68 -0
  71. package/components/oxy-checkbox-group/index.scss +20 -0
  72. package/components/oxy-checkbox-group/oxy-checkbox-group.vue +100 -0
  73. package/components/oxy-checkbox-group/types.ts +59 -0
  74. package/components/oxy-circle/index.scss +18 -0
  75. package/components/oxy-circle/oxy-circle.vue +296 -0
  76. package/components/oxy-circle/types.ts +54 -0
  77. package/components/oxy-col/index.scss +19 -0
  78. package/components/oxy-col/oxy-col.vue +49 -0
  79. package/components/oxy-col/types.ts +15 -0
  80. package/components/oxy-col-picker/index.scss +168 -0
  81. package/components/oxy-col-picker/oxy-col-picker.vue +498 -0
  82. package/components/oxy-col-picker/types.ts +166 -0
  83. package/components/oxy-collapse/index.scss +55 -0
  84. package/components/oxy-collapse/oxy-collapse.vue +151 -0
  85. package/components/oxy-collapse/types.ts +58 -0
  86. package/components/oxy-collapse-item/index.scss +90 -0
  87. package/components/oxy-collapse-item/oxy-collapse-item.vue +171 -0
  88. package/components/oxy-collapse-item/types.ts +48 -0
  89. package/components/oxy-config-provider/oxy-config-provider.vue +73 -0
  90. package/components/oxy-config-provider/types.ts +1052 -0
  91. package/components/oxy-count-down/index.scss +15 -0
  92. package/components/oxy-count-down/oxy-count-down.vue +60 -0
  93. package/components/oxy-count-down/types.ts +41 -0
  94. package/components/oxy-count-down/utils.ts +52 -0
  95. package/components/oxy-count-to/index.scss +7 -0
  96. package/components/oxy-count-to/oxy-count-to.vue +125 -0
  97. package/components/oxy-count-to/types.ts +117 -0
  98. package/components/oxy-curtain/index.scss +85 -0
  99. package/components/oxy-curtain/oxy-curtain.vue +172 -0
  100. package/components/oxy-curtain/types.ts +73 -0
  101. package/components/oxy-datetime-picker/index.scss +164 -0
  102. package/components/oxy-datetime-picker/oxy-datetime-picker.vue +801 -0
  103. package/components/oxy-datetime-picker/types.ts +231 -0
  104. package/components/oxy-datetime-picker-view/oxy-datetime-picker-view.vue +499 -0
  105. package/components/oxy-datetime-picker-view/types.ts +120 -0
  106. package/components/oxy-datetime-picker-view/util.ts +30 -0
  107. package/components/oxy-design-uni/oxy-design-uni.vue +5 -0
  108. package/components/oxy-divider/index.scss +100 -0
  109. package/components/oxy-divider/oxy-divider.vue +52 -0
  110. package/components/oxy-divider/types.ts +35 -0
  111. package/components/oxy-drop-menu/index.scss +86 -0
  112. package/components/oxy-drop-menu/oxy-drop-menu.vue +166 -0
  113. package/components/oxy-drop-menu/types.ts +38 -0
  114. package/components/oxy-drop-menu-item/index.scss +66 -0
  115. package/components/oxy-drop-menu-item/oxy-drop-menu-item.vue +221 -0
  116. package/components/oxy-drop-menu-item/types.ts +94 -0
  117. package/components/oxy-fab/index.scss +116 -0
  118. package/components/oxy-fab/oxy-fab.vue +276 -0
  119. package/components/oxy-fab/types.ts +66 -0
  120. package/components/oxy-floating-panel/index.scss +64 -0
  121. package/components/oxy-floating-panel/oxy-floating-panel.vue +140 -0
  122. package/components/oxy-floating-panel/type.ts +32 -0
  123. package/components/oxy-form/oxy-form.vue +207 -0
  124. package/components/oxy-form/types.ts +76 -0
  125. package/components/oxy-form-item/index.scss +18 -0
  126. package/components/oxy-form-item/oxy-form-item.vue +56 -0
  127. package/components/oxy-form-item/types.ts +16 -0
  128. package/components/oxy-gap/index.scss +9 -0
  129. package/components/oxy-gap/oxy-gap.vue +36 -0
  130. package/components/oxy-gap/types.ts +17 -0
  131. package/components/oxy-grid/index.scss +9 -0
  132. package/components/oxy-grid/oxy-grid.vue +106 -0
  133. package/components/oxy-grid/types.ts +50 -0
  134. package/components/oxy-grid-item/index.scss +148 -0
  135. package/components/oxy-grid-item/oxy-grid-item.vue +176 -0
  136. package/components/oxy-grid-item/types.ts +77 -0
  137. package/components/oxy-icon/index.scss +1230 -0
  138. package/components/oxy-icon/oxy-icon.vue +53 -0
  139. package/components/oxy-icon/oxy-icons.ttf +0 -0
  140. package/components/oxy-icon/types.ts +21 -0
  141. package/components/oxy-img/index.scss +19 -0
  142. package/components/oxy-img/oxy-img.vue +81 -0
  143. package/components/oxy-img/types.ts +61 -0
  144. package/components/oxy-img-cropper/index.scss +231 -0
  145. package/components/oxy-img-cropper/oxy-img-cropper.vue +664 -0
  146. package/components/oxy-img-cropper/types.ts +76 -0
  147. package/components/oxy-index-anchor/index.scss +35 -0
  148. package/components/oxy-index-anchor/oxy-index-anchor.vue +55 -0
  149. package/components/oxy-index-anchor/type.ts +9 -0
  150. package/components/oxy-index-bar/index.scss +39 -0
  151. package/components/oxy-index-bar/oxy-index-bar.vue +156 -0
  152. package/components/oxy-index-bar/type.ts +23 -0
  153. package/components/oxy-input/index.scss +323 -0
  154. package/components/oxy-input/oxy-input.vue +300 -0
  155. package/components/oxy-input/placeholder.scss +21 -0
  156. package/components/oxy-input/types.ts +189 -0
  157. package/components/oxy-input-number/index.scss +132 -0
  158. package/components/oxy-input-number/oxy-input-number.vue +464 -0
  159. package/components/oxy-input-number/types.ts +101 -0
  160. package/components/oxy-keyboard/constants.ts +81 -0
  161. package/components/oxy-keyboard/index.scss +102 -0
  162. package/components/oxy-keyboard/key/index.scss +79 -0
  163. package/components/oxy-keyboard/key/index.vue +76 -0
  164. package/components/oxy-keyboard/key/types.ts +11 -0
  165. package/components/oxy-keyboard/oxy-keyboard.vue +206 -0
  166. package/components/oxy-keyboard/types.ts +92 -0
  167. package/components/oxy-loading/index.scss +37 -0
  168. package/components/oxy-loading/oxy-loading.vue +90 -0
  169. package/components/oxy-loading/types.ts +22 -0
  170. package/components/oxy-loadmore/index.scss +39 -0
  171. package/components/oxy-loadmore/oxy-loadmore.vue +59 -0
  172. package/components/oxy-loadmore/types.ts +30 -0
  173. package/components/oxy-message-box/index.scss +108 -0
  174. package/components/oxy-message-box/index.ts +87 -0
  175. package/components/oxy-message-box/oxy-message-box.vue +291 -0
  176. package/components/oxy-message-box/types.ts +132 -0
  177. package/components/oxy-navbar/index.scss +93 -0
  178. package/components/oxy-navbar/oxy-navbar.vue +111 -0
  179. package/components/oxy-navbar/types.ts +52 -0
  180. package/components/oxy-navbar-capsule/index.scss +66 -0
  181. package/components/oxy-navbar-capsule/oxy-navbar-capsule.vue +35 -0
  182. package/components/oxy-navbar-capsule/types.ts +8 -0
  183. package/components/oxy-notice-bar/index.scss +68 -0
  184. package/components/oxy-notice-bar/oxy-notice-bar.vue +266 -0
  185. package/components/oxy-notice-bar/types.ts +67 -0
  186. package/components/oxy-notify/index.scss +34 -0
  187. package/components/oxy-notify/index.ts +61 -0
  188. package/components/oxy-notify/oxy-notify.vue +85 -0
  189. package/components/oxy-notify/types.ts +66 -0
  190. package/components/oxy-number-keyboard/index.scss +78 -0
  191. package/components/oxy-number-keyboard/key/index.scss +81 -0
  192. package/components/oxy-number-keyboard/key/index.vue +78 -0
  193. package/components/oxy-number-keyboard/key/types.ts +11 -0
  194. package/components/oxy-number-keyboard/oxy-number-keyboard.vue +151 -0
  195. package/components/oxy-number-keyboard/types.ts +83 -0
  196. package/components/oxy-overlay/index.scss +17 -0
  197. package/components/oxy-overlay/oxy-overlay.vue +47 -0
  198. package/components/oxy-overlay/types.ts +25 -0
  199. package/components/oxy-pagination/index.scss +57 -0
  200. package/components/oxy-pagination/oxy-pagination.vue +110 -0
  201. package/components/oxy-pagination/types.ts +41 -0
  202. package/components/oxy-password-input/index.scss +124 -0
  203. package/components/oxy-password-input/oxy-password-input.vue +49 -0
  204. package/components/oxy-password-input/types.ts +33 -0
  205. package/components/oxy-picker/index.scss +110 -0
  206. package/components/oxy-picker/oxy-picker.vue +412 -0
  207. package/components/oxy-picker/types.ts +189 -0
  208. package/components/oxy-picker-view/index.scss +92 -0
  209. package/components/oxy-picker-view/oxy-picker-view.vue +369 -0
  210. package/components/oxy-picker-view/types.ts +152 -0
  211. package/components/oxy-popover/index.scss +116 -0
  212. package/components/oxy-popover/oxy-popover.vue +180 -0
  213. package/components/oxy-popover/types.ts +69 -0
  214. package/components/oxy-popup/index.scss +84 -0
  215. package/components/oxy-popup/oxy-popup.vue +169 -0
  216. package/components/oxy-popup/types.ts +95 -0
  217. package/components/oxy-progress/index.scss +68 -0
  218. package/components/oxy-progress/oxy-progress.vue +197 -0
  219. package/components/oxy-progress/types.ts +35 -0
  220. package/components/oxy-radio/index.scss +301 -0
  221. package/components/oxy-radio/oxy-radio.vue +118 -0
  222. package/components/oxy-radio/types.ts +42 -0
  223. package/components/oxy-radio-group/index.scss +23 -0
  224. package/components/oxy-radio-group/oxy-radio-group.vue +51 -0
  225. package/components/oxy-radio-group/types.ts +39 -0
  226. package/components/oxy-rate/index.scss +25 -0
  227. package/components/oxy-rate/oxy-rate.vue +178 -0
  228. package/components/oxy-rate/types.ts +103 -0
  229. package/components/oxy-resize/index.scss +27 -0
  230. package/components/oxy-resize/oxy-resize.vue +144 -0
  231. package/components/oxy-resize/types.ts +6 -0
  232. package/components/oxy-root-portal/oxy-root-portal.vue +50 -0
  233. package/components/oxy-row/index.scss +10 -0
  234. package/components/oxy-row/oxy-row.vue +42 -0
  235. package/components/oxy-row/types.ts +16 -0
  236. package/components/oxy-search/index.scss +148 -0
  237. package/components/oxy-search/oxy-search.vue +187 -0
  238. package/components/oxy-search/types.ts +93 -0
  239. package/components/oxy-segmented/index.scss +101 -0
  240. package/components/oxy-segmented/oxy-segmented.vue +143 -0
  241. package/components/oxy-segmented/types.ts +71 -0
  242. package/components/oxy-select-picker/index.scss +102 -0
  243. package/components/oxy-select-picker/oxy-select-picker.vue +432 -0
  244. package/components/oxy-select-picker/types.ts +123 -0
  245. package/components/oxy-sidebar/index.scss +25 -0
  246. package/components/oxy-sidebar/oxy-sidebar.vue +63 -0
  247. package/components/oxy-sidebar/types.ts +38 -0
  248. package/components/oxy-sidebar-item/index.scss +97 -0
  249. package/components/oxy-sidebar-item/oxy-sidebar-item.vue +116 -0
  250. package/components/oxy-sidebar-item/types.ts +31 -0
  251. package/components/oxy-signature/index.scss +31 -0
  252. package/components/oxy-signature/oxy-signature.vue +630 -0
  253. package/components/oxy-signature/types.ts +108 -0
  254. package/components/oxy-skeleton/index.scss +96 -0
  255. package/components/oxy-skeleton/index.ts +1 -0
  256. package/components/oxy-skeleton/oxy-skeleton.vue +110 -0
  257. package/components/oxy-skeleton/types.ts +69 -0
  258. package/components/oxy-slider/index.scss +98 -0
  259. package/components/oxy-slider/oxy-slider.vue +356 -0
  260. package/components/oxy-slider/types.ts +138 -0
  261. package/components/oxy-sort-button/index.scss +89 -0
  262. package/components/oxy-sort-button/oxy-sort-button.vue +69 -0
  263. package/components/oxy-sort-button/types.ts +43 -0
  264. package/components/oxy-status-tip/images/collect.png +0 -0
  265. package/components/oxy-status-tip/images/content.png +0 -0
  266. package/components/oxy-status-tip/images/network.png +0 -0
  267. package/components/oxy-status-tip/images/search.png +0 -0
  268. package/components/oxy-status-tip/index.scss +37 -0
  269. package/components/oxy-status-tip/oxy-status-tip.vue +71 -0
  270. package/components/oxy-status-tip/types.ts +50 -0
  271. package/components/oxy-step/index.scss +235 -0
  272. package/components/oxy-step/oxy-step.vue +150 -0
  273. package/components/oxy-step/types.ts +33 -0
  274. package/components/oxy-steps/index.scss +10 -0
  275. package/components/oxy-steps/oxy-steps.vue +28 -0
  276. package/components/oxy-steps/types.ts +50 -0
  277. package/components/oxy-sticky/index.scss +9 -0
  278. package/components/oxy-sticky/oxy-sticky.vue +190 -0
  279. package/components/oxy-sticky/types.ts +13 -0
  280. package/components/oxy-sticky-box/index.scss +6 -0
  281. package/components/oxy-sticky-box/oxy-sticky-box.vue +155 -0
  282. package/components/oxy-sticky-box/types.ts +11 -0
  283. package/components/oxy-swipe-action/index.scss +22 -0
  284. package/components/oxy-swipe-action/oxy-swipe-action.vue +294 -0
  285. package/components/oxy-swipe-action/types.ts +40 -0
  286. package/components/oxy-swiper/index.scss +53 -0
  287. package/components/oxy-swiper/oxy-swiper.vue +318 -0
  288. package/components/oxy-swiper/types.ts +264 -0
  289. package/components/oxy-swiper-nav/index.scss +159 -0
  290. package/components/oxy-swiper-nav/oxy-swiper-nav.vue +37 -0
  291. package/components/oxy-swiper-nav/types.ts +42 -0
  292. package/components/oxy-switch/index.scss +58 -0
  293. package/components/oxy-switch/oxy-switch.vue +83 -0
  294. package/components/oxy-switch/types.ts +58 -0
  295. package/components/oxy-tab/index.scss +16 -0
  296. package/components/oxy-tab/oxy-tab.vue +88 -0
  297. package/components/oxy-tab/types.ts +30 -0
  298. package/components/oxy-tabbar/index.scss +62 -0
  299. package/components/oxy-tabbar/oxy-tabbar.vue +91 -0
  300. package/components/oxy-tabbar/types.ts +73 -0
  301. package/components/oxy-tabbar-item/index.scss +55 -0
  302. package/components/oxy-tabbar-item/oxy-tabbar-item.vue +99 -0
  303. package/components/oxy-tabbar-item/types.ts +51 -0
  304. package/components/oxy-table/index.scss +163 -0
  305. package/components/oxy-table/oxy-table.vue +283 -0
  306. package/components/oxy-table/types.ts +58 -0
  307. package/components/oxy-table-col/index.scss +46 -0
  308. package/components/oxy-table-col/oxy-table-col.vue +149 -0
  309. package/components/oxy-table-col/types.ts +54 -0
  310. package/components/oxy-tabs/index.scss +299 -0
  311. package/components/oxy-tabs/oxy-tabs.vue +443 -0
  312. package/components/oxy-tabs/types.ts +107 -0
  313. package/components/oxy-tag/index.scss +115 -0
  314. package/components/oxy-tag/oxy-tag.vue +148 -0
  315. package/components/oxy-tag/types.ts +81 -0
  316. package/components/oxy-text/index.scss +37 -0
  317. package/components/oxy-text/oxy-text.vue +139 -0
  318. package/components/oxy-text/types.ts +98 -0
  319. package/components/oxy-textarea/index.scss +340 -0
  320. package/components/oxy-textarea/oxy-textarea.vue +296 -0
  321. package/components/oxy-textarea/placeholder.scss +20 -0
  322. package/components/oxy-textarea/types.ts +288 -0
  323. package/components/oxy-toast/index.scss +75 -0
  324. package/components/oxy-toast/index.ts +92 -0
  325. package/components/oxy-toast/oxy-toast.vue +198 -0
  326. package/components/oxy-toast/types.ts +181 -0
  327. package/components/oxy-tooltip/index.scss +66 -0
  328. package/components/oxy-tooltip/oxy-tooltip.vue +141 -0
  329. package/components/oxy-tooltip/types.ts +107 -0
  330. package/components/oxy-transition/index.scss +95 -0
  331. package/components/oxy-transition/oxy-transition.vue +232 -0
  332. package/components/oxy-transition/types.ts +98 -0
  333. package/components/oxy-upload/index.scss +175 -0
  334. package/components/oxy-upload/oxy-upload.vue +673 -0
  335. package/components/oxy-upload/types.ts +391 -0
  336. package/components/oxy-video-preview/index.scss +34 -0
  337. package/components/oxy-video-preview/oxy-video-preview.vue +72 -0
  338. package/components/oxy-video-preview/types.ts +23 -0
  339. package/components/oxy-watermark/index.scss +18 -0
  340. package/components/oxy-watermark/oxy-watermark.vue +486 -0
  341. package/components/oxy-watermark/types.ts +76 -0
  342. package/dayjs/constant.js +26 -0
  343. package/dayjs/index.d.ts +430 -0
  344. package/dayjs/index.js +542 -0
  345. package/dayjs/locale/en.js +13 -0
  346. package/dayjs/utils.js +59 -0
  347. package/global.d.ts +101 -0
  348. package/index.ts +12 -0
  349. package/locale/index.ts +32 -0
  350. package/locale/lang/ar-SA.ts +133 -0
  351. package/locale/lang/en-US.ts +133 -0
  352. package/locale/lang/zh-CN.ts +137 -0
  353. package/package.json +1 -0
  354. package/tags.json +1 -0
  355. package/web-types.json +1 -0
@@ -0,0 +1,664 @@
1
+ <template>
2
+ <!-- 绘制的图片canvas -->
3
+ <view v-if="modelValue" :class="`oxy-img-cropper ${customClass}`" :style="customStyle" @touchmove="preventTouchMove">
4
+ <!-- 展示在用户面前的裁剪框 -->
5
+ <view class="oxy-img-cropper__wrapper">
6
+ <!-- 画出裁剪框 -->
7
+ <view class="oxy-img-cropper__cut">
8
+ <!-- 上方阴影块 -->
9
+ <view :class="`oxy-img-cropper__cut--top ${IS_TOUCH_END ? '' : 'is-hightlight'}`" :style="`height: ${cutTop}px;`"></view>
10
+ <view class="oxy-img-cropper__cut--middle" :style="`height: ${cutHeight}px;`">
11
+ <!-- 左侧阴影块 -->
12
+ <view
13
+ :class="`oxy-img-cropper__cut--left ${IS_TOUCH_END ? '' : 'is-hightlight'}`"
14
+ :style="`width: ${cutLeft}px; height: ${cutHeight}px;`"
15
+ ></view>
16
+ <!-- 裁剪框 -->
17
+ <view class="oxy-img-cropper__cut--body" :style="`width: ${cutWidth}px; height: ${cutHeight}px;`">
18
+ <!-- 内部网格线 -->
19
+ <view class="is-gridlines-x"></view>
20
+ <view class="is-gridlines-y"></view>
21
+ <!-- 裁剪窗体四个对角 -->
22
+ <view class="is-left-top"></view>
23
+ <view class="is-left-bottom"></view>
24
+ <view class="is-right-top"></view>
25
+ <view class="is-right-bottom"></view>
26
+ </view>
27
+ <!-- 右侧阴影块 -->
28
+ <view :class="`oxy-img-cropper__cut--right ${IS_TOUCH_END ? '' : 'is-hightlight'}`"></view>
29
+ </view>
30
+
31
+ <!-- 底部阴影块 -->
32
+ <view :class="`oxy-img-cropper__cut--bottom ${IS_TOUCH_END ? '' : 'is-hightlight'}`"></view>
33
+ </view>
34
+ <!-- 展示的传过来的图片: 控制图片的旋转角度(rotate)、缩放程度(imgScale)、移动位置(translate) -->
35
+ <image
36
+ :prop="isAnimation"
37
+ :change:prop="animation ? animation.setAnimation : ''"
38
+ class="oxy-img-cropper__img"
39
+ :src="imgSrc"
40
+ :style="imageStyle"
41
+ :lazy-load="false"
42
+ @touchstart="handleImgTouchStart"
43
+ @touchmove="handleImgTouchMove"
44
+ @touchend="handleImgTouchEnd"
45
+ @error="handleImgLoadError"
46
+ @load="handleImgLoaded"
47
+ />
48
+ </view>
49
+ <!-- 绘制的图片canvas -->
50
+ <canvas
51
+ :canvas-id="canvasId"
52
+ :id="canvasId"
53
+ class="oxy-img-cropper__canvas"
54
+ :disable-scroll="true"
55
+ :style="`width: ${Number(canvasWidth) * canvasScale}px; height: ${Number(canvasHeight) * canvasScale}px;`"
56
+ />
57
+ <!-- 下方按钮 -->
58
+ <view class="oxy-img-cropper__footer">
59
+ <oxy-icon custom-class="oxy-img-cropper__rotate" v-if="!disabledRotate" name="rotate" @click="handleRotate"></oxy-icon>
60
+ <view class="oxy-img-cropper__footer--button">
61
+ <view class="is-cancel" @click="handleCancel">{{ cancelButtonText || translate('cancel') }}</view>
62
+ <oxy-button size="small" :custom-style="buttonStyle" @click="handleConfirm">{{ confirmButtonText || translate('confirm') }}</oxy-button>
63
+ </view>
64
+ </view>
65
+ </view>
66
+ </template>
67
+
68
+ <script lang="ts">
69
+ export default {
70
+ name: 'oxy-img-cropper',
71
+ options: {
72
+ virtualHost: true,
73
+ addGlobalClass: true,
74
+ styleIsolation: 'shared'
75
+ }
76
+ }
77
+ </script>
78
+
79
+ <script lang="ts" setup>
80
+ import OxyIcon from '../oxy-icon/oxy-icon.vue'
81
+ import OxyButton from '../oxy-button/oxy-button.vue'
82
+ import { computed, getCurrentInstance, ref, watch } from 'vue'
83
+ import { addUnit, objToStyle, uuid } from '../common/util'
84
+ import { useTranslate } from '../composables/useTranslate'
85
+ import { imgCropperProps, type ImgCropperExpose } from './types'
86
+
87
+ const canvasId = ref<string>(`cropper${uuid()}`) // canvas 组件的唯一标识符
88
+
89
+ // 延时动画设置
90
+ let CHANGE_TIME: any | null = null
91
+ // 移动节流
92
+ let MOVE_THROTTLE: any | null = null
93
+ // 节流标志
94
+ let MOVE_THROTTLE_FLAG: boolean = true
95
+ // 图片设置尺寸,此值不变(记录最初设定的尺寸)
96
+ let INIT_IMGWIDTH: null | number | string = null
97
+ // 图片设置尺寸,此值不变(记录最初设定的尺寸)
98
+ let INIT_IMGHEIGHT: null | number | string = null
99
+ // 顶部裁剪框占比
100
+ const TOP_PERCENT = 0.85
101
+
102
+ const props = defineProps(imgCropperProps)
103
+ const emit = defineEmits(['imgloaded', 'imgloaderror', 'cancel', 'confirm', 'update:modelValue'])
104
+
105
+ const { translate } = useTranslate('img-cropper')
106
+
107
+ // 旋转角度
108
+ const imgAngle = ref<number>(0)
109
+ // 是否开启动画
110
+ const isAnimation = ref<boolean>(false)
111
+ // #ifdef MP-ALIPAY || APP-PLUS || H5
112
+ // hack 避免钉钉小程序、支付宝小程序、app抛出相关异常
113
+ const animation: any = null
114
+ // #endif
115
+
116
+ // 裁剪框的宽高
117
+ const picWidth = ref<number>(0)
118
+ const picHeight = ref<number>(0)
119
+ const cutWidth = ref<number>(0)
120
+ const cutHeight = ref<number>(0)
121
+ const offset = ref<number>(20)
122
+ // 裁剪框的距顶距左
123
+ const cutLeft = ref<number>(0)
124
+ const cutTop = ref<number>(0)
125
+ // canvas最终成像宽高
126
+ const canvasWidth = ref<string | number>('')
127
+ const canvasHeight = ref<string | number>('')
128
+ const canvasScale = ref<number>(2)
129
+ // 当前缩放大小
130
+ const imgScale = ref<number>(1)
131
+ // // 图片宽高
132
+ // imgWidth: null,
133
+ // imgHeight: null,
134
+ // 图片中心轴点距左的距离
135
+ const imgLeft = ref<number>(uni.getSystemInfoSync().windowWidth / 2)
136
+ const imgTop = ref<number>((uni.getSystemInfoSync().windowHeight / 2) * TOP_PERCENT)
137
+
138
+ const imgInfo = ref<UniApp.GetImageInfoSuccessData | null>(null)
139
+ const info = ref<UniApp.GetSystemInfoResult>(uni.getSystemInfoSync())
140
+
141
+ // 是否移动中设置 同时控制背景颜色是否高亮
142
+ const IS_TOUCH_END = ref<boolean>(true)
143
+ // 记录移动中的双指位置 [0][1]分别代表两根手指 [1]做待用参数
144
+ const movingPosRecord = ref<Record<string, string | number>[]>([
145
+ {
146
+ x: '',
147
+ y: ''
148
+ },
149
+ {
150
+ x: '',
151
+ y: ''
152
+ }
153
+ ])
154
+ // 双指缩放时 两个坐标点斜边长度
155
+ const fingerDistance = ref<string | number>('')
156
+
157
+ const ctx = ref<UniApp.CanvasContext | null>(null)
158
+
159
+ const { proxy } = getCurrentInstance() as any
160
+
161
+ watch(
162
+ () => props.modelValue,
163
+ (newValue) => {
164
+ if (newValue) {
165
+ INIT_IMGWIDTH = props.imgWidth
166
+ INIT_IMGHEIGHT = props.imgHeight
167
+ info.value = uni.getSystemInfoSync()
168
+
169
+ // 根据aspectRatio计算裁剪框尺寸
170
+ const [widthRatio, heightRatio] = props.aspectRatio.split(':').map(Number)
171
+ const tempCutWidth = info.value.windowWidth - offset.value * 2
172
+ const tempCutHeight = (tempCutWidth * heightRatio) / widthRatio
173
+
174
+ cutWidth.value = tempCutWidth
175
+ cutHeight.value = tempCutHeight
176
+ cutTop.value = (info.value.windowHeight * TOP_PERCENT - tempCutHeight) / 2
177
+ cutLeft.value = offset.value
178
+
179
+ canvasScale.value = props.exportScale
180
+ canvasHeight.value = tempCutHeight
181
+ canvasWidth.value = tempCutWidth
182
+
183
+ // 根据开发者设置的图片目标尺寸计算实际尺寸
184
+ initImageSize()
185
+ // 初始化canvas
186
+ initCanvas()
187
+ // 加载图片
188
+ props.imgSrc && loadImg()
189
+ } else {
190
+ resetImg()
191
+ }
192
+ },
193
+ {
194
+ deep: true,
195
+ immediate: true
196
+ }
197
+ )
198
+
199
+ watch(
200
+ () => props.imgSrc,
201
+ (newValue) => {
202
+ newValue && loadImg()
203
+ },
204
+ {
205
+ deep: true,
206
+ immediate: true
207
+ }
208
+ )
209
+
210
+ watch(
211
+ () => imgAngle.value,
212
+ (newValue) => {
213
+ if (newValue % 90) {
214
+ imgAngle.value = Math.round(newValue / 90) * 90
215
+ }
216
+ },
217
+ {
218
+ deep: true,
219
+ immediate: true
220
+ }
221
+ )
222
+ watch(
223
+ () => isAnimation.value,
224
+ (newValue) => {
225
+ // 开启过渡300毫秒之后自动关闭
226
+ CHANGE_TIME && clearTimeout(CHANGE_TIME)
227
+ if (newValue) {
228
+ CHANGE_TIME = setTimeout(() => {
229
+ revertIsAnimation(false)
230
+ clearTimeout(CHANGE_TIME)
231
+ }, 300)
232
+ }
233
+ },
234
+ {
235
+ deep: true,
236
+ immediate: true
237
+ }
238
+ )
239
+
240
+ const buttonStyle = computed(() => {
241
+ const style: Record<string, string | number> = {
242
+ position: 'absolute',
243
+ right: 0,
244
+ // height: 32px;
245
+ width: '56px',
246
+ 'border-radius': '16px',
247
+ 'font-size': '16px'
248
+ }
249
+
250
+ return objToStyle(style)
251
+ })
252
+
253
+ const imageStyle = computed(() => {
254
+ const style: Record<string, string | number> = {
255
+ width: picWidth.value ? addUnit(picWidth.value) : 'auto',
256
+ height: picHeight.value ? addUnit(picHeight.value) : 'auto',
257
+ transform: `translate(${addUnit(imgLeft.value - picWidth.value / 2)}, ${addUnit(imgTop.value - picHeight.value / 2)}) scale(${
258
+ imgScale.value
259
+ }) rotate(${imgAngle.value}deg)`,
260
+ 'transition-duration': (isAnimation.value ? 0.4 : 0) + 's'
261
+ }
262
+ return objToStyle(style)
263
+ })
264
+
265
+ /**
266
+ * 逆转是否使用动画
267
+ */
268
+ function revertIsAnimation(animation: boolean | { value: boolean }) {
269
+ if (typeof animation === 'boolean') {
270
+ isAnimation.value = animation
271
+ } else {
272
+ isAnimation.value = animation.value
273
+ }
274
+ }
275
+
276
+ /**
277
+ * 控制旋转角度
278
+ * @param angle 角度
279
+ */
280
+ function setRoate(angle: number) {
281
+ if (!angle || props.disabledRotate) return
282
+ revertIsAnimation(true)
283
+ imgAngle.value = angle
284
+
285
+ // 重新计算缩放比例
286
+ let tempPicWidth = picWidth.value
287
+ let tempPicHeight = picHeight.value
288
+
289
+ // 旋转后宽高互换
290
+ if ((angle / 90) % 2) {
291
+ tempPicWidth = picHeight.value
292
+ tempPicHeight = picWidth.value
293
+ }
294
+
295
+ // 计算新的缩放比例
296
+ const widthRatio = cutWidth.value / tempPicWidth
297
+ const heightRatio = cutHeight.value / tempPicHeight
298
+ imgScale.value = Math.max(widthRatio, heightRatio)
299
+
300
+ // 检测边缘位置
301
+ detectImgPosIsEdge()
302
+ }
303
+
304
+ /**
305
+ * 初始化图片的大小和角度以及距离
306
+ */
307
+ function resetImg() {
308
+ const { windowHeight, windowWidth } = uni.getSystemInfoSync()
309
+ imgScale.value = 1
310
+ imgAngle.value = 0
311
+ imgLeft.value = windowWidth / 2
312
+ imgTop.value = (windowHeight / 2) * TOP_PERCENT
313
+ }
314
+
315
+ /**
316
+ * 加载图片资源文件,并初始化裁剪框内图片信息
317
+ */
318
+ function loadImg() {
319
+ if (!props.imgSrc) return
320
+
321
+ uni.getImageInfo({
322
+ src: props.imgSrc,
323
+ success: (res) => {
324
+ // 存储img图片信息
325
+ imgInfo.value = res
326
+ // 计算最后图片尺寸
327
+ computeImgSize()
328
+ // 初始化尺寸
329
+ resetImg()
330
+ },
331
+ fail: () => {
332
+ // this.setData({ imgSrc: '' })
333
+ }
334
+ })
335
+ }
336
+
337
+ /**
338
+ * 设置图片尺寸,使其短边完全显示并填满裁剪框
339
+ */
340
+ function computeImgSize() {
341
+ let tempPicWidth: number = picWidth.value
342
+ let tempPicHeight: number = picHeight.value
343
+
344
+ if (!INIT_IMGHEIGHT && !INIT_IMGWIDTH) {
345
+ // 计算图片与裁剪框的宽高比
346
+ const imgRatio = imgInfo.value!.width / imgInfo.value!.height
347
+ const cropRatio = cutWidth.value / cutHeight.value
348
+
349
+ if (imgRatio > cropRatio) {
350
+ // 图片更宽,以高度为准
351
+ tempPicHeight = cutHeight.value
352
+ tempPicWidth = tempPicHeight * imgRatio
353
+ } else {
354
+ // 图片更高,以宽度为准
355
+ tempPicWidth = cutWidth.value
356
+ tempPicHeight = tempPicWidth / imgRatio
357
+ }
358
+ } else if (INIT_IMGHEIGHT && !INIT_IMGWIDTH) {
359
+ tempPicHeight = Number(INIT_IMGHEIGHT)
360
+ tempPicWidth = (imgInfo.value!.width / imgInfo.value!.height) * tempPicHeight
361
+ } else if ((!INIT_IMGHEIGHT && INIT_IMGWIDTH) || (INIT_IMGHEIGHT && INIT_IMGWIDTH)) {
362
+ tempPicWidth = Number(INIT_IMGWIDTH)
363
+ tempPicHeight = (imgInfo.value!.height / imgInfo.value!.width) * tempPicWidth
364
+ }
365
+
366
+ // 确保计算后的尺寸至少有一边等于裁剪框尺寸
367
+ const widthRatio = cutWidth.value / tempPicWidth
368
+ const heightRatio = cutHeight.value / tempPicHeight
369
+ const scale = Math.max(widthRatio, heightRatio)
370
+
371
+ picWidth.value = tempPicWidth
372
+ picHeight.value = tempPicHeight
373
+ // 设置初始缩放以适应裁剪框
374
+ imgScale.value = scale
375
+ }
376
+
377
+ /**
378
+ * canvas 初始化
379
+ */
380
+ function initCanvas() {
381
+ if (!ctx.value) {
382
+ ctx.value = uni.createCanvasContext(canvasId.value, proxy)
383
+ }
384
+ }
385
+
386
+ /**
387
+ * 图片初始化,处理宽高特殊单位
388
+ */
389
+ function initImageSize() {
390
+ // 处理宽高特殊单位 %>px
391
+ if (INIT_IMGWIDTH && typeof INIT_IMGWIDTH === 'string' && INIT_IMGWIDTH.indexOf('%') !== -1) {
392
+ const width: string = INIT_IMGWIDTH.replace('%', '')
393
+ INIT_IMGWIDTH = (info.value.windowWidth / 100) * Number(width)
394
+ picWidth.value = INIT_IMGWIDTH
395
+ } else if (INIT_IMGWIDTH && typeof INIT_IMGWIDTH === 'number') {
396
+ picWidth.value = INIT_IMGWIDTH
397
+ }
398
+ if (INIT_IMGHEIGHT && typeof INIT_IMGHEIGHT === 'string' && INIT_IMGHEIGHT.indexOf('%') !== -1) {
399
+ const height = (props.imgHeight as string).replace('%', '')
400
+ // INIT_IMGHEIGHT = this.data.imgHeight = (info.value.windowHeight / 100) * Number(height)
401
+ INIT_IMGHEIGHT = (info.value.windowHeight / 100) * Number(height)
402
+ picWidth.value = INIT_IMGHEIGHT
403
+ } else if (INIT_IMGHEIGHT && typeof INIT_IMGHEIGHT === 'number') {
404
+ picWidth.value = Number(INIT_IMGWIDTH)
405
+ }
406
+ }
407
+
408
+ /**
409
+ * 图片拖动边缘检测:检测移动或缩放时 是否触碰到图片边缘位置
410
+ */
411
+ function detectImgPosIsEdge(scale?: number) {
412
+ const currentScale = scale || imgScale.value
413
+ let currentImgLeft = imgLeft.value
414
+ let currentImgTop = imgTop.value
415
+ let currentPicWidth = picWidth.value
416
+ let currentPicHeight = picHeight.value
417
+
418
+ // 翻转后宽高切换
419
+ if ((imgAngle.value / 90) % 2) {
420
+ currentPicWidth = picHeight.value
421
+ currentPicHeight = picWidth.value
422
+ }
423
+ // 左
424
+ currentImgLeft =
425
+ (currentPicWidth * currentScale) / 2 + cutLeft.value >= currentImgLeft ? currentImgLeft : (currentPicWidth * imgScale.value) / 2 + cutLeft.value
426
+ // 右
427
+ currentImgLeft =
428
+ cutLeft.value + cutWidth.value - (currentPicWidth * currentScale) / 2 <= currentImgLeft
429
+ ? currentImgLeft
430
+ : cutLeft.value + cutWidth.value - (currentPicWidth * currentScale) / 2
431
+ // 上
432
+ currentImgTop =
433
+ (currentPicHeight * currentScale) / 2 + cutTop.value >= currentImgTop ? currentImgTop : (currentPicHeight * currentScale) / 2 + cutTop.value
434
+ // 下
435
+ currentImgTop =
436
+ cutTop.value + cutHeight.value - (currentPicHeight * currentScale) / 2 <= currentImgTop
437
+ ? currentImgTop
438
+ : cutTop.value + cutHeight.value - (currentPicHeight * currentScale) / 2
439
+
440
+ imgScale.value = currentScale
441
+ imgTop.value = currentImgTop
442
+ imgLeft.value = currentImgLeft
443
+ }
444
+
445
+ /**
446
+ * 缩放边缘检测:检测移动或缩放时 是否触碰到图片边缘位置
447
+ */
448
+ function detectImgScaleIsEdge() {
449
+ let tempPicWidth = picWidth.value
450
+ let tempPicHeight = picHeight.value
451
+ let tempImgScale = imgScale.value
452
+
453
+ // 翻转后宽高切换
454
+ if ((imgAngle.value / 90) % 2) {
455
+ tempPicWidth = picHeight.value
456
+ tempPicHeight = picWidth.value
457
+ }
458
+ if (tempPicWidth * tempImgScale < cutWidth.value) {
459
+ tempImgScale = cutWidth.value / tempPicWidth
460
+ }
461
+ if (tempPicHeight * tempImgScale < cutHeight.value) {
462
+ tempImgScale = cutHeight.value / tempPicHeight
463
+ }
464
+ detectImgPosIsEdge(tempImgScale)
465
+ }
466
+
467
+ /**
468
+ * 节流
469
+ */
470
+ function throttle() {
471
+ if (info.value.platform === 'android') {
472
+ MOVE_THROTTLE && clearTimeout(MOVE_THROTTLE)
473
+ MOVE_THROTTLE = setTimeout(() => {
474
+ MOVE_THROTTLE_FLAG = true
475
+ }, 1000 / 40)
476
+ } else {
477
+ !MOVE_THROTTLE_FLAG && (MOVE_THROTTLE_FLAG = true)
478
+ }
479
+ }
480
+
481
+ /**
482
+ * {图片区} 开始拖动
483
+ */
484
+ function handleImgTouchStart(event: any) {
485
+ // 如果处于在拖动中,背景为淡色展示全部,拖动结束则为 0.85 透明度
486
+ IS_TOUCH_END.value = false
487
+ if (event.touches.length === 1) {
488
+ // 单指拖动
489
+ movingPosRecord.value[0] = {
490
+ x: event.touches[0].clientX - imgLeft.value,
491
+ y: event.touches[0].clientY - imgTop.value
492
+ }
493
+ } else {
494
+ // 以两指为坐标点 做直角三角形 a2 + b2 = c2
495
+ const width = Math.abs(event.touches[1].clientX - event.touches[0].clientX)
496
+ const height = Math.abs(event.touches[1].clientY - event.touches[0].clientY)
497
+ fingerDistance.value = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2))
498
+ }
499
+ }
500
+
501
+ /**
502
+ * {图片区} 拖动中
503
+ */
504
+ function handleImgTouchMove(event: any) {
505
+ if (IS_TOUCH_END.value || !MOVE_THROTTLE_FLAG) return
506
+ // 节流
507
+ throttle()
508
+ if (event.touches.length === 1) {
509
+ // 单指拖动
510
+ const { x, y } = movingPosRecord.value[0]
511
+ const left = event.touches[0].clientX - Number(x)
512
+ const top = event.touches[0].clientY - Number(y)
513
+ imgLeft.value = left
514
+ imgTop.value = top
515
+ detectImgPosIsEdge()
516
+ } else {
517
+ // 以两指为坐标点 做直角三角形 a2 + b2 = c2
518
+ const width = Math.abs(event.touches[1].clientX - event.touches[0].clientX)
519
+ const height = Math.abs(event.touches[1].clientY - event.touches[0].clientY)
520
+ const hypotenuse = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2))
521
+ const scale = imgScale.value * (hypotenuse / Number(fingerDistance.value))
522
+ imgScale.value = Math.min(scale, props.maxScale)
523
+ detectImgScaleIsEdge()
524
+ fingerDistance.value = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2))
525
+ }
526
+ }
527
+
528
+ /**
529
+ * {图片区} 拖动结束
530
+ */
531
+ function handleImgTouchEnd() {
532
+ IS_TOUCH_END.value = true
533
+ }
534
+
535
+ /**
536
+ * 图片已加载完成
537
+ */
538
+ function handleImgLoaded(res: any) {
539
+ emit('imgloaded', res)
540
+ }
541
+
542
+ /**
543
+ * 图片加载失败
544
+ */
545
+ function handleImgLoadError(err: any) {
546
+ emit('imgloaderror', err)
547
+ }
548
+
549
+ /**
550
+ * 旋转图片
551
+ */
552
+ function handleRotate() {
553
+ setRoate(imgAngle.value - 90)
554
+ }
555
+
556
+ /**
557
+ * 取消裁剪图片
558
+ */
559
+ function handleCancel() {
560
+ emit('cancel')
561
+ emit('update:modelValue', false)
562
+ }
563
+
564
+ /**
565
+ * 完成裁剪
566
+ */
567
+ function handleConfirm() {
568
+ draw()
569
+ }
570
+
571
+ /**
572
+ * canvas 绘制图片输出成文件类型
573
+ */
574
+ function canvasToImage() {
575
+ const { fileType, quality, exportScale } = props
576
+ uni.canvasToTempFilePath(
577
+ {
578
+ width: cutWidth.value * exportScale,
579
+ height: Math.round(cutHeight.value * exportScale),
580
+ destWidth: cutWidth.value * exportScale,
581
+ destHeight: Math.round(cutHeight.value * exportScale),
582
+ fileType,
583
+ quality,
584
+ canvasId: canvasId.value,
585
+ success: (res: any) => {
586
+ const result = { tempFilePath: res.tempFilePath, width: cutWidth.value * exportScale, height: cutHeight.value * exportScale }
587
+ // #ifdef MP-DINGTALK
588
+ result.tempFilePath = res.filePath
589
+ // #endif
590
+ emit('confirm', result)
591
+ },
592
+ complete: () => {
593
+ emit('update:modelValue', false)
594
+ }
595
+ },
596
+ proxy
597
+ )
598
+ }
599
+
600
+ /**
601
+ * canvas绘制,用canvas模拟裁剪框 对根据图片当前的裁剪信息进行模拟
602
+ */
603
+ function draw() {
604
+ if (!props.imgSrc) return
605
+ const draw = () => {
606
+ // 图片真实大小
607
+ const width = picWidth.value * imgScale.value * props.exportScale
608
+ const height = picHeight.value * imgScale.value * props.exportScale
609
+ // 取裁剪框和图片的交集
610
+ const x = imgLeft.value - cutLeft.value
611
+ const y = imgTop.value - cutTop.value
612
+ // 如果直接使用canvas绘制的图片会有锯齿,因此需要*设备像素比
613
+ // 设置(x, y)设置图片在canvas中的位置
614
+ ctx.value!.translate(x * props.exportScale, y * props.exportScale)
615
+ // 设置 旋转角度
616
+ if (!props.disabledRotate) {
617
+ ctx.value!.rotate((imgAngle.value * Math.PI) / 180)
618
+ }
619
+ // drawImage 的 旋转是根据以当前图片的图片水平垂直方向为x、y轴,并在x y轴上移动
620
+ ctx.value!.drawImage(props.imgSrc, -width / 2, -height / 2, width, height)
621
+
622
+ ctx.value!.restore()
623
+
624
+ // 绘制图片
625
+ ctx.value!.draw(false, () => {
626
+ canvasToImage()
627
+ })
628
+ }
629
+
630
+ canvasHeight.value = cutHeight.value
631
+ canvasWidth.value = cutWidth.value
632
+ draw()
633
+ }
634
+ function preventTouchMove() {}
635
+
636
+ defineExpose<ImgCropperExpose>({
637
+ revertIsAnimation,
638
+ setRoate,
639
+ resetImg
640
+ })
641
+ </script>
642
+
643
+ <!-- #ifdef MP-WEIXIN || MP-QQ -->
644
+ <script module="animation" lang="wxs">
645
+
646
+ function setAnimation(newValue, oldValue, ownerInstance){
647
+ if (newValue) {
648
+ var id = ownerInstance.setTimeout(function() {
649
+ ownerInstance.callMethod('revertIsAnimation',{value:false})
650
+ ownerInstance.clearTimeout(id)
651
+ },300)
652
+ }
653
+
654
+ }
655
+
656
+ module.exports= {
657
+ setAnimation:setAnimation,
658
+ }
659
+ </script>
660
+ <!-- #endif -->
661
+
662
+ <style lang="scss" scoped>
663
+ @import './index.scss';
664
+ </style>