first commit

This commit is contained in:
pakerpale
2020-06-10 06:19:03 +09:00
commit cd6b5b7832
6081 changed files with 624389 additions and 0 deletions

304
public/cropperjs/css/cropper.css Executable file
View File

@@ -0,0 +1,304 @@
/*!
* Cropper.js v1.5.6
* https://fengyuanchen.github.io/cropperjs
*
* Copyright 2015-present Chen Fengyuan
* Released under the MIT license
*
* Date: 2019-10-04T04:33:44.164Z
*/
.cropper-container {
direction: ltr;
font-size: 0;
line-height: 0;
position: relative;
-ms-touch-action: none;
touch-action: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.cropper-container img {
display: block;
height: 100%;
image-orientation: 0deg;
max-height: none !important;
max-width: none !important;
min-height: 0 !important;
min-width: 0 !important;
width: 100%;
}
.cropper-wrap-box,
.cropper-canvas,
.cropper-drag-box,
.cropper-crop-box,
.cropper-modal {
bottom: 0;
left: 0;
position: absolute;
right: 0;
top: 0;
}
.cropper-wrap-box,
.cropper-canvas {
overflow: hidden;
}
.cropper-drag-box {
background-color: #fff;
opacity: 0;
}
.cropper-modal {
background-color: #000;
opacity: 0.5;
}
.cropper-view-box {
display: block;
height: 100%;
outline: 1px solid #39f;
outline-color: rgba(51, 153, 255, 0.75);
overflow: hidden;
width: 100%;
}
.cropper-dashed {
border: 0 dashed #eee;
display: block;
opacity: 0.5;
position: absolute;
}
.cropper-dashed.dashed-h {
border-bottom-width: 1px;
border-top-width: 1px;
height: calc(100% / 3);
left: 0;
top: calc(100% / 3);
width: 100%;
}
.cropper-dashed.dashed-v {
border-left-width: 1px;
border-right-width: 1px;
height: 100%;
left: calc(100% / 3);
top: 0;
width: calc(100% / 3);
}
.cropper-center {
display: block;
height: 0;
left: 50%;
opacity: 0.75;
position: absolute;
top: 50%;
width: 0;
}
.cropper-center::before,
.cropper-center::after {
background-color: #eee;
content: ' ';
display: block;
position: absolute;
}
.cropper-center::before {
height: 1px;
left: -3px;
top: 0;
width: 7px;
}
.cropper-center::after {
height: 7px;
left: 0;
top: -3px;
width: 1px;
}
.cropper-face,
.cropper-line,
.cropper-point {
display: block;
height: 100%;
opacity: 0.1;
position: absolute;
width: 100%;
}
.cropper-face {
background-color: #fff;
left: 0;
top: 0;
}
.cropper-line {
background-color: #39f;
}
.cropper-line.line-e {
cursor: ew-resize;
right: -3px;
top: 0;
width: 5px;
}
.cropper-line.line-n {
cursor: ns-resize;
height: 5px;
left: 0;
top: -3px;
}
.cropper-line.line-w {
cursor: ew-resize;
left: -3px;
top: 0;
width: 5px;
}
.cropper-line.line-s {
bottom: -3px;
cursor: ns-resize;
height: 5px;
left: 0;
}
.cropper-point {
background-color: #39f;
height: 5px;
opacity: 0.75;
width: 5px;
}
.cropper-point.point-e {
cursor: ew-resize;
margin-top: -3px;
right: -3px;
top: 50%;
}
.cropper-point.point-n {
cursor: ns-resize;
left: 50%;
margin-left: -3px;
top: -3px;
}
.cropper-point.point-w {
cursor: ew-resize;
left: -3px;
margin-top: -3px;
top: 50%;
}
.cropper-point.point-s {
bottom: -3px;
cursor: s-resize;
left: 50%;
margin-left: -3px;
}
.cropper-point.point-ne {
cursor: nesw-resize;
right: -3px;
top: -3px;
}
.cropper-point.point-nw {
cursor: nwse-resize;
left: -3px;
top: -3px;
}
.cropper-point.point-sw {
bottom: -3px;
cursor: nesw-resize;
left: -3px;
}
.cropper-point.point-se {
bottom: -3px;
cursor: nwse-resize;
height: 20px;
opacity: 1;
right: -3px;
width: 20px;
}
@media (min-width: 768px) {
.cropper-point.point-se {
height: 15px;
width: 15px;
}
}
@media (min-width: 992px) {
.cropper-point.point-se {
height: 10px;
width: 10px;
}
}
@media (min-width: 1200px) {
.cropper-point.point-se {
height: 5px;
opacity: 0.75;
width: 5px;
}
}
.cropper-point.point-se::before {
background-color: #39f;
bottom: -50%;
content: ' ';
display: block;
height: 200%;
opacity: 0;
position: absolute;
right: -50%;
width: 200%;
}
.cropper-invisible {
opacity: 0;
}
.cropper-bg {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC');
}
.cropper-hide {
display: block;
height: 0;
position: absolute;
width: 0;
}
.cropper-hidden {
display: none !important;
}
.cropper-move {
cursor: move;
}
.cropper-crop {
cursor: crosshair;
}
.cropper-disabled .cropper-drag-box,
.cropper-disabled .cropper-face,
.cropper-disabled .cropper-line,
.cropper-disabled .cropper-point {
cursor: not-allowed;
}

252
public/cropperjs/css/main.css Executable file
View File

@@ -0,0 +1,252 @@
.btn {
padding-left: 0.75rem;
padding-right: 0.75rem;
}
label.btn {
margin-bottom: 0;
}
.d-flex > .btn {
flex: 1;
}
.carbonads {
border: 1px solid #ccc;
border-radius: 0.25rem;
font-size: 0.875rem;
overflow: hidden;
padding: 1rem;
}
.carbon-wrap {
overflow: hidden;
}
.carbon-img {
clear: left;
display: block;
float: left;
}
.carbon-text,
.carbon-poweredby {
display: block;
margin-left: 140px;
}
.carbon-text,
.carbon-text:hover,
.carbon-text:focus {
color: #fff;
text-decoration: none;
}
.carbon-poweredby,
.carbon-poweredby:hover,
.carbon-poweredby:focus {
color: #ddd;
text-decoration: none;
}
@media (min-width: 768px) {
.carbonads {
float: right;
margin-bottom: -1rem;
margin-top: -1rem;
max-width: 360px;
}
}
.footer {
font-size: 0.875rem;
}
.heart {
color: #ddd;
display: block;
height: 2rem;
line-height: 2rem;
margin-bottom: 0;
margin-top: 1rem;
position: relative;
text-align: center;
width: 100%;
}
.heart:hover {
color: #ff4136;
}
.heart::before {
border-top: 1px solid #eee;
content: " ";
display: block;
height: 0;
left: 0;
position: absolute;
right: 0;
top: 50%;
}
.heart::after {
background-color: #fff;
content: "♥";
padding-left: 0.5rem;
padding-right: 0.5rem;
position: relative;
z-index: 1;
}
.img-container,
.img-preview {
background-color: #f7f7f7;
text-align: center;
width: 100%;
}
.img-container {
margin-bottom: 1rem;
max-height: 497px;
min-height: 200px;
}
@media (min-width: 768px) {
.img-container {
min-height: 497px;
}
}
.img-container > img {
max-width: 100%;
}
.docs-preview {
margin-right: -1rem;
}
.img-preview {
float: left;
margin-bottom: 0.5rem;
margin-right: 0.5rem;
overflow: hidden;
}
.img-preview > img {
max-width: 100%;
}
.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;
}
.docs-data > .input-group {
margin-bottom: 0.5rem;
}
.docs-data .input-group-prepend .input-group-text {
min-width: 4rem;
}
.docs-data .input-group-append .input-group-text {
min-width: 3rem;
}
.docs-buttons > .btn,
.docs-buttons > .btn-group,
.docs-buttons > .form-control {
margin-bottom: 0.5rem;
margin-right: 0.25rem;
}
.docs-toggles > .btn,
.docs-toggles > .btn-group,
.docs-toggles > .dropdown {
margin-bottom: 0.5rem;
}
.docs-tooltip {
display: block;
margin: -0.5rem -0.75rem;
padding: 0.5rem 0.75rem;
}
.docs-tooltip > .icon {
margin: 0 -0.25rem;
vertical-align: top;
}
.tooltip-inner {
white-space: normal;
}
.btn-upload .tooltip-inner,
.btn-toggle .tooltip-inner {
white-space: nowrap;
}
.btn-toggle {
padding: 0.5rem;
}
.btn-toggle > .docs-tooltip {
margin: -0.5rem;
padding: 0.5rem;
}
@media (max-width: 400px) {
.btn-group-crop {
margin-right: -1rem !important;
}
.btn-group-crop > .btn {
padding-left: 0.5rem;
padding-right: 0.5rem;
}
.btn-group-crop .docs-tooltip {
margin-left: -0.5rem;
margin-right: -0.5rem;
padding-left: 0.5rem;
padding-right: 0.5rem;
}
}
.docs-options .dropdown-menu {
width: 100%;
}
.docs-options .dropdown-menu > li {
font-size: 0.875rem;
padding: 0.125rem 1rem;
}
.docs-options .dropdown-menu .form-check-label {
display: block;
}
.docs-cropped .modal-body {
text-align: center;
}
.docs-cropped .modal-body > img,
.docs-cropped .modal-body > canvas {
max-width: 100%;
}

