HTML
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>图片裁剪插件cropper - 光年(Light Year Admin)后台管理系统模板</title>
<link rel="icon" href="favicon.ico" type="image/ico">
<meta name="keywords" content="LightYear,光年,后台模板,后台管理系统,光年HTML模板">
<meta name="description" content="LightYear是一个基于Bootstrap v3.3.7的后台管理系统的HTML模板。">
<meta name="author" content="yinqi">
<link href="http://lyear.itshubao.com/iframe/css/bootstrap.min.css" rel="stylesheet">
<link href="http://example.itshubao.com/demo/css/materialdesignicons.min.css" rel="stylesheet">
<link href="http://lyear.itshubao.com/iframe/css/animate.css" rel="stylesheet">
<link href="http://libs.itshubao.com/cropper/cropper.min.css" rel="stylesheet">
<link href="http://lyear.itshubao.com/iframe/css/style.min.css" rel="stylesheet">
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-header"><h4>图片裁剪插件 cropper</h4></div>
<div class="card-body">
<div class="form-group">
<label for="pic_url">没有图片地址的新上传</label>
<div class="input-group">
<input type="text" class="form-control image-src" name="picurl1" value="" />
<div class="input-group-btn">
<button class="btn btn-default trigger-btn" type="button">上传图片</button>
</div>
</div>
</div>
<div class="form-group">
<label for="pic_url">已有图片地址的修改操作</label>
<div class="input-group">
<input type="text" class="form-control image-src" name="picurl2" value="http://libs.itshubao.com/pic/small_003.jpg" />
<div class="input-group-btn">
<button class="btn btn-default trigger-btn" type="button">上传图片</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!--图片裁剪START-->
<div class="modal fade" id="image-modal" aria-hidden="true" aria-labelledby="image-modal-label" role="dialog" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button class="close" data-dismiss="modal" type="button">×</button>
<h4 class="modal-title" id="image-modal-label">上传图片</h4>
</div>
<div class="modal-body">
<div class="image-body">
<div class="image-upload m-b-15">
<button class="btn btn-primary" type="button" onclick="$('input[id=imageInput]').click();">请选择图片</button>
<span class="image-name"></span>
<input type="file" class="image-input hide" id="imageInput" name="file" accept=".jpg,.jpeg,.png,.gif,.bmp,.tiff">
</div>
<div class="row">
<div class="col-md-9 m-b-15">
<div class="image-wrapper"></div>
</div>
<div class="col-md-3">
<div class="image-previews clearfix">
<div class="image-preview preview-lg"></div>
<div class="image-preview preview-md"></div>
<div class="image-preview preview-sm"></div>
<div class="image-preview preview-xs"></div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4 image-btns">
<button class="btn btn-primary mdi mdi-rotate-left" data-method="rotate" data-option="-45" type="button" title="向左旋转-45度"></button>
<button class="btn btn-primary mdi mdi-rotate-right" data-method="rotate" data-option="45" type="button" title="向右旋转45度"></button>
<button type="button" class="btn btn-primary mdi mdi-magnify-plus-outline" data-method="zoom" data-option="0.1" title="放大图片"></button>
<button type="button" class="btn btn-primary mdi mdi-magnify-minus-outline" data-method="zoom" data-option="-0.1" title="缩小图片"></button>
<button type="button" class="btn btn-primary mdi mdi-cached" data-method="reset" title="重置图片"></button>
</div>
<div class="col-md-5 image-btns toggles-btns">
<div class="btn-group btn-group-toggle" data-toggle="buttons">
<label class="btn btn-primary active">
<input type="radio" name="aspectRatio" id="aspectRatio1" value="1.7777777777777777" checked>
<span>16:9</span>
</label>
<label class="btn btn-primary">
<input type="radio" name="aspectRatio" id="aspectRatio2" value="1.3333333333333333">
<span>4:3</span>
</label>
<label class="btn btn-primary">
<input type="radio" name="aspectRatio" id="aspectRatio3" value="1">
<span>1:1</span>
</label>
<label class="btn btn-primary">
<input type="radio" name="aspectRatio" id="aspectRatio3" value="0.6666666666666666">
<span>2:3</span>
</label>
<label class="btn btn-primary">
<input type="radio" name="aspectRatio" id="aspectRatio3" value="NaN">
<span>自适应</span>
</label>
</div>
</div>
<div class="col-md-3">
<button class="btn btn-primary btn-block upload-btn mdi mdi-content-save" type="submit">保存修改</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!--图片裁剪END-->
<script type="text/javascript" src="http://lyear.itshubao.com/iframe/js/jquery.min.js"></script>
<script type="text/javascript" src="http://lyear.itshubao.com/iframe/js/bootstrap.min.js"></script>
<script type="text/javascript" src="http://libs.itshubao.com/cropper/cropper.min.js"></script>
<script type="text/javascript" src="http://libs.itshubao.com/jquery.lyear.loading.js"></script>
<script type="text/javascript" src="http://lyear.itshubao.com/iframe/js/bootstrap-notify.min.js"></script>
<script type="text/javascript" src="http://lyear.itshubao.com/iframe/js/lightyear.js"></script>
<script type="text/javascript" src="http://lyear.itshubao.com/iframe/js/main.min.js"></script>
</body>
</html>
CSS
/* 裁剪样式 */
.image-wrapper {
height: 364px;
width: 100%;
box-shadow: inset 0 0 3px rgba(0, 0, 0, .075);
background-color: #fcfdfe;
overflow: hidden;
}
.image-preview {
float: left;
margin-bottom: 0.5rem;
margin-right: 0.5rem;
border: 1px solid #f1f2f3;
border-radius: 2px;
background-color: #fff;
overflow: hidden;
}
.image-preview img {
vertical-align: top;
}
.preview-lg {
height: 9rem;
width: 16rem;
}
.preview-md {
height: 4.5rem;
width: 8rem;
}
.preview-sm {
height: 2.25rem;
width: 4rem;
}
.preview-xs {
height: 1.125rem;
margin-right: 0;
width: 2rem;
}
@media (max-width: 991px) {
#image-modal .image-btns {
margin-bottom: 15px;
}
}
/* loading样式 - 可整体替换之前的loading */
@-webkit-keyframes spinner-border {
to {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes spinner-borderspinner-border {
to {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
.spinner-border {
display: inline-block;
vertical-align: text-bottom;
border: 0.125em solid currentColor;
border-right-color: transparent;
border-radius: 50%;
-webkit-animation: spinner-border .75s linear infinite;
animation: spinner-border .75s linear infinite;
}
JavaScript
function cropImage()
{
this.$triggerBtn = $('.trigger-btn'); // 上传按钮
//this.$imageText = this.$triggerBtn.parent().prev('.image-src'); // 图片地址输入框
this.$imageModal = $('#image-modal'); // 弹出框
this.$imageName = this.$imageModal.find('.image-name') // 图片名称
this.$imageInput = this.$imageModal.find('.image-input'); // file上传文件
this.$imageUpload = this.$imageModal.find('.image-upload'); // file所在元素
this.$imageBtns = this.$imageModal.find('.image-btns'); // 图片调整按钮(旋转、放大等)
this.$imageWrapper = this.$imageModal.find('.image-wrapper'); // 图片处理区域
this.$imagePreview = this.$imageModal.find('.image-preview'); // 图片裁剪预览区域
this.$uploadBtn = this.$imageModal.find('.upload-btn'); // 上传按钮
this.$togglesBtns = this.$imageModal.find('.toggles-btns'); // 比例切换按钮
this.URL = window.URL || window.webkitURL;
this.$options = {
aspectRatio: 16 / 9,
preview: '.image-preview'
}; // 配置
this.init();
}
cropImage.prototype = {
constructor: cropImage,
init: function() {
this.initModal();
this.addListener();
},
initModal: function() {
this.$imageModal.modal({
show: false
});
if(!URL) {
this.$imageInput.prop('disabled', true);
}
},
addListener: function() {
// 绑定事件
this.$triggerBtn.on('click', $.proxy(this.click, this));
this.$imageInput.on('change', $.proxy(this.change, this));
this.$togglesBtns.on('change', $.proxy(this.choose, this));
this.$uploadBtn.on('click', $.proxy(this.ajaxUpload, this));
this.$imageBtns.on('click', $.proxy(this.rotate, this));
},
click: function(e) {
// 点击上传按钮
this.$imageText = $(e.target).parent().prev('.image-src');
this.$imageModal.modal('show');
this.initPreview();
},
initPreview: function() {
this.active = false;
this.$imageInput.val('');
this.$imageName.text('');
this.$imageWrapper.empty();
// 如果已有图片地址,初始化图片预览区域
this.$imagePreview.empty();
var url = this.$imageText.val();
(url.length > 0) && this.$imagePreview.html('<img src="' + url + '">');
},
change: function() {
// 选择图片
var files, file;
files = this.$imageInput.prop('files');
if (files && files.length > 0) {
file = files[0];
if (this.isImageFile(file)) {
this.$imageType = file.type;
this.$imageName.text(file.name);
if (this.imageUrl) {
this.URL.revokeObjectURL(this.imageUrl);
}
this.imageUrl = this.URL.createObjectURL(file);
this.startCropper();
}
}
},
startCropper: function() {
// 选择图片后初始化
if (this.active) {
this.$image.cropper('replace', this.imageUrl, true);
} else {
this.$image = $('<img src="' + this.imageUrl + '">');
this.$imageWrapper.empty().html(this.$image);
this.$image.cropper('destroy').cropper(this.$options);
this.active = true;
}
},
isImageFile: function(file) {
// 判断是否图片格式
if (file.type) {
return /^image\/\w+$/.test(file.type);
} else {
return /\.(jpg|jpeg|png|gif|bmp|tiff)$/.test(file);
}
},
choose: function(e) {
var $this = $(e.target);
var name = $this.attr('name');
if (!this.active) {
return;
}
this.$options[name] = $this.val();
this.$image.cropper('destroy').cropper(this.$options);
},
rotate: function(e) {
// 调整图片操作
var data;
if (this.active) {
data = $(e.target).data();
if (data.method) {
this.$image.cropper(data.method, data.option);
}
}
},
stopCropper: function() {
// 裁剪上传完成后重置
if (this.active) {
this.$image.cropper('destroy');
this.$image.remove();
this.$imageModal.modal('hide');
this.$imageInput.val('');
this.$imageName.text('');
this.$togglesBtns.find('#aspectRatio1').attr('checked', true);
this.active = false;
}
},
ajaxUpload: function() {
var cas = this.$image.cropper('getCroppedCanvas'),
base64Data = cas.toDataURL(this.$imageType),
_this = this,
$loading;
// ajax上传
$.ajax("http://example.itshubao.com/index/test/upload_base64", {
type: 'post',
data: {"picdata" : base64Data},
dataType: 'json',
beforeSend: function() {
_this.$uploadBtn.prop('disabled', true);
$loading = $('.upload-btn').lyearloading({
opacity: 0.2,
spinnerSize: 'nm'
});
},
success: function(data) {
if ($.isPlainObject(data) && data.state === 200) {
_this.$imageText.val(data.picurl);
_this.stopCropper();
} else {
lightyear.notify(data.message, 'danger', 3000);
}
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
console.log(textStatus);
},
complete: function() {
_this.$uploadBtn.prop('disabled', false);
$loading.destroy();
}
});
}
};
$(document).ready(function(){
new cropImage();
});