index.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  1. <template>
  2. <view class="container">
  3. <view class="page-body uni-content-info">
  4. <view class='cropper-content'>
  5. <view v-if="isShowImg" class="uni-corpper" :style="'width:'+cropperInitW+'px;height:'+cropperInitH+'px;background:#000'">
  6. <view class="uni-corpper-content" :style="'width:'+cropperW+'px;height:'+cropperH+'px;left:'+cropperL+'px;top:'+cropperT+'px'">
  7. <image :src="imageSrc" :style="'width:'+cropperW+'px;height:'+cropperH+'px'"></image>
  8. <view class="uni-corpper-crop-box" @touchstart.stop="contentStartMove" @touchmove.stop="contentMoveing" @touchend.stop="contentTouchEnd"
  9. :style="'left:'+cutL+'px;top:'+cutT+'px;right:'+cutR+'px;bottom:'+cutB+'px'">
  10. <view class="uni-cropper-view-box">
  11. <view class="uni-cropper-dashed-h"></view>
  12. <view class="uni-cropper-dashed-v"></view>
  13. <view class="uni-cropper-line-t" data-drag="top" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
  14. <view class="uni-cropper-line-r" data-drag="right" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
  15. <view class="uni-cropper-line-b" data-drag="bottom" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
  16. <view class="uni-cropper-line-l" data-drag="left" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
  17. <view class="uni-cropper-point point-t" data-drag="top" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
  18. <view class="uni-cropper-point point-tr" data-drag="topTight"></view>
  19. <view class="uni-cropper-point point-r" data-drag="right" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
  20. <view class="uni-cropper-point point-rb" data-drag="rightBottom" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
  21. <view class="uni-cropper-point point-b" data-drag="bottom" @touchstart.stop="dragStart" @touchmove.stop="dragMove" @touchend.stop="dragEnd"></view>
  22. <view class="uni-cropper-point point-bl" data-drag="bottomLeft"></view>
  23. <view class="uni-cropper-point point-l" data-drag="left" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
  24. <view class="uni-cropper-point point-lt" data-drag="leftTop"></view>
  25. </view>
  26. </view>
  27. </view>
  28. </view>
  29. </view>
  30. <view class='cropper-config'>
  31. <button type="primary reverse" @click="getImage" style='margin-top: 30rpx;'> 选择头像 </button>
  32. <button type="warn" @click="getImageInfo" style='margin-top: 30rpx;'> 提交 </button>
  33. </view>
  34. <canvas canvas-id="myCanvas" :style="'position:absolute;border: 1px solid red; width:'+imageW+'px;height:'+imageH+'px;top:-9999px;left:-9999px;'"></canvas>
  35. </view>
  36. </view>
  37. </template>
  38. <script>
  39. import config from '@/config'
  40. import store from "@/store"
  41. import { uploadAvatar } from "@/api/system/user"
  42. const baseUrl = config.baseUrl
  43. let sysInfo = uni.getSystemInfoSync()
  44. let SCREEN_WIDTH = sysInfo.screenWidth
  45. let PAGE_X, // 手按下的x位置
  46. PAGE_Y, // 手按下y的位置
  47. PR = sysInfo.pixelRatio, // dpi
  48. T_PAGE_X, // 手移动的时候x的位置
  49. T_PAGE_Y, // 手移动的时候Y的位置
  50. CUT_L, // 初始化拖拽元素的left值
  51. CUT_T, // 初始化拖拽元素的top值
  52. CUT_R, // 初始化拖拽元素的
  53. CUT_B, // 初始化拖拽元素的
  54. CUT_W, // 初始化拖拽元素的宽度
  55. CUT_H, // 初始化拖拽元素的高度
  56. IMG_RATIO, // 图片比例
  57. IMG_REAL_W, // 图片实际的宽度
  58. IMG_REAL_H, // 图片实际的高度
  59. DRAFG_MOVE_RATIO = 1, //移动时候的比例,
  60. INIT_DRAG_POSITION = 100, // 初始化屏幕宽度和裁剪区域的宽度之差,用于设置初始化裁剪的宽度
  61. DRAW_IMAGE_W = sysInfo.screenWidth // 设置生成的图片宽度
  62. export default {
  63. /**
  64. * 页面的初始数据
  65. */
  66. data() {
  67. return {
  68. imageurl: store.getters.avatar,
  69. avatarimg:require("@/static/images/mine/profile.png"),
  70. imageSrc:'',
  71. isShowImg: false,
  72. // 初始化的宽高
  73. cropperInitW: SCREEN_WIDTH,
  74. cropperInitH: SCREEN_WIDTH,
  75. // 动态的宽高
  76. cropperW: SCREEN_WIDTH,
  77. cropperH: SCREEN_WIDTH,
  78. // 动态的left top值
  79. cropperL: 0,
  80. cropperT: 0,
  81. transL: 0,
  82. transT: 0,
  83. // 图片缩放值
  84. scaleP: 0,
  85. imageW: 0,
  86. imageH: 0,
  87. // 裁剪框 宽高
  88. cutL: 0,
  89. cutT: 0,
  90. cutB: SCREEN_WIDTH,
  91. cutR: '100%',
  92. qualityWidth: DRAW_IMAGE_W,
  93. innerAspectRadio: DRAFG_MOVE_RATIO
  94. }
  95. },
  96. /**
  97. * 生命周期函数--监听页面初次渲染完成
  98. */
  99. onReady: function () {
  100. this.loadImage()
  101. },
  102. onLoad:function(){
  103. this.imageSrc=this.imageurl?this.imageurl:this.avatarimg
  104. },
  105. methods: {
  106. setData: function (obj) {
  107. let that = this
  108. Object.keys(obj).forEach(function (key) {
  109. that.$set(that.$data, key, obj[key])
  110. })
  111. },
  112. getImage: function () {
  113. var _this = this
  114. uni.chooseImage({
  115. success: function (res) {
  116. _this.setData({
  117. imageSrc: res.tempFilePaths[0],
  118. })
  119. _this.loadImage()
  120. },
  121. })
  122. },
  123. loadImage: function () {
  124. var _this = this
  125. uni.getImageInfo({
  126. src: _this.imageSrc,
  127. success: function success(res) {
  128. IMG_RATIO = 1 / 1
  129. if (IMG_RATIO >= 1) {
  130. IMG_REAL_W = SCREEN_WIDTH
  131. IMG_REAL_H = SCREEN_WIDTH / IMG_RATIO
  132. } else {
  133. IMG_REAL_W = SCREEN_WIDTH * IMG_RATIO
  134. IMG_REAL_H = SCREEN_WIDTH
  135. }
  136. let minRange = IMG_REAL_W > IMG_REAL_H ? IMG_REAL_W : IMG_REAL_H
  137. INIT_DRAG_POSITION = minRange > INIT_DRAG_POSITION ? INIT_DRAG_POSITION : minRange
  138. // 根据图片的宽高显示不同的效果 保证图片可以正常显示
  139. if (IMG_RATIO >= 1) {
  140. let cutT = Math.ceil((SCREEN_WIDTH / IMG_RATIO - (SCREEN_WIDTH / IMG_RATIO - INIT_DRAG_POSITION)) / 2)
  141. let cutB = cutT
  142. let cutL = Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH + INIT_DRAG_POSITION) / 2)
  143. let cutR = cutL
  144. _this.setData({
  145. cropperW: SCREEN_WIDTH,
  146. cropperH: SCREEN_WIDTH / IMG_RATIO,
  147. // 初始化left right
  148. cropperL: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH) / 2),
  149. cropperT: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH / IMG_RATIO) / 2),
  150. cutL: cutL,
  151. cutT: cutT,
  152. cutR: cutR,
  153. cutB: cutB,
  154. // 图片缩放值
  155. imageW: IMG_REAL_W,
  156. imageH: IMG_REAL_H,
  157. scaleP: IMG_REAL_W / SCREEN_WIDTH,
  158. qualityWidth: DRAW_IMAGE_W,
  159. innerAspectRadio: IMG_RATIO
  160. })
  161. } else {
  162. let cutL = Math.ceil((SCREEN_WIDTH * IMG_RATIO - (SCREEN_WIDTH * IMG_RATIO)) / 2)
  163. let cutR = cutL
  164. let cutT = Math.ceil((SCREEN_WIDTH - INIT_DRAG_POSITION) / 2)
  165. let cutB = cutT
  166. _this.setData({
  167. cropperW: SCREEN_WIDTH * IMG_RATIO,
  168. cropperH: SCREEN_WIDTH,
  169. // 初始化left right
  170. cropperL: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH * IMG_RATIO) / 2),
  171. cropperT: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH) / 2),
  172. cutL: cutL,
  173. cutT: cutT,
  174. cutR: cutR,
  175. cutB: cutB,
  176. // 图片缩放值
  177. imageW: IMG_REAL_W,
  178. imageH: IMG_REAL_H,
  179. scaleP: IMG_REAL_W / SCREEN_WIDTH,
  180. qualityWidth: DRAW_IMAGE_W,
  181. innerAspectRadio: IMG_RATIO
  182. })
  183. }
  184. _this.setData({
  185. isShowImg: true
  186. })
  187. uni.hideLoading()
  188. }
  189. })
  190. },
  191. // 拖动时候触发的touchStart事件
  192. contentStartMove(e) {
  193. PAGE_X = e.touches[0].pageX
  194. PAGE_Y = e.touches[0].pageY
  195. },
  196. // 拖动时候触发的touchMove事件
  197. contentMoveing(e) {
  198. var _this = this
  199. var dragLengthX = (PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
  200. var dragLengthY = (PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
  201. // 左移
  202. if (dragLengthX > 0) {
  203. if (this.cutL - dragLengthX < 0) dragLengthX = this.cutL
  204. } else {
  205. if (this.cutR + dragLengthX < 0) dragLengthX = -this.cutR
  206. }
  207. if (dragLengthY > 0) {
  208. if (this.cutT - dragLengthY < 0) dragLengthY = this.cutT
  209. } else {
  210. if (this.cutB + dragLengthY < 0) dragLengthY = -this.cutB
  211. }
  212. this.setData({
  213. cutL: this.cutL - dragLengthX,
  214. cutT: this.cutT - dragLengthY,
  215. cutR: this.cutR + dragLengthX,
  216. cutB: this.cutB + dragLengthY
  217. })
  218. PAGE_X = e.touches[0].pageX
  219. PAGE_Y = e.touches[0].pageY
  220. },
  221. contentTouchEnd() {
  222. },
  223. // 获取图片
  224. getImageInfo() {
  225. var _this = this
  226. uni.showLoading({
  227. title: '图片生成中...',
  228. })
  229. // 将图片写入画布
  230. const ctx = uni.createCanvasContext('myCanvas')
  231. ctx.drawImage(_this.imageSrc, 0, 0, IMG_REAL_W, IMG_REAL_H)
  232. ctx.draw(true, () => {
  233. // 获取画布要裁剪的位置和宽度 均为百分比 * 画布中图片的宽度 保证了在微信小程序中裁剪的图片模糊 位置不对的问题 canvasT = (_this.cutT / _this.cropperH) * (_this.imageH / pixelRatio)
  234. var canvasW = ((_this.cropperW - _this.cutL - _this.cutR) / _this.cropperW) * IMG_REAL_W
  235. var canvasH = ((_this.cropperH - _this.cutT - _this.cutB) / _this.cropperH) * IMG_REAL_H
  236. var canvasL = (_this.cutL / _this.cropperW) * IMG_REAL_W
  237. var canvasT = (_this.cutT / _this.cropperH) * IMG_REAL_H
  238. uni.canvasToTempFilePath({
  239. x: canvasL,
  240. y: canvasT,
  241. width: canvasW,
  242. height: canvasH,
  243. destWidth: canvasW,
  244. destHeight: canvasH,
  245. quality: 0.5,
  246. canvasId: 'myCanvas',
  247. success: function (res) {
  248. uni.hideLoading()
  249. let data = {name: 'avatarfile', filePath: res.tempFilePath}
  250. uploadAvatar(data).then(response => {
  251. store.commit('SET_AVATAR', baseUrl + response.imgUrl)
  252. uni.showToast({ title: "修改成功", icon: 'success' })
  253. uni.navigateBack()
  254. })
  255. }
  256. })
  257. })
  258. },
  259. // 设置大小的时候触发的touchStart事件
  260. dragStart(e) {
  261. T_PAGE_X = e.touches[0].pageX
  262. T_PAGE_Y = e.touches[0].pageY
  263. CUT_L = this.cutL
  264. CUT_R = this.cutR
  265. CUT_B = this.cutB
  266. CUT_T = this.cutT
  267. },
  268. // 设置大小的时候触发的touchMove事件
  269. dragMove(e) {
  270. var _this = this
  271. var dragType = e.target.dataset.drag
  272. switch (dragType) {
  273. case 'right':
  274. var dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
  275. if (CUT_R + dragLength < 0) dragLength = -CUT_R
  276. this.setData({
  277. cutR: CUT_R + dragLength
  278. })
  279. break
  280. case 'left':
  281. var dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
  282. if (CUT_L - dragLength < 0) dragLength = CUT_L
  283. if ((CUT_L - dragLength) > (this.cropperW - this.cutR)) dragLength = CUT_L - (this.cropperW - this.cutR)
  284. this.setData({
  285. cutL: CUT_L - dragLength
  286. })
  287. break
  288. case 'top':
  289. var dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
  290. if (CUT_T - dragLength < 0) dragLength = CUT_T
  291. if ((CUT_T - dragLength) > (this.cropperH - this.cutB)) dragLength = CUT_T - (this.cropperH - this.cutB)
  292. this.setData({
  293. cutT: CUT_T - dragLength
  294. })
  295. break
  296. case 'bottom':
  297. var dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
  298. if (CUT_B + dragLength < 0) dragLength = -CUT_B
  299. this.setData({
  300. cutB: CUT_B + dragLength
  301. })
  302. break
  303. case 'rightBottom':
  304. var dragLengthX = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
  305. var dragLengthY = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
  306. if (CUT_B + dragLengthY < 0) dragLengthY = -CUT_B
  307. if (CUT_R + dragLengthX < 0) dragLengthX = -CUT_R
  308. let cutB = CUT_B + dragLengthY
  309. let cutR = CUT_R + dragLengthX
  310. this.setData({
  311. cutB: cutB,
  312. cutR: cutR
  313. })
  314. break
  315. default:
  316. break
  317. }
  318. }
  319. }
  320. }
  321. </script>
  322. <style>
  323. /* pages/uni-cropper/index.wxss */
  324. .uni-content-info {
  325. /* position: fixed;
  326. top: 0;
  327. left: 0;
  328. right: 0;
  329. bottom: 0;
  330. display: block;
  331. align-items: center;
  332. flex-direction: column; */
  333. }
  334. .cropper-config {
  335. padding: 20rpx 40rpx;
  336. }
  337. .cropper-content {
  338. min-height: 750rpx;
  339. width: 100%;
  340. }
  341. .uni-corpper {
  342. position: relative;
  343. overflow: hidden;
  344. -webkit-user-select: none;
  345. -moz-user-select: none;
  346. -ms-user-select: none;
  347. user-select: none;
  348. -webkit-tap-highlight-color: transparent;
  349. -webkit-touch-callout: none;
  350. box-sizing: border-box;
  351. }
  352. .uni-corpper-content {
  353. position: relative;
  354. }
  355. .uni-corpper-content image {
  356. display: block;
  357. width: 100%;
  358. min-width: 0 !important;
  359. max-width: none !important;
  360. height: 100%;
  361. min-height: 0 !important;
  362. max-height: none !important;
  363. image-orientation: 0deg !important;
  364. margin: 0 auto;
  365. }
  366. /* 移动图片效果 */
  367. .uni-cropper-drag-box {
  368. position: absolute;
  369. top: 0;
  370. right: 0;
  371. bottom: 0;
  372. left: 0;
  373. cursor: move;
  374. background: rgba(0, 0, 0, 0.6);
  375. z-index: 1;
  376. }
  377. /* 内部的信息 */
  378. .uni-corpper-crop-box {
  379. position: absolute;
  380. background: rgba(255, 255, 255, 0.3);
  381. z-index: 2;
  382. }
  383. .uni-corpper-crop-box .uni-cropper-view-box {
  384. position: relative;
  385. display: block;
  386. width: 100%;
  387. height: 100%;
  388. overflow: visible;
  389. outline: 1rpx solid #69f;
  390. outline-color: rgba(102, 153, 255, .75)
  391. }
  392. /* 横向虚线 */
  393. .uni-cropper-dashed-h {
  394. position: absolute;
  395. top: 33.33333333%;
  396. left: 0;
  397. width: 100%;
  398. height: 33.33333333%;
  399. border-top: 1rpx dashed rgba(255, 255, 255, 0.5);
  400. border-bottom: 1rpx dashed rgba(255, 255, 255, 0.5);
  401. }
  402. /* 纵向虚线 */
  403. .uni-cropper-dashed-v {
  404. position: absolute;
  405. left: 33.33333333%;
  406. top: 0;
  407. width: 33.33333333%;
  408. height: 100%;
  409. border-left: 1rpx dashed rgba(255, 255, 255, 0.5);
  410. border-right: 1rpx dashed rgba(255, 255, 255, 0.5);
  411. }
  412. /* 四个方向的线 为了之后的拖动事件*/
  413. .uni-cropper-line-t {
  414. position: absolute;
  415. display: block;
  416. width: 100%;
  417. background-color: #69f;
  418. top: 0;
  419. left: 0;
  420. height: 1rpx;
  421. opacity: 0.1;
  422. cursor: n-resize;
  423. }
  424. .uni-cropper-line-t::before {
  425. content: '';
  426. position: absolute;
  427. top: 50%;
  428. right: 0rpx;
  429. width: 100%;
  430. -webkit-transform: translate3d(0, -50%, 0);
  431. transform: translate3d(0, -50%, 0);
  432. bottom: 0;
  433. height: 41rpx;
  434. background: transparent;
  435. z-index: 11;
  436. }
  437. .uni-cropper-line-r {
  438. position: absolute;
  439. display: block;
  440. background-color: #69f;
  441. top: 0;
  442. right: 0rpx;
  443. width: 1rpx;
  444. opacity: 0.1;
  445. height: 100%;
  446. cursor: e-resize;
  447. }
  448. .uni-cropper-line-r::before {
  449. content: '';
  450. position: absolute;
  451. top: 0;
  452. left: 50%;
  453. width: 41rpx;
  454. -webkit-transform: translate3d(-50%, 0, 0);
  455. transform: translate3d(-50%, 0, 0);
  456. bottom: 0;
  457. height: 100%;
  458. background: transparent;
  459. z-index: 11;
  460. }
  461. .uni-cropper-line-b {
  462. position: absolute;
  463. display: block;
  464. width: 100%;
  465. background-color: #69f;
  466. bottom: 0;
  467. left: 0;
  468. height: 1rpx;
  469. opacity: 0.1;
  470. cursor: s-resize;
  471. }
  472. .uni-cropper-line-b::before {
  473. content: '';
  474. position: absolute;
  475. top: 50%;
  476. right: 0rpx;
  477. width: 100%;
  478. -webkit-transform: translate3d(0, -50%, 0);
  479. transform: translate3d(0, -50%, 0);
  480. bottom: 0;
  481. height: 41rpx;
  482. background: transparent;
  483. z-index: 11;
  484. }
  485. .uni-cropper-line-l {
  486. position: absolute;
  487. display: block;
  488. background-color: #69f;
  489. top: 0;
  490. left: 0;
  491. width: 1rpx;
  492. opacity: 0.1;
  493. height: 100%;
  494. cursor: w-resize;
  495. }
  496. .uni-cropper-line-l::before {
  497. content: '';
  498. position: absolute;
  499. top: 0;
  500. left: 50%;
  501. width: 41rpx;
  502. -webkit-transform: translate3d(-50%, 0, 0);
  503. transform: translate3d(-50%, 0, 0);
  504. bottom: 0;
  505. height: 100%;
  506. background: transparent;
  507. z-index: 11;
  508. }
  509. .uni-cropper-point {
  510. width: 5rpx;
  511. height: 5rpx;
  512. background-color: #69f;
  513. opacity: .75;
  514. position: absolute;
  515. z-index: 3;
  516. }
  517. .point-t {
  518. top: -3rpx;
  519. left: 50%;
  520. margin-left: -3rpx;
  521. cursor: n-resize;
  522. }
  523. .point-tr {
  524. top: -3rpx;
  525. left: 100%;
  526. margin-left: -3rpx;
  527. cursor: n-resize;
  528. }
  529. .point-r {
  530. top: 50%;
  531. left: 100%;
  532. margin-left: -3rpx;
  533. margin-top: -3rpx;
  534. cursor: n-resize;
  535. }
  536. .point-rb {
  537. left: 100%;
  538. top: 100%;
  539. -webkit-transform: translate3d(-50%, -50%, 0);
  540. transform: translate3d(-50%, -50%, 0);
  541. cursor: n-resize;
  542. width: 36rpx;
  543. height: 36rpx;
  544. background-color: #69f;
  545. position: absolute;
  546. z-index: 1112;
  547. opacity: 1;
  548. }
  549. .point-b {
  550. left: 50%;
  551. top: 100%;
  552. margin-left: -3rpx;
  553. margin-top: -3rpx;
  554. cursor: n-resize;
  555. }
  556. .point-bl {
  557. left: 0%;
  558. top: 100%;
  559. margin-left: -3rpx;
  560. margin-top: -3rpx;
  561. cursor: n-resize;
  562. }
  563. .point-l {
  564. left: 0%;
  565. top: 50%;
  566. margin-left: -3rpx;
  567. margin-top: -3rpx;
  568. cursor: n-resize;
  569. }
  570. .point-lt {
  571. left: 0%;
  572. top: 0%;
  573. margin-left: -3rpx;
  574. margin-top: -3rpx;
  575. cursor: n-resize;
  576. }
  577. /* 裁剪框预览内容 */
  578. .uni-cropper-viewer {
  579. position: relative;
  580. width: 100%;
  581. height: 100%;
  582. overflow: hidden;
  583. }
  584. .uni-cropper-viewer image {
  585. position: absolute;
  586. z-index: 2;
  587. }
  588. </style>