View File

@@ -0,0 +1,70 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Cropper.js</title>
<link rel="stylesheet" href="../css/cropper.css">
<style>
.container {
margin: 20px auto;
max-width: 640px;
}
img {
max-width: 100%;
}
</style>
</head>
<body>
<div class="container">
<h1>Cropper with a range of aspect ratio</h1>
<div>
<img id="image" src="../images/picture.jpg" alt="Picture">
</div>
</div>
<script src="../js/cropper.js"></script>
<script>
window.addEventListener('DOMContentLoaded', function () {
var image = document.querySelector('#image');
var minAspectRatio = 0.5;
var maxAspectRatio = 1.5;
var cropper = new Cropper(image, {
ready: function () {
var cropper = this.cropper;
var containerData = cropper.getContainerData();
var cropBoxData = cropper.getCropBoxData();
var aspectRatio = cropBoxData.width / cropBoxData.height;
var newCropBoxWidth;
if (aspectRatio < minAspectRatio || aspectRatio > maxAspectRatio) {
newCropBoxWidth = cropBoxData.height * ((minAspectRatio + maxAspectRatio) / 2);
cropper.setCropBoxData({
left: (containerData.width - newCropBoxWidth) / 2,
width: newCropBoxWidth
});
}
},
cropmove: function () {
var cropper = this.cropper;
var cropBoxData = cropper.getCropBoxData();
var aspectRatio = cropBoxData.width / cropBoxData.height;
if (aspectRatio < minAspectRatio) {
cropper.setCropBoxData({
width: cropBoxData.height * minAspectRatio
});
} else if (aspectRatio > maxAspectRatio) {
cropper.setCropBoxData({
width: cropBoxData.height * maxAspectRatio
});
}
},
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,94 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Cropper.js</title>
<link rel="stylesheet" href="../css/cropper.css">
<style>
.container {
margin: 20px auto;
max-width: 640px;
}
img {
max-width: 100%;
}
.cropper-view-box,
.cropper-face {
border-radius: 50%;
}
</style>
</head>
<body>
<div class="container">
<h1>Crop a round image</h1>
<h3>Image</h3>
<div>
<img id="image" src="../images/picture.jpg" alt="Picture">
</div>
<h3>Result</h3>
<p>
<button type="button" id="button">Crop</button>
</p>
<div id="result"></div>
</div>
<script src="../js/cropper.js"></script>
<script>
function getRoundedCanvas(sourceCanvas) {
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
var width = sourceCanvas.width;
var height = sourceCanvas.height;
canvas.width = width;
canvas.height = height;
context.imageSmoothingEnabled = true;
context.drawImage(sourceCanvas, 0, 0, width, height);
context.globalCompositeOperation = 'destination-in';
context.beginPath();
context.arc(width / 2, height / 2, Math.min(width, height) / 2, 0, 2 * Math.PI, true);
context.fill();
return canvas;
}
window.addEventListener('DOMContentLoaded', function () {
var image = document.getElementById('image');
var button = document.getElementById('button');
var result = document.getElementById('result');
var croppable = false;
var cropper = new Cropper(image, {
aspectRatio: 1,
viewMode: 1,
ready: function () {
croppable = true;
},
});
button.onclick = function () {
var croppedCanvas;
var roundedCanvas;
var roundedImage;
if (!croppable) {
return;
}
// Crop
croppedCanvas = cropper.getCroppedCanvas();
// Round
roundedCanvas = getRoundedCanvas(croppedCanvas);
// Show
roundedImage = document.createElement('img');
roundedImage.src = roundedCanvas.toDataURL()
result.innerHTML = '';
result.appendChild(roundedImage);
};
});
</script>
</body>
</html>

View File

@@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Cropper.js</title>
<link rel="stylesheet" href="../css/cropper.css">
<style>
.container {
margin: 20px auto;
max-width: 640px;
}
img {
max-width: 100%;
}
</style>
</head>
<body>
<div class="container">
<h1>Crop a cross origin image</h1>
<p>A cross origin image with a <code>crossorigin</code> attribute and an available <code>Access-Control-Allow-Origin</code> response header can be cropped by Cropper.</p>
<h3>Image</h3>
<div>
<img id="image" src="https://raw.githubusercontent.com/fengyuanchen/cropperjs/master/docs/images/picture.jpg" crossorigin>
</div>
<h3>Result</h3>
<div id="result"></div>
</div>
<script src="../js/cropper.js"></script>
<script>
window.addEventListener('DOMContentLoaded', function () {
var image = document.querySelector('#image');
var result = document.querySelector('#result');
var cropper = new Cropper(image, {
ready: function () {
var image = new Image();
image.src = cropper.getCroppedCanvas().toDataURL('image/jpeg');
result.appendChild(image);
},
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,62 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Cropper.js</title>
<link rel="stylesheet" href="../css/cropper.css">
<style>
.container {
margin: 20px auto;
max-width: 640px;
}
img {
max-width: 100%;
}
</style>
</head>
<body>
<div class="container">
<h1>Crop on canvas with Cropper</h1>
<h3>Image</h3>
<div class="img-container">
<img id="image" src="../images/picture.jpg" alt="Picture">
</div>
<h3>Canvas</h3>
<div class="img-container">
<canvas id="canvas"></canvas>
</div>
</div>
<script src="../js/cropper.js"></script>
<script>
function start() {
var width = this.offsetWidth;
var height = this.offsetHeight;
var cropper;
canvas.width = width;
canvas.height = height;
canvas.getContext('2d').drawImage(
this,
0, 0, this.naturalWidth, this.naturalHeight,
0, 0, width, height
);
cropper = new Cropper(canvas);
}
window.addEventListener('DOMContentLoaded', function () {
var canvas = document.getElementById('canvas');
var image = document.getElementById('image');
if (image.complete) {
start.call(image);
} else {
image.onload = start;
}
});
</script>
</body>
</html>

View File

@@ -0,0 +1,74 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Cropper.js</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" crossorigin="anonymous">
<link rel="stylesheet" href="../css/cropper.css">
<style>
.img-container img {
max-width: 100%;
}
</style>
</head>
<body>
<div class="container">
<h1>Cropper in a Bootstrap modal</h1>
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-target="#modal" data-toggle="modal">
Launch the demo
</button>
<!-- Modal -->
<div class="modal fade" id="modal" tabindex="-1" role="dialog" aria-labelledby="modalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalLabel">Cropper</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="img-container">
<img id="image" src="../images/picture.jpg" alt="Picture">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
<script src="../js/cropper.js"></script>
<script>
window.addEventListener('DOMContentLoaded', function () {
var image = document.getElementById('image');
var cropBoxData;
var canvasData;
var cropper;
$('#modal').on('shown.bs.modal', function () {
cropper = new Cropper(image, {
autoCropArea: 0.5,
ready: function () {
//Should set crop box data first here
cropper.setCropBoxData(cropBoxData).setCanvasData(canvasData);
}
});
}).on('hidden.bs.modal', function () {
cropBoxData = cropper.getCropBoxData();
canvasData = cropper.getCanvasData();
cropper.destroy();
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,128 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Cropper.js</title>
<link rel="stylesheet" href="../css/cropper.css">
<style>
.container {
margin: 20px auto;
max-width: 960px;
}
img {
max-width: 100%;
}
.row,
.preview {
overflow: hidden;
}
.col {
float: left;
}
.col-6 {
width: 50%;
}
.col-3 {
width: 25%;
}
.col-2 {
width: 16.7%;
}
.col-1 {
width: 8.3%;
}
</style>
</head>
<body>
<div class="container">
<h1>Customize preview for Cropper</h1>
<div class="row">
<div class="col col-6">
<img id="image" src="../images/picture.jpg" alt="Picture">
</div>
<div class="col col-3">
<div class="preview"></div>
</div>
<div class="col col-2">
<div class="preview"></div>
</div>
<div class="col col-1">
<div class="preview"></div>
</div>
</div>
</div>
<script src="../js/cropper.js"></script>
<script>
function each(arr, callback) {
var length = arr.length;
var i;
for (i = 0; i < length; i++) {
callback.call(arr, arr[i], i, arr);
}
return arr;
}
window.addEventListener('DOMContentLoaded', function () {
var image = document.querySelector('#image');
var previews = document.querySelectorAll('.preview');
var previewReady = false;
var cropper = new Cropper(image, {
ready: function () {
var clone = this.cloneNode();
clone.className = '';
clone.style.cssText = (
'display: block;' +
'width: 100%;' +
'min-width: 0;' +
'min-height: 0;' +
'max-width: none;' +
'max-height: none;'
);
each(previews, function (elem) {
elem.appendChild(clone.cloneNode());
});
previewReady = true;
},
crop: function (event) {
if (!previewReady) {
return;
}
var data = event.detail;
var cropper = this.cropper;
var imageData = cropper.getImageData();
var previewAspectRatio = data.width / data.height;
each(previews, function (elem) {
var previewImage = elem.getElementsByTagName('img').item(0);
var previewWidth = elem.offsetWidth;
var previewHeight = previewWidth / previewAspectRatio;
var imageScaledRatio = data.width / previewWidth;
elem.style.height = previewHeight + 'px';
previewImage.style.width = imageData.naturalWidth / imageScaledRatio + 'px';
previewImage.style.height = imageData.naturalHeight / imageScaledRatio + 'px';
previewImage.style.marginLeft = -data.x / imageScaledRatio + 'px';
previewImage.style.marginTop = -data.y / imageScaledRatio + 'px';
});
},
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Cropper.js</title>
<link rel="stylesheet" href="../css/cropper.css">
<style>
.container {
margin: 20px auto;
max-width: 640px;
}
img {
max-width: 100%;
}
</style>
</head>
<body>
<div class="container">
<h1>Cropper with fixed crop box</h1>
<div>
<img id="image" src="../images/picture.jpg" alt="Picture">
</div>
</div>
<script src="../js/cropper.js"></script>
<script>
window.addEventListener('DOMContentLoaded', function () {
var image = document.querySelector('#image');
var cropper = new Cropper(image, {
dragMode: 'move',
aspectRatio: 16 / 9,
autoCropArea: 0.65,
restore: false,
guides: false,
center: false,
highlight: false,
cropBoxMovable: false,
cropBoxResizable: false,
toggleDragModeOnDblclick: false,
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Cropper.js</title>
<link rel="stylesheet" href="../css/cropper.css">
<style>
.container {
margin: 20px auto;
max-width: 640px;
}
img {
max-width: 100%;
}
</style>
</head>
<body>
<div class="container">
<h1>Cropper with full crop box</h1>
<div>
<img id="image" src="../images/picture.jpg" alt="Picture">
</div>
</div>
<script src="../js/cropper.js"></script>
<script>
window.addEventListener('DOMContentLoaded', function () {
var image = document.querySelector('#image');
var cropper = new Cropper(image, {
viewMode: 3,
dragMode: 'move',
autoCropArea: 1,
restore: false,
modal: false,
guides: false,
highlight: false,
cropBoxMovable: false,
cropBoxResizable: false,
toggleDragModeOnDblclick: false,
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,108 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Cropper.js</title>
<link rel="stylesheet" href="../css/cropper.css">
<style>
.container {
margin: 20px auto;
max-width: 640px;
}
img {
max-width: 100%;
}
.cropper-view-box,
.cropper-face {
background-color: black;
opacity: 1;
}
</style>
</head>
<body>
<div class="container">
<h1>Mask an image (Redaction)</h1>
<h3>Image</h3>
<div>
<img id="image" src="../images/picture.jpg" alt="Picture">
</div>
<h3>Result</h3>
<p><button type="button" id="button">Mask</button></p>
<div id="result"></div>
</div>
<script src="../js/cropper.js"></script>
<script>
function getMaskedCanvas(sourceCanvas, sourceImage, cropper) {
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
var maskWidth = cropper.getData().width;
var maskHeight = cropper.getData().height;
var maskTop = cropper.getData().y;
var maskLeft = cropper.getData().x;
var imageWidth = cropper.getImageData().naturalWidth;
var imageHeight = cropper.getImageData().naturalHeight;
var imageLeft = cropper.getImageData().left;
var imageTop = cropper.getImageData().top;
var imageAspect = cropper.getImageData().aspectRatio;
canvas.width = imageWidth;
canvas.height = imageHeight;
// Debug
console.log('Image Width: ' + imageWidth + ' Image Height: ' + imageHeight + ' Image Aspect Ratio: ' + imageAspect );
console.log('Image Left: ' + imageLeft + ' Image Top: ' + imageTop );
console.log('Mask Width: ' + maskWidth + ' Mask Height: ' + maskHeight + ' Mask Left: ' + maskLeft + ' Mask Top: ' + maskTop);
context.imageSmoothingEnabled = true;
context.drawImage(image, 0, 0, imageWidth, imageHeight);
context.fillRect(maskLeft, maskTop, maskWidth, maskHeight);
return canvas;
}
window.addEventListener('DOMContentLoaded', function () {
var image = document.getElementById('image');
var button = document.getElementById('button');
var result = document.getElementById('result');
var croppable = false;
var cropper = new Cropper(image, {
viewMode: 0,
guides: true,
center: true,
highlight: true,
cropBoxMovable: true,
cropBoxResizable: true,
ready: function () {
croppable = true;
},
});
button.onclick = function () {
var croppedCanvas;
var maskedCanvas;
var maskedImage;
if (!croppable) {
return;
}
// Crop
croppedCanvas = cropper.getCroppedCanvas();
// Mask
maskedCanvas = getMaskedCanvas(croppedCanvas, image, cropper);
// Show
maskedImage = document.createElement('img');
maskedImage.src = maskedCanvas.toDataURL();
result.innerHTML = '';
result.appendChild(maskedImage);
};
});
</script>
</body>
</html>

View File

@@ -0,0 +1,81 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Cropper.js</title>
<link rel="stylesheet" href="../css/cropper.css">
<style>
.container {
margin: 20px auto;
max-width: 640px;
}
img {
max-width: 100%;
}
</style>
</head>
<body>
<div class="container">
<h1>Minimum and maximum cropped dimensions</h1>
<h3>Image</h3>
<div>
<img id="image" src="../images/picture.jpg" alt="Picture">
</div>
<p>Maximum Width: 640, Maximum Height: 320, Minimum Width: 320, Minimum Height: 160</p>
<p>Data: <span id="data"></span></p>
<h3>Result</h3>
<p>
<button type="button" id="button">Crop</button>
</p>
<div id="result"></div>
</div>
<script src="../js/cropper.js"></script>
<script>
window.addEventListener('DOMContentLoaded', function () {
var image = document.querySelector('#image');
var data = document.querySelector('#data');
var button = document.getElementById('button');
var result = document.getElementById('result');
var minCroppedWidth = 320;
var minCroppedHeight = 160;
var maxCroppedWidth = 640;
var maxCroppedHeight = 320;
var cropper = new Cropper(image, {
viewMode: 3,
data: {
width: (minCroppedWidth + maxCroppedWidth) / 2,
height: (minCroppedHeight + maxCroppedHeight) / 2,
},
crop: function (event) {
var width = event.detail.width;
var height = event.detail.height;
if (
width < minCroppedWidth
|| height < minCroppedHeight
|| width > maxCroppedWidth
|| height > maxCroppedHeight
) {
cropper.setData({
width: Math.max(minCroppedWidth, Math.min(maxCroppedWidth, width)),
height: Math.max(minCroppedHeight, Math.min(maxCroppedHeight, height)),
});
}
data.textContent = JSON.stringify(cropper.getData(true));
},
});
button.onclick = function () {
result.innerHTML = '';
result.appendChild(cropper.getCroppedCanvas());
};
});
</script>
</body>
</html>

View File

@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Cropper.js</title>
<link rel="stylesheet" href="../css/cropper.css">
<style>
.container {
margin: 20px auto;
max-width: 640px;
}
img {
max-width: 100%;
}
</style>
</head>
<body>
<div class="container">
<h1>Multiple Croppers</h1>
<h3>Cropper</h3>
<div>
<img src="../images/picture.jpg" alt="Picture">
</div>
<h3>Another</h3>
<div>
<img src="../images/picture.jpg" alt="Picture">
</div>
</div>
<script src="../js/cropper.js"></script>
<script>
window.addEventListener('DOMContentLoaded', function () {
var images = document.querySelectorAll('img');
var length = images.length;
var croppers = [];
var i;
for (i = 0; i < length; i++) {
croppers.push(new Cropper(images[i]));
}
});
</script>
</body>
</html>

View File

@@ -0,0 +1,70 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Cropper.js</title>
<link rel="stylesheet" href="../css/cropper.css">
<style>
.container {
margin: 20px auto;
max-width: 640px;
}
img {
max-width: 100%;
}
</style>
</head>
<body>
<div class="container">
<h1>One to one crop box</h1>
<p>The image displays in its natural size, so the size of the crop box size equals real cropped size.</p>
<h3>Image</h3>
<div>
<img id="image" src="../images/picture.jpg" alt="Picture">
</div>
<p>Data: <span id="data"></span></p>
<p>Crop Box Data: <span id="cropBoxData"></span></p>
<h3>Result</h3>
<p>
<button type="button" id="button">Crop</button>
</p>
<div id="result"></div>
</div>
<script src="../js/cropper.js"></script>
<script>
window.addEventListener('DOMContentLoaded', function () {
var image = document.querySelector('#image');
var data = document.querySelector('#data');
var cropBoxData = document.querySelector('#cropBoxData');
var button = document.getElementById('button');
var result = document.getElementById('result');
var cropper = new Cropper(image, {
ready: function (event) {
// Zoom the image to its natural size
cropper.zoomTo(1);
},
crop: function (event) {
data.textContent = JSON.stringify(cropper.getData());
cropBoxData.textContent = JSON.stringify(cropper.getCropBoxData());
},
zoom: function (event) {
// Keep the image in its natural size
if (event.detail.oldRatio === 1) {
event.preventDefault();
}
},
});
button.onclick = function () {
result.innerHTML = '';
result.appendChild(cropper.getCroppedCanvas());
};
});
</script>
</body>
</html>

View File

@@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Cropper.js</title>
<link rel="stylesheet" href="../css/cropper.css">
<style>
.container {
margin: 20px auto;
max-width: 640px;
}
img {
width: 100%;
}
</style>
</head>
<body>
<div class="container">
<h1>Cropper with responsive container</h1>
<p>
<button type="button" id="replace">Replace Image</button>
</p>
<div>
<img id="image" src="../images/picture.jpg" alt="Picture">
</div>
</div>
<script src="../js/cropper.js"></script>
<script>
window.addEventListener('DOMContentLoaded', function () {
var image = document.querySelector('#image');
var cropper = new Cropper(image, {
movable: false,
zoomable: false,
rotatable: false,
scalable: false
});
document.getElementById('replace').onclick = function () {
cropper.replace('../images/picture-2.jpg');
};
});
</script>
</body>
</html>

View File

@@ -0,0 +1,176 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Cropper.js</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" crossorigin="anonymous">
<link rel="stylesheet" href="../css/cropper.css">
<style>
.label {
cursor: pointer;
}
.progress {
display: none;
margin-bottom: 1rem;
}
.alert {
display: none;
}
.img-container img {
max-width: 100%;
}
</style>
</head>
<body>
<div class="container">
<h1>Upload cropped image to server</h1>
<label class="label" data-toggle="tooltip" title="Change your avatar">
<img class="rounded" id="avatar" src="https://avatars0.githubusercontent.com/u/3456749?s=160" alt="avatar">
<input type="file" class="sr-only" id="input" name="image" accept="image/*">
</label>
<div class="progress">
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">0%</div>
</div>
<div class="alert" role="alert"></div>
<div class="modal fade" id="modal" tabindex="-1" role="dialog" aria-labelledby="modalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalLabel">Crop the image</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="img-container">
<img id="image" src="https://avatars0.githubusercontent.com/u/3456749">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="crop">Crop</button>
</div>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
<script src="../js/cropper.js"></script>
<script>
window.addEventListener('DOMContentLoaded', function () {
var avatar = document.getElementById('avatar');
var image = document.getElementById('image');
var input = document.getElementById('input');
var $progress = $('.progress');
var $progressBar = $('.progress-bar');
var $alert = $('.alert');
var $modal = $('#modal');
var cropper;
$('[data-toggle="tooltip"]').tooltip();
input.addEventListener('change', function (e) {
var files = e.target.files;
var done = function (url) {
input.value = '';
image.src = url;
$alert.hide();
$modal.modal('show');
};
var reader;
var file;
var url;
if (files && files.length > 0) {
file = files[0];
if (URL) {
done(URL.createObjectURL(file));
} else if (FileReader) {
reader = new FileReader();
reader.onload = function (e) {
done(reader.result);
};
reader.readAsDataURL(file);
}
}
});
$modal.on('shown.bs.modal', function () {
cropper = new Cropper(image, {
aspectRatio: 1,
viewMode: 3,
});
}).on('hidden.bs.modal', function () {
cropper.destroy();
cropper = null;
});
document.getElementById('crop').addEventListener('click', function () {
var initialAvatarURL;
var canvas;
$modal.modal('hide');
if (cropper) {
canvas = cropper.getCroppedCanvas({
width: 160,
height: 160,
});
initialAvatarURL = avatar.src;
avatar.src = canvas.toDataURL();
$progress.show();
$alert.removeClass('alert-success alert-warning');
canvas.toBlob(function (blob) {
var formData = new FormData();
formData.append('avatar', blob, 'avatar.jpg');
$.ajax('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
data: formData,
processData: false,
contentType: false,
xhr: function () {
var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function (e) {
var percent = '0';
var percentage = '0%';
if (e.lengthComputable) {
percent = Math.round((e.loaded / e.total) * 100);
percentage = percent + '%';
$progressBar.width(percentage).attr('aria-valuenow', percent).text(percentage);
}
};
return xhr;
},
success: function () {
$alert.show().addClass('alert-success').text('Upload success');
},
error: function () {
avatar.src = initialAvatarURL;
$alert.show().addClass('alert-warning').text('Upload error');
},
complete: function () {
$progress.hide();
},
});
});
}
});
});
</script>
</body>
</html>

BIN
public/cropperjs/images/data.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

179
public/cropperjs/index.html Executable file
View File

@@ -0,0 +1,179 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Cropper.js</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" crossorigin="anonymous">
<link rel="stylesheet" href="/assets/css/cropper/cropper.min.css">
<style>
.label {
cursor: pointer;
}
.progress {
display: none;
margin-bottom: 1rem;
}
.alert {
display: none;
}
.img-container img {
max-width: 100%;
}
</style>
</head>
<body>
<div class="container">
<h1>Upload cropped image to server</h1>
<label class="label" data-toggle="tooltip" title="Change your avatar">
<img class="rounded" id="avatar" src="https://avatars0.githubusercontent.com/u/3456749?s=160" alt="avatar">
<input type="file" class="sr-only" id="input" name="image" accept="image/*">
</label>
<div class="progress">
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">0%</div>
</div>
<div class="alert" role="alert"></div>
<div class="modal fade" id="modal" tabindex="-1" role="dialog" aria-labelledby="modalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalLabel">Crop the image</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="img-container">
<img id="image" src="https://avatars0.githubusercontent.com/u/3456749">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="crop">Crop</button>
</div>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
<script src="/assets/js/cropper/cropper.min.js"></script>
<script>
window.addEventListener('DOMContentLoaded', function() {
var avatar = document.getElementById('avatar');
var image = document.getElementById('image');
var input = document.getElementById('input');
var $progress = $('.progress');
var $progressBar = $('.progress-bar');
var $alert = $('.alert');
var $modal = $('#modal');
var cropper;
$('[data-toggle="tooltip"]').tooltip();
input.addEventListener('change', function(e) {
var files = e.target.files;
var done = function(url) {
input.value = '';
image.src = url;
$alert.hide();
$modal.modal('show');
};
var reader;
var file;
var url;
if (files && files.length > 0) {
file = files[0];
if (URL) {
done(URL.createObjectURL(file));
} else if (FileReader) {
reader = new FileReader();
reader.onload = function(e) {
done(reader.result);
};
reader.readAsDataURL(file);
}
}
});
$modal.on('shown.bs.modal', function() {
cropper = new Cropper(image, {
aspectRatio: 1,
viewMode: 3,
});
}).on('hidden.bs.modal', function() {
cropper.destroy();
cropper = null;
});
document.getElementById('crop').addEventListener('click', function() {
var initialAvatarURL;
var canvas;
$modal.modal('hide');
if (cropper) {
canvas = cropper.getCroppedCanvas({
width: 160,
height: 160,
});
initialAvatarURL = avatar.src;
avatar.src = canvas.toDataURL();
$progress.show();
$alert.removeClass('alert-success alert-warning');
canvas.toBlob(function(blob) {
var formData = new FormData();
formData.append('avatar', blob, 'avatar.jpg');
$.ajax('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
data: formData,
processData: false,
contentType: false,
xhr: function() {
var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function(e) {
var percent = '0';
var percentage = '0%';
if (e.lengthComputable) {
percent = Math.round((e.loaded / e.total) * 100);
percentage = percent + '%';
$progressBar.width(percentage).attr('aria-valuenow', percent).text(percentage);
}
};
return xhr;
},
success: function() {
$alert.show().addClass('alert-success').text('Upload success');
},
error: function() {
avatar.src = initialAvatarURL;
$alert.show().addClass('alert-warning').text('Upload error');
},
complete: function() {
$progress.hide();
},
});
});
}
});
});
</script>
</body>
</html>

610
public/cropperjs/index.html- Executable file
View File

@@ -0,0 +1,610 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="JavaScript image cropper.">
<meta name="author" content="Chen Fengyuan">
<title>Cropper.js</title>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.11.2/css/all.css" crossorigin="anonymous">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" crossorigin="anonymous">
<link rel="stylesheet" href="css/cropper.css">
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<!--[if lt IE 9]>
<div class="alert alert-warning alert-dismissible fade show m-0 rounded-0" role="alert">
You are using an <strong>outdated</strong> browser. Please <a href="https://browsehappy.com/">upgrade your browser</a> to improve your experience.
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<![endif]-->
<!-- Header -->
<header class="navbar navbar-light navbar-expand-md">
<div class="container">
<a class="navbar-brand" href="./">Cropper.js</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar-collapse" aria-controls="navbar-collapse" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse justify-content-end" id="navbar-collapse" role="navigation">
<ul class="nav navbar-nav">
<li class="nav-item">
<a class="nav-link" href="https://github.com/fengyuanchen/cropperjs/blob/master/README.md" data-toggle="tooltip" title="View the documentation">Docs</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Examples
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
<a class="dropdown-item" href="examples/a-range-of-aspect-ratio.html">Cropper with a range of aspect ratio</a>
<a class="dropdown-item" href="examples/crop-a-round-image.html">Crop a round image</a>
<a class="dropdown-item" href="examples/crop-cross-origin-image.html">Crop cross origin image</a>
<a class="dropdown-item" href="examples/crop-on-canvas.html">Crop on canvas</a>
<a class="dropdown-item" href="examples/cropper-in-modal.html">Cropper in modal</a>
<a class="dropdown-item" href="examples/customize-preview.html">Customize preview</a>
<a class="dropdown-item" href="examples/fixed-crop-box.html">Fixed crop box</a>
<a class="dropdown-item" href="examples/full-crop-box.html">Full crop box</a>
<a class="dropdown-item" href="examples/mask-an-image.html">Mask an image</a>
<a class="dropdown-item" href="examples/minimum-and-maximum-cropped-dimensions.html">Minimum and maximum cropped dimensions</a>
<a class="dropdown-item" href="examples/multiple-croppers.html">Multiple croppers</a>
<a class="dropdown-item" href="examples/one-to-one-crop-box.html">One to one crop box</a>
<a class="dropdown-item" href="examples/responsive-container.html">Responsive container</a>
<a class="dropdown-item" href="examples/upload-cropped-image-to-server.html">Upload cropped image to server</a>
</div>
</li>
<li class="nav-item">
<a class="nav-link" href="https://fengyuanchen.github.io/photo-editor" data-toggle="tooltip" title="An advanced example of Cropper.js">Photo Editor</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://github.com/fengyuanchen/cropperjs" data-toggle="tooltip" title="View the GitHub project">GitHub</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://fengyuanchen.github.io/" data-toggle="tooltip" title="Explore more projects">Explore</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://chenfengyuan.com/" data-toggle="tooltip" title="About the author">About</a>
</li>
<li class="nav-item">
<a class="nav-link text-warning" href="https://fengyuanchen.github.io/cropper.js/" data-toggle="tooltip" title="View the next version">v2.0 (Alpha)</a>
</li>
</ul>
</div>
</div>
</header>
<!-- Jumbotron -->
<div class="jumbotron bg-primary text-white rounded-0">
<div class="container">
<div class="row">
<div class="col-md">
<h1>Cropper.js <small class="h6">v1.5.6</small></h1>
<p class="lead">JavaScript image cropper.</p>
</div>
<div class="col-md">
<div class="carbonads">
<script id="_carbonads_js" src="https://cdn.carbonads.com/carbon.js?serve=CKYI55Q7&placement=fengyuanchengithubio" async></script>
</div>
</div>
</div>
</div>
</div>
<!-- Content -->
<div class="container">
<div class="row">
<div class="col-md-9">
<!-- <h3>Demo:</h3> -->
<div class="img-container">
<img src="images/picture.jpg" alt="Picture">
</div>
</div>
<div class="col-md-3">
<!-- <h3>Preview:</h3> -->
<div class="docs-preview clearfix">
<div class="img-preview preview-lg"></div>
<div class="img-preview preview-md"></div>
<div class="img-preview preview-sm"></div>
<div class="img-preview preview-xs"></div>
</div>
<!-- <h3>Data:</h3> -->
<div class="docs-data">
<div class="input-group input-group-sm">
<span class="input-group-prepend">
<label class="input-group-text" for="dataX">X</label>
</span>
<input type="text" class="form-control" id="dataX" placeholder="x">
<span class="input-group-append">
<span class="input-group-text">px</span>
</span>
</div>
<div class="input-group input-group-sm">
<span class="input-group-prepend">
<label class="input-group-text" for="dataY">Y</label>
</span>
<input type="text" class="form-control" id="dataY" placeholder="y">
<span class="input-group-append">
<span class="input-group-text">px</span>
</span>
</div>
<div class="input-group input-group-sm">
<span class="input-group-prepend">
<label class="input-group-text" for="dataWidth">Width</label>
</span>
<input type="text" class="form-control" id="dataWidth" placeholder="width">
<span class="input-group-append">
<span class="input-group-text">px</span>
</span>
</div>
<div class="input-group input-group-sm">
<span class="input-group-prepend">
<label class="input-group-text" for="dataHeight">Height</label>
</span>
<input type="text" class="form-control" id="dataHeight" placeholder="height">
<span class="input-group-append">
<span class="input-group-text">px</span>
</span>
</div>
<div class="input-group input-group-sm">
<span class="input-group-prepend">
<label class="input-group-text" for="dataRotate">Rotate</label>
</span>
<input type="text" class="form-control" id="dataRotate" placeholder="rotate">
<span class="input-group-append">
<span class="input-group-text">deg</span>
</span>
</div>
<div class="input-group input-group-sm">
<span class="input-group-prepend">
<label class="input-group-text" for="dataScaleX">ScaleX</label>
</span>
<input type="text" class="form-control" id="dataScaleX" placeholder="scaleX">
</div>
<div class="input-group input-group-sm">
<span class="input-group-prepend">
<label class="input-group-text" for="dataScaleY">ScaleY</label>
</span>
<input type="text" class="form-control" id="dataScaleY" placeholder="scaleY">
</div>
</div>
</div>
</div>
<div class="row" id="actions">
<div class="col-md-9 docs-buttons">
<!-- <h3>Toolbar:</h3> -->
<div class="btn-group">
<button type="button" class="btn btn-primary" data-method="setDragMode" data-option="move" title="Move">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.setDragMode(&quot;move&quot;)">
<span class="fa fa-arrows-alt"></span>
</span>
</button>
<button type="button" class="btn btn-primary" data-method="setDragMode" data-option="crop" title="Crop">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.setDragMode(&quot;crop&quot;)">
<span class="fa fa-crop-alt"></span>
</span>
</button>
</div>
<div class="btn-group">
<button type="button" class="btn btn-primary" data-method="zoom" data-option="0.1" title="Zoom In">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.zoom(0.1)">
<span class="fa fa-search-plus"></span>
</span>
</button>
<button type="button" class="btn btn-primary" data-method="zoom" data-option="-0.1" title="Zoom Out">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.zoom(-0.1)">
<span class="fa fa-search-minus"></span>
</span>
</button>
</div>
<div class="btn-group">
<button type="button" class="btn btn-primary" data-method="move" data-option="-10" data-second-option="0" title="Move Left">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.move(-10, 0)">
<span class="fa fa-arrow-left"></span>
</span>
</button>
<button type="button" class="btn btn-primary" data-method="move" data-option="10" data-second-option="0" title="Move Right">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.move(10, 0)">
<span class="fa fa-arrow-right"></span>
</span>
</button>
<button type="button" class="btn btn-primary" data-method="move" data-option="0" data-second-option="-10" title="Move Up">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.move(0, -10)">
<span class="fa fa-arrow-up"></span>
</span>
</button>
<button type="button" class="btn btn-primary" data-method="move" data-option="0" data-second-option="10" title="Move Down">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.move(0, 10)">
<span class="fa fa-arrow-down"></span>
</span>
</button>
</div>
<div class="btn-group">
<button type="button" class="btn btn-primary" data-method="rotate" data-option="-45" title="Rotate Left">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.rotate(-45)">
<span class="fa fa-undo-alt"></span>
</span>
</button>
<button type="button" class="btn btn-primary" data-method="rotate" data-option="45" title="Rotate Right">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.rotate(45)">
<span class="fa fa-redo-alt"></span>
</span>
</button>
</div>
<div class="btn-group">
<button type="button" class="btn btn-primary" data-method="scaleX" data-option="-1" title="Flip Horizontal">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.scaleX(-1)">
<span class="fa fa-arrows-alt-h"></span>
</span>
</button>
<button type="button" class="btn btn-primary" data-method="scaleY" data-option="-1" title="Flip Vertical">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.scaleY(-1)">
<span class="fa fa-arrows-alt-v"></span>
</span>
</button>
</div>
<div class="btn-group">
<button type="button" class="btn btn-primary" data-method="crop" title="Crop">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.crop()">
<span class="fa fa-check"></span>
</span>
</button>
<button type="button" class="btn btn-primary" data-method="clear" title="Clear">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.clear()">
<span class="fa fa-times"></span>
</span>
</button>
</div>
<div class="btn-group">
<button type="button" class="btn btn-primary" data-method="disable" title="Disable">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.disable()">
<span class="fa fa-lock"></span>
</span>
</button>
<button type="button" class="btn btn-primary" data-method="enable" title="Enable">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.enable()">
<span class="fa fa-unlock"></span>
</span>
</button>
</div>
<div class="btn-group">
<button type="button" class="btn btn-primary" data-method="reset" title="Reset">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.reset()">
<span class="fa fa-sync-alt"></span>
</span>
</button>
<label class="btn btn-primary btn-upload" for="inputImage" title="Upload image file">
<input type="file" class="sr-only" id="inputImage" name="file" accept="image/*">
<span class="docs-tooltip" data-toggle="tooltip" title="Import image with Blob URLs">
<span class="fa fa-upload"></span>
</span>
</label>
<button type="button" class="btn btn-primary" data-method="destroy" title="Destroy">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.destroy()">
<span class="fa fa-power-off"></span>
</span>
</button>
</div>
<div class="btn-group btn-group-crop">
<button type="button" class="btn btn-success" data-method="getCroppedCanvas" data-option="{ &quot;maxWidth&quot;: 4096, &quot;maxHeight&quot;: 4096 }">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.getCroppedCanvas({ maxWidth: 4096, maxHeight: 4096 })">
Get Cropped Canvas
</span>
</button>
<button type="button" class="btn btn-success" data-method="getCroppedCanvas" data-option="{ &quot;width&quot;: 160, &quot;height&quot;: 90 }">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.getCroppedCanvas({ width: 160, height: 90 })">
160&times;90
</span>
</button>
<button type="button" class="btn btn-success" data-method="getCroppedCanvas" data-option="{ &quot;width&quot;: 320, &quot;height&quot;: 180 }">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.getCroppedCanvas({ width: 320, height: 180 })">
320&times;180
</span>
</button>
</div>
<!-- Show the cropped image in modal -->
<div class="modal fade docs-cropped" id="getCroppedCanvasModal" role="dialog" aria-hidden="true" aria-labelledby="getCroppedCanvasTitle" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="getCroppedCanvasTitle">Cropped</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body"></div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<a class="btn btn-primary" id="download" href="javascript:void(0);" download="cropped.jpg">Download</a>
</div>
</div>
</div>
</div><!-- /.modal -->
<button type="button" class="btn btn-secondary" data-method="getData" data-option data-target="#putData">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.getData()">
Get Data
</span>
</button>
<button type="button" class="btn btn-secondary" data-method="setData" data-target="#putData">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.setData(data)">
Set Data
</span>
</button>
<button type="button" class="btn btn-secondary" data-method="getContainerData" data-option data-target="#putData">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.getContainerData()">
Get Container Data
</span>
</button>
<button type="button" class="btn btn-secondary" data-method="getImageData" data-option data-target="#putData">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.getImageData()">
Get Image Data
</span>
</button>
<button type="button" class="btn btn-secondary" data-method="getCanvasData" data-option data-target="#putData">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.getCanvasData()">
Get Canvas Data
</span>
</button>
<button type="button" class="btn btn-secondary" data-method="setCanvasData" data-target="#putData">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.setCanvasData(data)">
Set Canvas Data
</span>
</button>
<button type="button" class="btn btn-secondary" data-method="getCropBoxData" data-option data-target="#putData">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.getCropBoxData()">
Get Crop Box Data
</span>
</button>
<button type="button" class="btn btn-secondary" data-method="setCropBoxData" data-target="#putData">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.setCropBoxData(data)">
Set Crop Box Data
</span>
</button>
<button type="button" class="btn btn-secondary" data-method="moveTo" data-option="0">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.moveTo(0)">
Move to [0,0]
</span>
</button>
<button type="button" class="btn btn-secondary" data-method="zoomTo" data-option="1">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.zoomTo(1)">
Zoom to 100%
</span>
</button>
<button type="button" class="btn btn-secondary" data-method="rotateTo" data-option="180">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.rotateTo(180)">
Rotate 180°
</span>
</button>
<button type="button" class="btn btn-secondary" data-method="scale" data-option="-2" data-second-option="-1">
<span class="docs-tooltip" data-toggle="tooltip" title="cropper.scale(-2, -1)">
Scale (-2, -1)
</span>
</button>
<textarea class="form-control" id="putData" placeholder="Get data to here or set data with this value"></textarea>
</div><!-- /.docs-buttons -->
<div class="col-md-3 docs-toggles">
<!-- <h3>Toggles:</h3> -->
<div class="btn-group d-flex flex-nowrap" data-toggle="buttons">
<label class="btn btn-primary active">
<input type="radio" class="sr-only" id="aspectRatio1" name="aspectRatio" value="1.7777777777777777">
<span class="docs-tooltip" data-toggle="tooltip" title="aspectRatio: 16 / 9">
16:9
</span>
</label>
<label class="btn btn-primary">
<input type="radio" class="sr-only" id="aspectRatio2" name="aspectRatio" value="1.3333333333333333">
<span class="docs-tooltip" data-toggle="tooltip" title="aspectRatio: 4 / 3">
4:3
</span>
</label>
<label class="btn btn-primary">
<input type="radio" class="sr-only" id="aspectRatio3" name="aspectRatio" value="1">
<span class="docs-tooltip" data-toggle="tooltip" title="aspectRatio: 1 / 1">
1:1
</span>
</label>
<label class="btn btn-primary">
<input type="radio" class="sr-only" id="aspectRatio4" name="aspectRatio" value="0.6666666666666666">
<span class="docs-tooltip" data-toggle="tooltip" title="aspectRatio: 2 / 3">
2:3
</span>
</label>
<label class="btn btn-primary">
<input type="radio" class="sr-only" id="aspectRatio5" name="aspectRatio" value="NaN">
<span class="docs-tooltip" data-toggle="tooltip" title="aspectRatio: NaN">
Free
</span>
</label>
</div>
<div class="btn-group d-flex flex-nowrap" data-toggle="buttons">
<label class="btn btn-primary active">
<input type="radio" class="sr-only" id="viewMode0" name="viewMode" value="0" checked>
<span class="docs-tooltip" data-toggle="tooltip" title="View Mode 0">
VM0
</span>
</label>
<label class="btn btn-primary">
<input type="radio" class="sr-only" id="viewMode1" name="viewMode" value="1">
<span class="docs-tooltip" data-toggle="tooltip" title="View Mode 1">
VM1
</span>
</label>
<label class="btn btn-primary">
<input type="radio" class="sr-only" id="viewMode2" name="viewMode" value="2">
<span class="docs-tooltip" data-toggle="tooltip" title="View Mode 2">
VM2
</span>
</label>
<label class="btn btn-primary">
<input type="radio" class="sr-only" id="viewMode3" name="viewMode" value="3">
<span class="docs-tooltip" data-toggle="tooltip" title="View Mode 3">
VM3
</span>
</label>
</div>
<div class="dropdown dropup docs-options">
<button type="button" class="btn btn-primary btn-block dropdown-toggle" id="toggleOptions" data-toggle="dropdown" aria-expanded="true">
Toggle Options
<span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu" aria-labelledby="toggleOptions">
<li class="dropdown-item">
<div class="form-check">
<input class="form-check-input" id="responsive" type="checkbox" name="responsive" checked>
<label class="form-check-label" for="responsive">responsive</label>
</div>
</li>
<li class="dropdown-item">
<div class="form-check">
<input class="form-check-input" id="restore" type="checkbox" name="restore" checked>
<label class="form-check-label" for="restore">restore</label>
</div>
</li>
<li class="dropdown-item">
<div class="form-check">
<input class="form-check-input" id="checkCrossOrigin" type="checkbox" name="checkCrossOrigin" checked>
<label class="form-check-label" for="checkCrossOrigin">checkCrossOrigin</label>
</div>
</li>
<li class="dropdown-item">
<div class="form-check">
<input class="form-check-input" id="checkOrientation" type="checkbox" name="checkOrientation" checked>
<label class="form-check-label" for="checkOrientation">checkOrientation</label>
</div>
</li>
<li class="dropdown-item">
<div class="form-check">
<input class="form-check-input" id="modal" type="checkbox" name="modal" checked>
<label class="form-check-label" for="modal">modal</label>
</div>
</li>
<li class="dropdown-item">
<div class="form-check">
<input class="form-check-input" id="guides" type="checkbox" name="guides" checked>
<label class="form-check-label" for="guides">guides</label>
</div>
</li>
<li class="dropdown-item">
<div class="form-check">
<input class="form-check-input" id="center" type="checkbox" name="center" checked>
<label class="form-check-label" for="center">center</label>
</div>
</li>
<li class="dropdown-item">
<div class="form-check">
<input class="form-check-input" id="highlight" type="checkbox" name="highlight" checked>
<label class="form-check-label" for="highlight">highlight</label>
</div>
</li>
<li class="dropdown-item">
<div class="form-check">
<input class="form-check-input" id="background" type="checkbox" name="background" checked>
<label class="form-check-label" for="background">background</label>
</div>
</li>
<li class="dropdown-item">
<div class="form-check">
<input class="form-check-input" id="autoCrop" type="checkbox" name="autoCrop" checked>
<label class="form-check-label" for="autoCrop">autoCrop</label>
</div>
</li>
<li class="dropdown-item">
<div class="form-check">
<input class="form-check-input" id="movable" type="checkbox" name="movable" checked>
<label class="form-check-label" for="movable">movable</label>
</div>
</li>
<li class="dropdown-item">
<div class="form-check">
<input class="form-check-input" id="rotatable" type="checkbox" name="rotatable" checked>
<label class="form-check-label" for="rotatable">rotatable</label>
</div>
</li>
<li class="dropdown-item">
<div class="form-check">
<input class="form-check-input" id="scalable" type="checkbox" name="scalable" checked>
<label class="form-check-label" for="scalable">scalable</label>
</div>
</li>
<li class="dropdown-item">
<div class="form-check">
<input class="form-check-input" id="zoomable" type="checkbox" name="zoomable" checked>
<label class="form-check-label" for="zoomable">zoomable</label>
</div>
</li>
<li class="dropdown-item">
<div class="form-check">
<input class="form-check-input" id="zoomOnTouch" type="checkbox" name="zoomOnTouch" checked>
<label class="form-check-label" for="zoomOnTouch">zoomOnTouch</label>
</div>
</li>
<li class="dropdown-item">
<div class="form-check">
<input class="form-check-input" id="zoomOnWheel" type="checkbox" name="zoomOnWheel" checked>
<label class="form-check-label" for="zoomOnWheel">zoomOnWheel</label>
</div>
</li>
<li class="dropdown-item">
<div class="form-check">
<input class="form-check-input" id="cropBoxMovable" type="checkbox" name="cropBoxMovable" checked>
<label class="form-check-label" for="cropBoxMovable">cropBoxMovable</label>
</div>
</li>
<li class="dropdown-item">
<div class="form-check">
<input class="form-check-input" id="cropBoxResizable" type="checkbox" name="cropBoxResizable" checked>
<label class="form-check-label" for="cropBoxResizable">cropBoxResizable</label>
</div>
</li>
<li class="dropdown-item">
<div class="form-check">
<input class="form-check-input" id="toggleDragModeOnDblclick" type="checkbox" name="toggleDragModeOnDblclick" checked>
<label class="form-check-label" for="toggleDragModeOnDblclick">toggleDragModeOnDblclick</label>
</div>
</li>
</ul>
</div><!-- /.dropdown -->
<a class="btn btn-success btn-block" data-toggle="tooltip" href="https://fengyuanchen.github.io/photo-editor" title="An advanced example of Cropper.js">Photo Editor</a>
</div><!-- /.docs-toggles -->
</div>
</div>
<!-- Footer -->
<footer class="footer">
<div class="container">
<p class="heart"></p>
<nav class="nav flex-wrap justify-content-center mb-3">
<a class="nav-link" href="https://github.com/fengyuanchen/cropperjs">GitHub</a>
<a class="nav-link" href="https://github.com/fengyuanchen/cropperjs/releases">Releases</a>
<a class="nav-link" href="https://github.com/fengyuanchen/cropperjs/blob/master/LICENSE">License</a>
<a class="nav-link" href="https://chenfengyuan.com/">About</a>
</nav>
</div>
</footer>
<!-- Scripts -->
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
<script src="https://fengyuanchen.github.io/shared/google-analytics.js" crossorigin="anonymous"></script>
<script src="js/cropper.js"></script>
<script src="js/main.js"></script>
</body>
</html>

3616
public/cropperjs/js/cropper.js Executable file

File diff suppressed because it is too large Load Diff

301
public/cropperjs/js/main.js Executable file
View File

@@ -0,0 +1,301 @@
window.onload = function () {
'use strict';
var Cropper = window.Cropper;
var URL = window.URL || window.webkitURL;
var container = document.querySelector('.img-container');
var image = container.getElementsByTagName('img').item(0);
var download = document.getElementById('download');
var actions = document.getElementById('actions');
var dataX = document.getElementById('dataX');
var dataY = document.getElementById('dataY');
var dataHeight = document.getElementById('dataHeight');
var dataWidth = document.getElementById('dataWidth');
var dataRotate = document.getElementById('dataRotate');
var dataScaleX = document.getElementById('dataScaleX');
var dataScaleY = document.getElementById('dataScaleY');
var options = {
aspectRatio: 16 / 9,
preview: '.img-preview',
ready: function (e) {
console.log(e.type);
},
cropstart: function (e) {
console.log(e.type, e.detail.action);
},
cropmove: function (e) {
console.log(e.type, e.detail.action);
},
cropend: function (e) {
console.log(e.type, e.detail.action);
},
crop: function (e) {
var data = e.detail;
console.log(e.type);
dataX.value = Math.round(data.x);
dataY.value = Math.round(data.y);
dataHeight.value = Math.round(data.height);
dataWidth.value = Math.round(data.width);
dataRotate.value = typeof data.rotate !== 'undefined' ? data.rotate : '';
dataScaleX.value = typeof data.scaleX !== 'undefined' ? data.scaleX : '';
dataScaleY.value = typeof data.scaleY !== 'undefined' ? data.scaleY : '';
},
zoom: function (e) {
console.log(e.type, e.detail.ratio);
}
};
var cropper = new Cropper(image, options);
var originalImageURL = image.src;
var uploadedImageType = 'image/jpeg';
var uploadedImageName = 'cropped.jpg';
var uploadedImageURL;
// Tooltip
$('[data-toggle="tooltip"]').tooltip();
// Buttons
if (!document.createElement('canvas').getContext) {
$('button[data-method="getCroppedCanvas"]').prop('disabled', true);
}
if (typeof document.createElement('cropper').style.transition === 'undefined') {
$('button[data-method="rotate"]').prop('disabled', true);
$('button[data-method="scale"]').prop('disabled', true);
}
// Download
if (typeof download.download === 'undefined') {
download.className += ' disabled';
download.title = 'Your browser does not support download';
}
// Options
actions.querySelector('.docs-toggles').onchange = function (event) {
var e = event || window.event;
var target = e.target || e.srcElement;
var cropBoxData;
var canvasData;
var isCheckbox;
var isRadio;
if (!cropper) {
return;
}
if (target.tagName.toLowerCase() === 'label') {
target = target.querySelector('input');
}
isCheckbox = target.type === 'checkbox';
isRadio = target.type === 'radio';
if (isCheckbox || isRadio) {
if (isCheckbox) {
options[target.name] = target.checked;
cropBoxData = cropper.getCropBoxData();
canvasData = cropper.getCanvasData();
options.ready = function () {
console.log('ready');
cropper.setCropBoxData(cropBoxData).setCanvasData(canvasData);
};
} else {
options[target.name] = target.value;
options.ready = function () {
console.log('ready');
};
}
// Restart
cropper.destroy();
cropper = new Cropper(image, options);
}
};
// Methods
actions.querySelector('.docs-buttons').onclick = function (event) {
var e = event || window.event;
var target = e.target || e.srcElement;
var cropped;
var result;
var input;
var data;
if (!cropper) {
return;
}
while (target !== this) {
if (target.getAttribute('data-method')) {
break;
}
target = target.parentNode;
}
if (target === this || target.disabled || target.className.indexOf('disabled') > -1) {
return;
}
data = {
method: target.getAttribute('data-method'),
target: target.getAttribute('data-target'),
option: target.getAttribute('data-option') || undefined,
secondOption: target.getAttribute('data-second-option') || undefined
};
cropped = cropper.cropped;
if (data.method) {
if (typeof data.target !== 'undefined') {
input = document.querySelector(data.target);
if (!target.hasAttribute('data-option') && data.target && input) {
try {
data.option = JSON.parse(input.value);
} catch (e) {
console.log(e.message);
}
}
}
switch (data.method) {
case 'rotate':
if (cropped && options.viewMode > 0) {
cropper.clear();
}
break;
case 'getCroppedCanvas':
try {
data.option = JSON.parse(data.option);
} catch (e) {
console.log(e.message);
}
if (uploadedImageType === 'image/jpeg') {
if (!data.option) {
data.option = {};
}
data.option.fillColor = '#fff';
}
break;
}
result = cropper[data.method](data.option, data.secondOption);
switch (data.method) {
case 'rotate':
if (cropped && options.viewMode > 0) {
cropper.crop();
}
break;
case 'scaleX':
case 'scaleY':
target.setAttribute('data-option', -data.option);
break;
case 'getCroppedCanvas':
if (result) {
// Bootstrap's Modal
$('#getCroppedCanvasModal').modal().find('.modal-body').html(result);
if (!download.disabled) {
download.download = uploadedImageName;
download.href = result.toDataURL(uploadedImageType);
}
}
break;
case 'destroy':
cropper = null;
if (uploadedImageURL) {
URL.revokeObjectURL(uploadedImageURL);
uploadedImageURL = '';
image.src = originalImageURL;
}
break;
}
if (typeof result === 'object' && result !== cropper && input) {
try {
input.value = JSON.stringify(result);
} catch (e) {
console.log(e.message);
}
}
}
};
document.body.onkeydown = function (event) {
var e = event || window.event;
if (e.target !== this || !cropper || this.scrollTop > 300) {
return;
}
switch (e.keyCode) {
case 37:
e.preventDefault();
cropper.move(-1, 0);
break;
case 38:
e.preventDefault();
cropper.move(0, -1);
break;
case 39:
e.preventDefault();
cropper.move(1, 0);
break;
case 40:
e.preventDefault();
cropper.move(0, 1);
break;
}
};
// Import image
var inputImage = document.getElementById('inputImage');
if (URL) {
inputImage.onchange = function () {
var files = this.files;
var file;
if (cropper && files && files.length) {
file = files[0];
if (/^image\/\w+/.test(file.type)) {
uploadedImageType = file.type;
uploadedImageName = file.name;
if (uploadedImageURL) {
URL.revokeObjectURL(uploadedImageURL);
}
image.src = uploadedImageURL = URL.createObjectURL(file);
cropper.destroy();
cropper = new Cropper(image, options);
inputImage.value = null;
} else {
window.alert('Please choose an image file.');
}
}
};
} else {
inputImage.disabled = true;
inputImage.parentNode.className += ' disabled';
}
};