【小程序开发原创】小程序裁剪图片上传头像,二维码源码

微信小程序 图片裁剪工具,简单易用

项目需求

在做微信小程序的时候有个图片上传之前裁剪的需求,找过一些github中的项目,都不太理想,主要是没有办法自定义宽高,于是自己研究了一下,做了一个简单的图片裁剪效果

使用方法

项目里面直接放的该功能的文件,将这个文件夹复制到小程序项目中,在app.json中启动该页面即可看到效果

微信小程序技术比较新,所以在网上找了很久都没有找到理想的裁剪插件,正好这两天不是很忙就自己查找资料做了,经过一天的努力终于把它做出来了,不容易啊,现在把它分享给你们(可为你门节省一天开发时间哦):

wxml:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

<!--图片展示 -->

<viewbindtap=\'upEwm\' data-which=\'1\' >

<view>第一个图</view>

<imagewidth:200rpx;height:200rpx;</image>

</view>

<viewbindtap=\'upEwm\' data-which=\'2\' >

<view>第二个图</view>

<imagewidth:200rpx;height:200rpx;</image>

</view>

<!--裁剪图片浮层-->

<viewclass=\'fixed-upimg\' wx:if="{{imageFixed}}">

<viewclass="wx-content-info" >

<!-- <view class="wx-content-info" wx:if="{{imageSrc}}"> -->

<viewwx:if="{{isShowImg}}" class="wx-corpper" >

<viewbindtap=\'upLoad\' class="wx-corpper-content" >

<imagesrc="{{imageSrc}}" ></image>

<viewclass="wx-corpper-crop-box" bindtouchstart="contentStartMove" bindtouchmove="contentMoveing" >

<viewclass="wx-cropper-view-box">

<!-- <view class="wx-cropper-viewer">

<image src="{{imageSrc}}" ></image>

</view> -->

<viewclass="wx-cropper-dashed-h"></view>

<viewclass="wx-cropper-dashed-v"></view>

<viewclass="wx-cropper-line-t" data-drag="top" catchtouchstart="dragStart" catchtouchmove="dragMove"></view>

<viewclass="wx-cropper-line-r" data-drag="right" catchtouchstart="dragStart" catchtouchmove="dragMove"></view>

<viewclass="wx-cropper-line-b" data-drag="bottom" catchtouchstart="dragStart" catchtouchmove="dragMove"></view>

<viewclass="wx-cropper-line-l" data-drag="left" catchtouchstart="dragStart" catchtouchmove="dragMove"></view>

<viewclass="wx-cropper-point point-t" data-drag="top" catchtouchstart="dragStart" catchtouchmove="dragMove"></view>

<viewclass="wx-cropper-point point-tr" data-drag="topTight"></view>

<viewclass="wx-cropper-point point-r" data-drag="right" catchtouchstart="dragStart" catchtouchmove="dragMove"></view>

<viewclass="wx-cropper-point point-rb" data-drag="rightBottom" catchtouchstart="dragStart" catchtouchmove="dragMove"></view>

<viewclass="wx-cropper-point point-b" data-drag="bottom" catchtouchstart="dragStart" catchtouchmove="dragMove"></view>

<viewclass="wx-cropper-point point-bl" data-drag="bottomLeft"></view>

<viewclass="wx-cropper-point point-l" data-drag="left" catchtouchstart="dragStart" catchtouchmove="dragMove"></view>

<viewclass="wx-cropper-point point-lt" data-drag="leftTop"></view>

</view>

</view>

</view>

<!-- <view class="wx-cropper-drag-box"></view> -->

</view>

<canvascanvas- ></canvas>

<buttontype="primary" bindtap="getImageInfo" > 确认提交 </button>

</view>

</view>

  js:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

439

440

441

442

443

444

445

446

447

448

449

450

451

452

453

454

455

456

457

458

459

460

461

462

463

// pages/wx-cropper/index.js

// 手机的宽度

varwindowWRPX = 750

// 拖动时候的 pageX

varpageX = 0

// 拖动时候的 pageY

varpageY = 0

