引用

layui-layer(弹窗)
cropper.js
cropper-demo

HTML

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>cropper</title>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/layui/2.6.8/layui.js"
integrity="sha512-lH7rGfsFWwehkeyJYllBq73IsiR7RH2+wuOVjr06q8NKwHp5xVnkdSvUm8RNt31QCROqtPrjAAd1VuNH0ISxqQ=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/layui/2.6.8/css/layui.min.css"
integrity="sha512-iQBJbsNHXUcgEIgWThd2dr8tOdKPvICwqjPEZYY81z3eMya44A5MiAqfWSCh+Ee1YzNYkdrI982Qhwgr8LEYOQ=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
<link
href="https://cdn.bootcdn.net/ajax/libs/cropperjs/1.5.9/cropper.css"
rel="stylesheet"
/>
<script src="https://cdn.bootcdn.net/ajax/libs/cropperjs/1.5.9/cropper.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
.wrapper {
position: relative;
}
.box {
width: 300px;
height: 300px;
margin: 0 auto;
}
.avatar {
width: 100%;
display: block;
}
.upload {
display: none;
}
.popup {
display: none;
padding: 15px;
}
.popup .image-wrapper {
width: 400px;
}
.image-wrapper .image {
width: 100%;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="box">
<img
class="avatar"
src="https://img1.baidu.com/it/u=52681052,678098948&fm=253&fmt=auto&app=120&f=JPEG?w=1000&h=400"
/>
<input type="file" class="upload" accept="image/*" />
</div>
<div class="popup">
<div class="image-wrapper">
<img src="" class="image" />
</div>
</div>
</div>
</body>
</html>

JavaScript

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
$(function () {
class Upload {
constructor() {
this.$box = $(".box");
this.$input = $(".box .upload");
this.$image = $(".popup .image");
this.$popup = "";
this.cropper = null;
this.imgUrl = "";
this.init();
}
// 初始化
init() {
this.bindFileInputClick();
this.bindImageClick();
this.bindUploadChange();
}
// 创建弹窗
openLayer() {
var that = this;
layui.use("layer", function () {
var layer = layui.layer;
that.$popup = layer.open({
offset: "100px",
title: "裁剪图片",
type: 1,
btn: ["确定"],
content: $(".popup"),
// 弹窗打开的回调
success: function () {
that.cropper = new Cropper(that.$image[0], {
aspectRatio: 1,
viewMode: 3,
});
console.log("new Cropper");
},
// 点击确定按钮的回调
yes: function (index) {
console.log("保存");
that.saveCropped();
that.cropper.destroy();
that.cropper = null;
layer.close(index, () => {
$(".popup").hide();
});
console.log("cropper destroy");
},
// 点击关闭按钮的回调
cancel: function (index) {
that.cropper.destroy();
that.cropper = null;
layer.close(index, () => {
$(".popup").hide();
});
console.log("cropper destroy");
},
});
});
}
bindImageClick() {
var that = this;
this.$box.on("click", function (e) {
e.preventDefault();
e.stopPropagation();
that.$input.click();
});
}
bindFileInputClick() {
this.$input.on("click", function (e) {
e.stopPropagation();
});
}
initPopup(url) {
this.$input.val("");
this.$image.attr("src", url);
this.openLayer();
}
bindUploadChange() {
var that = this;
this.$input.on("change", function (e) {
var files = e.target.files;
var reader;
var file;
var url;
if (files && files.length > 0) {
file = files[0];
}
that.initPopup(URL.createObjectURL(file));
});
}
saveCropped() {
var that = this;
var saveAvatar = this.$box.find(".avatar").attr("src");
if (this.cropper) {
this.imgUrl = "";
var canvas = this.cropper.getCroppedCanvas({
width: 300,
height: 300,
});
canvas.toBlob(function (blob) {
var formData = new FormData();
formData.append("avatar", blob, "avatar.jpg");
$.ajax({
url: "https://jsonplaceholder.typicode.com/posts", // mock api
method: "post",
processData: false,
contentType: false,
success: function (res) {
console.log("upload success");
that.imgUrl = res.url; // mock
console.log(res);
that.$box.find(".avatar").attr("src", canvas.toDataURL());
},
error: function () {
that.$box.find(".avatar").attr("src", saveAvatar);
console.log("upload error");
},
});
});
}
}
}

class Page {
constructor() {
this.$upload = new Upload();
this.consoleUrl();
}
consoleUrl() {
var that = this;
$(document).on("click", function () {
console.log(that.$upload.imgUrl);
});
}
}

new Page();
});

codepen