varpixelRatio = wx.getSystemInfoSync().pixelRatio

// 调整大小时候的 pageX

varsizeConfPageX = 0

// 调整大小时候的 pageY

varsizeConfPageY = 0

varinitDragCutW = 0

varinitDragCutL = 0

varinitDragCutH = 0

varinitDragCutT = 0

// 移动时 手势位移与 实际元素位移的比

vardragScaleP = 2

Page({

/**

* 页面的初始数据

*/

data: {

imageNum:\'\',//上传的图片id

headImg:\'\',//头像上传

ewmImg:\'\',//二维码上传

imageFixed:false,//裁剪浮层

// imageSrc: \'http://topmdrt-static.oss-cn-shenzhen.aliyuncs.com/images/testimg2.jpeg\',

imageSrc:\'\',//要裁剪的图片

returnImage:\'\',

isShowImg:false,

// 初始化的宽高

cropperInitW: windowWRPX,

cropperInitH: windowWRPX,

// 动态的宽高

cropperW: windowWRPX,

cropperH: windowWRPX,

// 动态的left top值

cropperL: 0,

cropperT: 0,

// 图片缩放值

scaleP: 0,

imageW: 0,

imageH: 0,

// 裁剪框 宽高

cutW: 400,

cutH: 400,

cutL: 0,

cutT: 0,

},

/**

* 生命周期函数--监听页面加载

*/

onReady:function(options) {

},

/**

* 生命周期函数--监听页面初次渲染完成

*/

onLoad:function() {

var_this =this

// wx.showLoading({

// title: \'图片加载中...\',

// })

wx.getImageInfo({

src: _this.data.imageSrc,

success:functionsuccess(res) {

varinnerAspectRadio = res.width / res.height;

console.log(innerAspectRadio)

// 根据图片的宽高显示不同的效果 保证图片可以正常显示

if(innerAspectRadio >= 1) {

_this.setData({

cropperW: windowWRPX,

cropperH: windowWRPX / innerAspectRadio,

// 初始化left right

cropperL: Math.ceil((windowWRPX - windowWRPX) / 2),

cropperT: Math.ceil((windowWRPX - windowWRPX / innerAspectRadio) / 2),

// 裁剪框 宽高

// cutW: windowWRPX - 200,

// cutH: windowWRPX / innerAspectRadio - 200,

cutL: Math.ceil((windowWRPX - windowWRPX + 340) / 2),

cutT: Math.ceil((windowWRPX / innerAspectRadio - (windowWRPX / innerAspectRadio - 20)) / 2),

// 图片缩放值

scaleP: res.width * pixelRatio / windowWRPX,

// 图片原始宽度 rpx

imageW: res.width * pixelRatio,

imageH: res.height * pixelRatio

})

}else{

_this.setData({

cropperW: windowWRPX * innerAspectRadio,

cropperH: windowWRPX,

// 初始化left right

cropperL: Math.ceil((windowWRPX - windowWRPX * innerAspectRadio) / 2),

cropperT: Math.ceil((windowWRPX - windowWRPX) / 2),

// 裁剪框的宽高

// cutW: windowWRPX * innerAspectRadio - 66,

// cutH: 400,

cutL: Math.ceil((windowWRPX * innerAspectRadio - (windowWRPX * innerAspectRadio - 20)) / 2),

cutT: Math.ceil((windowWRPX - 340) / 2),

// 图片缩放值

scaleP: res.width * pixelRatio / windowWRPX,

// 图片原始宽度 rpx

imageW: res.width * pixelRatio,

imageH: res.height * pixelRatio

})

}

_this.setData({

isShowImg:true

})

wx.hideLoading()

}

})

},

// 拖动时候触发的touchStart事件

contentStartMove (e) {

pageX = e.touches[0].pageX

pageY = e.touches[0].pageY

},

// 拖动时候触发的touchMove事件

contentMoveing (e) {

var_this =this

// _this.data.cutL + (e.touches[0].pageX - pageX)

// console.log(e.touches[0].pageX)

// console.log(e.touches[0].pageX - pageX)

vardragLengthX = (pageX - e.touches[0].pageX) * dragScaleP

vardragLengthY = (pageY - e.touches[0].pageY) * dragScaleP

varminX = Math.max(_this.data.cutL - (dragLengthX), 0)

varminY = Math.max(_this.data.cutT - (dragLengthY), 0)

varmaxX = _this.data.cropperW - _this.data.cutW

varmaxY = _this.data.cropperH - _this.data.cutH

this.setData({

cutL: Math.min(maxX, minX),

cutT: Math.min(maxY, minY),

})

console.log(`${maxX} ----- ${minX}`)

pageX = e.touches[0].pageX

pageY = e.touches[0].pageY

},

// 获取图片

getImageInfo () {

var_this =this

console.log(\'shengcheng:\'+_this.data.imageSrc)

wx.showLoading({

title:\'图片生成中...\',

})

// wx.downloadFile({

// url:_this.data.imageSrc, //仅为示例,并非真实的资源

// success: function (res) {

// 将图片写入画布

const ctx = wx.createCanvasContext(\'myCanvas\')

// ctx.drawImage(res.tempFilePath)

ctx.drawImage(_this.data.imageSrc)

ctx.draw(true, () => {

// 获取画布要裁剪的位置和宽度 均为百分比 * 画布中图片的宽度 保证了在微信小程序中裁剪的图片模糊 位置不对的问题

varcanvasW = (_this.data.cutW / _this.data.cropperW) * (_this.data.imageW / pixelRatio)

varcanvasH = (_this.data.cutH / _this.data.cropperH) * (_this.data.imageH / pixelRatio)

varcanvasL = (_this.data.cutL / _this.data.cropperW) * (_this.data.imageW / pixelRatio)

varcanvasT = (_this.data.cutT / _this.data.cropperH) * (_this.data.imageH / pixelRatio)

console.log(`canvasW:${canvasW} --- canvasH: ${canvasH} --- canvasL: ${canvasL} --- canvasT: ${canvasT} -------- _this.data.imageW: ${_this.data.imageW} ------- _this.data.imageH: ${_this.data.imageH} ---- pixelRatio ${pixelRatio}`)

wx.canvasToTempFilePath({

x: canvasL,

y: canvasT,

width: canvasW,

height: canvasH,

destWidth: canvasW,

destHeight: canvasH,

canvasId:\'myCanvas\',

success:function(res) {

wx.hideLoading()

// 成功获得地址的地方

console.log(\'end:\'+res.tempFilePath)

// 判断时上传头像还是二维码

_this.setData({

imageFixed:false,

})

if(_this.data.imageNum ==\'1\') {

_this.setData({

headImg: res.tempFilePath

})

}elseif(_this.data.imageNum ==\'2\') {

_this.setData({

ewmImg: res.tempFilePath

})

}

}

})

})

// }

// })

},

// 设置大小的时候触发的touchStart事件

dragStart(e) {

var_this =this

sizeConfPageX = e.touches[0].pageX

sizeConfPageY = e.touches[0].pageY

initDragCutW = _this.data.cutW

initDragCutL = _this.data.cutL

initDragCutT = _this.data.cutT

initDragCutH = _this.data.cutH

},

// 设置大小的时候触发的touchMove事件

dragMove (e) {

var_this =this

vardragType = e.target.dataset.drag

switch(dragType) {

case\'right\':

vardragLength = (sizeConfPageX - e.touches[0].pageX) * dragScaleP

if(initDragCutW >= dragLength) {

// 如果 移动小于0 说明是在往下啦 放大裁剪的高度 这样一来 图片的高度 最大 等于 图片的top值加 当前图片的高度 否则就说明超出界限

if(dragLength < 0 && _this.data.cropperW > initDragCutL + _this.data.cutW) {

this.setData({

cutW: initDragCutW - dragLength

})

}

// 如果是移动 大于0 说明在缩小 只需要缩小的距离小于原本裁剪的高度就ok

if(dragLength > 0) {

this.setData({

cutW: initDragCutW - dragLength

})

}

else{

return

}

}else{

return

}

break;

case\'left\':

vardragLength = (dragLength = sizeConfPageX - e.touches[0].pageX) * dragScaleP

console.log(dragLength)

if(initDragCutW >= dragLength && initDragCutL > dragLength) {

if(dragLength < 0 && Math.abs(dragLength) >= initDragCutW)return

this.setData({

cutL: initDragCutL - dragLength,

cutW: initDragCutW + dragLength

})

}else{

return;

}

break;

case\'top\':

vardragLength = (sizeConfPageY - e.touches[0].pageY) * dragScaleP

if(initDragCutH >= dragLength && initDragCutT > dragLength) {

if(dragLength < 0 && Math.abs(dragLength) >= initDragCutH)return

this.setData({

cutT: initDragCutT - dragLength,

cutH: initDragCutH + dragLength

})

}else{

return;

}

break;

case\'bottom\':

vardragLength = (sizeConfPageY - e.touches[0].pageY) * dragScaleP

// console.log(_this.data.cropperH > _this.data.cutT + _this.data.cutH)

console.log(dragLength)

console.log(initDragCutH >= dragLength)

console.log(_this.data.cropperH > initDragCutT + _this.data.cutH)

// 必须是 dragLength 向上缩小的时候必须小于原本的高度

if(initDragCutH >= dragLength) {

// 如果 移动小于0 说明是在往下啦 放大裁剪的高度 这样一来 图片的高度 最大 等于 图片的top值加 当前图片的高度 否则就说明超出界限

if(dragLength < 0 && _this.data.cropperH > initDragCutT + _this.data.cutH) {

this.setData({

cutH: initDragCutH - dragLength

})

}

// 如果是移动 大于0 说明在缩小 只需要缩小的距离小于原本裁剪的高度就ok

if(dragLength > 0) {

this.setData({

cutH: initDragCutH - dragLength

})

}

else{

return

}

}else{

return

}

break;

case\'rightBottom\':

vardragLengthX = (sizeConfPageX - e.touches[0].pageX) * dragScaleP

vardragLengthY = (sizeConfPageY - e.touches[0].pageY) * dragScaleP

if(initDragCutH >= dragLengthY && initDragCutW >= dragLengthX) {

// bottom 方向的变化

if((dragLengthY < 0 && _this.data.cropperH > initDragCutT + _this.data.cutH) || (dragLengthY > 0)) {

this.setData({

cutH: initDragCutH - dragLengthY

})

}

// right 方向的变化

if((dragLengthX < 0 && _this.data.cropperW > initDragCutL + _this.data.cutW) || (dragLengthX > 0)) {

this.setData({

cutW: initDragCutW - dragLengthX

})

}

else{

return

}

}else{

return

}

break;

default:

break;

}

},

// 图片上传

upLoad:function() {

},

upEwm:function(e){

var_this =this

wx.chooseImage({

count: 1,// 默认9

sizeType: [\'original\',\'compressed\'],// 可以指定是原图还是压缩图,默认二者都有

sourceType: [\'album\',\'camera\'],// 可以指定来源是相册还是相机,默认二者都有

success:function(res) {

// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片

vartempFilePaths = res.tempFilePaths;

// var mode = parseFloat(e.currentTarget.dataset.current);

console.log(\'shangchuan:\'+ tempFilePaths)

console.log(e.currentTarget.dataset.which);

_this.setData({

imageFixed:true,

imageSrc: tempFilePaths.join(),

imageNum: e.currentTarget.dataset.which

})

// start

wx.getImageInfo({

src: _this.data.imageSrc,

success:functionsuccess(res) {

varinnerAspectRadio = res.width / res.height;

console.log(\'bili\'+innerAspectRadio)

// 根据图片的宽高显示不同的效果 保证图片可以正常显示

if(innerAspectRadio ==\'1\') {

console.log(\'zhengfangxingtu\')

_this.setData({

imageFixed:false,

})

// 判断时上传头像还是二维码

if(_this.data.imageNum ==\'1\') {

_this.setData({

headImg: tempFilePaths.join()

})

}elseif(_this.data.imageNum ==\'2\') {

_this.setData({

ewmImg: tempFilePaths.join()

})

}

}elseif(innerAspectRadio > 1) {

_this.setData({

cropperW: windowWRPX,

cropperH: windowWRPX / innerAspectRadio,

// 初始化left right

cropperL: Math.ceil((windowWRPX - windowWRPX) / 2),

cropperT: Math.ceil((windowWRPX - windowWRPX / innerAspectRadio) / 2),

// 裁剪框 宽高

// cutW: windowWRPX - 200,

// cutH: windowWRPX / innerAspectRadio - 200,

cutL: Math.ceil((windowWRPX - windowWRPX + 340) / 2),

cutT: Math.ceil((windowWRPX / innerAspectRadio - (windowWRPX / innerAspectRadio - 20)) / 2),

// 图片缩放值

scaleP: res.width * pixelRatio / windowWRPX,

// 图片原始宽度 rpx

imageW: res.width * pixelRatio,

imageH: res.height * pixelRatio

})

}else{

_this.setData({

cropperW: windowWRPX * innerAspectRadio,

cropperH: windowWRPX,

// 初始化left right

cropperL: Math.ceil((windowWRPX - windowWRPX * innerAspectRadio) / 2),

cropperT: Math.ceil((windowWRPX - windowWRPX) / 2),

// 裁剪框的宽高

// cutW: windowWRPX * innerAspectRadio - 66,

// cutH: 400,

cutL: Math.ceil((windowWRPX * innerAspectRadio - (windowWRPX * innerAspectRadio - 20)) / 2),

cutT: Math.ceil((windowWRPX - 340) / 2),

// 图片缩放值

scaleP: res.width * pixelRatio / windowWRPX,

// 图片原始宽度 rpx

imageW: res.width * pixelRatio,

imageH: res.height * pixelRatio

})

}

_this.setData({

isShowImg:true

})

wx.hideLoading()

}

})

// end

}

})

},

/**

* 生命周期函数--监听页面显示

*/

onShow:function() {

},

/**

* 生命周期函数--监听页面隐藏

*/

onHide:function() {

},

/**

* 生命周期函数--监听页面卸载

*/

onUnload:function() {

},

/**

* 页面相关事件处理函数--监听用户下拉动作

*/

onPullDownRefresh:function() {

},

/**

* 页面上拉触底事件的处理函数

*/

onReachBottom:function() {

},

/**

* 用户点击右上角分享

*/

onShareAppMessage:function() {

}

})

  

 wxss:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

/* pages/wx-cropper/index.wxss */

.fixed-upimg{

position:fixed;

top:0;

left:0;

right:0;

bottom:0;

background-color:#fff;

}

.wx-content-info{

position:fixed;

top:130rpx;

left:0;

right:0;

bottom:0;

}

.wx-corpper{

position:relative;

overflow:hidden;

-webkit-user-select:none;

-moz-user-select:none;

-ms-user-select:none;

user-select:none;

-webkit-tap-highlight-color:transparent;

-webkit-touch-callout:none;

box-sizing: border-box;

}

.wx-corpper-content{

position:absolute;

top:0;

right:0;

bottom:0;

left:0;

}

.wx-corpper-content image {

display:block;

width:100%;

min-width:0!important;

max-width:none!important;

height:100%;

min-height:0!important;

max-height:none!important;

image-orientation:0deg!important;

margin:0auto;

}

/* 移动图片效果 */

.wx-cropper-drag-box{

position:absolute;

top:0;

right:0;

bottom:0;

left:0;

cursor:move;

background: rgba(0,0,0,0.6);

z-index:1;

}

/* 内部的信息 */

.wx-corpper-crop-box{

position:absolute;

width:500rpx;

height:500rpx;

background: rgba(255,255,255,0.3);

z-index:2;

}

.wx-corpper-crop-box .wx-cropper-view-box {

position:relative;

display:block;

width:100%;

height:100%;

overflow:visible;

outline:1pxsolid#69f;

outline-color: rgba(102,153,255, .75)

}

/* 横向虚线 */

.wx-cropper-dashed-h{

position:absolute;

top:33.33333333%;

left:0;

width:100%;

height:33.33333333%;

border-top:1pxdashedrgba(255,255,255,0.5);

border-bottom:1pxdashedrgba(255,255,255,0.5);

}

/* 纵向虚线 */

.wx-cropper-dashed-v{

position:absolute;

left:33.33333333%;

top:0;

width:33.33333333%;

height:100%;

border-left:1pxdashedrgba(255,255,255,0.5);

border-right:1pxdashedrgba(255,255,255,0.5);

}

/* 四个方向的线 为了之后的拖动事件*/

.wx-cropper-line-t{

position:absolute;

display:block;

width:100%;

background-color:#69f;

top:0;

left:0;

height:1px;

opacity:0.1;

cursor:n-resize;

}

.wx-cropper-line-t::before{

content:\'\';

position:absolute;

top:50%;

right:0rpx;

width:100%;

-webkit-transform: translate3d(0,-50%,0);

transform: translate3d(0,-50%,0);

bottom:0;

height:41rpx;

background:transparent;

z-index:11;

}

.wx-cropper-line-r{

position:absolute;

display:block;

background-color:#69f;

top:0;

right:0px;

width:1px;

opacity:0.1;

height:100%;

cursor:e-resize;

}

.wx-cropper-line-r::before{

content:\'\';

position:absolute;

top:0;

left:50%;

width:41rpx;

-webkit-transform: translate3d(-50%,0,0);

transform: translate3d(-50%,0,0);

bottom:0;

height:100%;

background:transparent;

z-index:11;

}

.wx-cropper-line-b{

position:absolute;

display:block;

width:100%;

background-color:#69f;

bottom:0;

left:0;

height:1px;

opacity:0.1;

cursor:s-resize;

}

.wx-cropper-line-b::before{

content:\'\';

position:absolute;

top:50%;

right:0rpx;

width:100%;

-webkit-transform: translate3d(0,-50%,0);

transform: translate3d(0,-50%,0);

bottom:0;

height:41rpx;

background:transparent;

z-index:11;

}

.wx-cropper-line-l{

position:absolute;

display:block;

background-color:#69f;

top:0;

left:0;

width:1px;

opacity:0.1;

height:100%;

cursor:w-resize;

}

.wx-cropper-line-l::before{

content:\'\';

position:absolute;

top:0;

left:50%;

width:41rpx;

-webkit-transform: translate3d(-50%,0,0);

transform: translate3d(-50%,0,0);

bottom:0;

height:100%;

background:transparent;

z-index:11;

}

.wx-cropper-point{

width:5px;

height:5px;

background-color:#69f;

opacity: .75;

position:absolute;

z-index:3;

}

.point-t{

top:-3px;

left:50%;

margin-left:-3px;

cursor:n-resize;

}

.point-tr{

top:-3px;

left:100%;

margin-left:-3px;

cursor:n-resize;

}

.point-r{

top:50%;

left:100%;

margin-left:-3px;

margin-top:-3px;

cursor:n-resize;

}

.point-rb{

left:100%;

top:100%;

-webkit-transform: translate3d(-50%,-50%,0);

transform: translate3d(-50%,-50%,0);

cursor:n-resize;

width:24rpx;

height:24rpx;

background-color:#69f;

position:absolute;

z-index:1112;

opacity:1;

}

.point-b{

left:50%;

top:100%;

margin-left:-3px;

margin-top:-3px;

cursor:n-resize;

}

.point-bl{

left:0%;

top:100%;

margin-left:-3px;

margin-top:-3px;

cursor:n-resize;

}

.point-l{

left:0%;

top:50%;

margin-left:-3px;

margin-top:-3px;

cursor:n-resize;

}

.point-lt{

left:0%;

top:0%;

margin-left:-3px;

margin-top:-3px;

cursor:n-resize;

}

/* 裁剪框预览内容 */

.wx-cropper-viewer{

position:relative;

width:100%;

height:100%;

overflow:hidden;

}

.wx-cropper-viewer image{

position:absolute;

z-index:2;

}

from https://www.cnblogs.com/xiaohuizhang/p/8884253.html