<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>cropIt.js</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
</head>
<style>
html {
height: 100%;
width: 100%;
background: linear-gradient(45deg, #bbb 25%, transparent 25%, transparent 75%, #bbb 75%, #bbb) 5px 5px,
linear-gradient(45deg, #bbb 25%, #eee 25%, #eee 75%, #bbb 75%, #bbb) 15px 15px;
background-size: 20px 20px;
cursor: default;
user-select: none;
-webkit-user-drag: none; /* !!!ОСТОРОЖНО!!!, нестандартный код */
user-drag: none;
}
body {
height: 100%;
margin: 0;
}
img {
max-width: calc(100vw - 2em);
max-height: calc(100vh - 2em);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.5);
background: rgba(0, 0, 0, 0.4);
transform: translate(calc(-50% + 50vw), calc(-50% + 50vh)) scale(1);
display: block;
cursor: crosshair;
}
/* img /deep/ .cropper {*/
.cropper {
position: absolute;
pointer-events: none;
opacity: 0.7;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(90deg, black var(--low-x), transparent 0, transparent var(--high-x), black 0),
linear-gradient(180deg, black var(--low-y), transparent 0, transparent var(--high-y), black 0);
max-width: calc(100vw - 2em);
max-height: calc(100vh - 2em);
transform: translate(calc(-50% + 50vw), calc(-50% + 50vh)) scale(1);
}
#info, #logo {
background: rgba(0, 0, 0, 0.4);
text-shadow: 0 1px black;
color: white;
position: absolute;
bottom: 0;
left: 50%;
margin: auto;
transform: translateX(-50%);
padding: 1em;
z-index: 1;
font: bold 1em Menlo, Consolas, monospace;
box-shadow: 0 0 1px white;
pointer-events: none;
border-radius: 5px 5px 0 0;
}
#logo {
bottom: auto;
top: 0;
padding: 0.5em;
font-weight: normal;
font-size: 1.5em;
border-radius: 0 0 5px 5px;
}
#logo::after {
content: "by Malleys";
position: absolute;
font-size: 50%;
bottom: 0.3em;
right: 0.2em;
opacity: 0.8;
}
</style>
<body>
<div id="logo">Crop✂it</div>
<span id="info">Выдели часть изображения и здесь появится информация</span>
<img src="http://wallpaperscraft.com/image/fruit_lemon_orange_kiwi_banana_apple_113092_4896x3264.jpg">
<script>
(function() {
var _ = function Cropper(image) {
if(!(this instanceof Cropper)) return new _(image);
this.cropper = document.createElement("div");
this.cropper.className = "cropper";
this.image = image;
// пришлось создать элемент-обёртку :( :( :(
// Uncaught DOMException: Failed to execute 'createShadowRoot' on 'Element':
// Author-created shadow roots are disabled for 'img' element.
var imageWrapper = document.createElement("div");
imageWrapper.style.position = "absolute";
this.image.parentNode.insertBefore(imageWrapper, this.image);
this.image.parentNode.removeChild(this.image);
imageWrapper.appendChild(this.image);
imageWrapper.appendChild(this.cropper);
this.image.addEventListener("mousedown", this.onPointerStart.bind(this));
this.image.addEventListener("mousemove", this.onPointerMove.bind(this));
document.addEventListener("mouseup", this.onPointerUp.bind(this));
this.points = {};
this.cropperInProcess = false;
// Mozilla bug fixing
this.image.setAttribute("ondragstart", "return false");
}
_.prototype = {
onPointerStart: function(event) {
// первая нужная точка
// здесь выясняется в какую часть картинки щёлкнули
this.points.x = [event.offsetX / this.image.width, event.offsetX / this.image.width];
this.points.y = [event.offsetY / this.image.height, event.offsetY / this.image.height];
this.cropperInProcess = true;
},
onPointerMove: function(event) {
if(!this.cropperInProcess) return;
// вторая точка обновляется пока двигаем мышь
this.points.x[1] = event.offsetX / this.image.width;
this.points.y[1] = event.offsetY / this.image.height;
this.update();
},
onPointerUp: function(event) {
this.cropperInProcess = false;
},
update: function() {
info.innerHTML = this.points.x;
// координаты северо-западного угла
this.points.nw = {
x: Math.min.apply(null, this.points.x),
y: Math.min.apply(null, this.points.y)
};
// координаты южно-восточного угла
this.points.se = {
x: Math.max.apply(null, this.points.x),
y: Math.max.apply(null, this.points.y)
};
this.onUpdate();
},
onUpdate: function() {
// здесь используются полученные данные
this.cropper.setAttribute("style", [
"--low-x: " + (100 * this.points.nw.x) + "%",
"--low-y: " + (100 * this.points.nw.y) + "%",
"--high-x: " + (100 * this.points.se.x) + "%",
"--high-y: " + (100 * this.points.se.y) + "%"
].join("; "));
info.textContent = "crop(" +[
"low-x: " + (100 * this.points.nw.x | 0) + "%",
"low-y: " + (100 * this.points.nw.y | 0) + "%",
"high-x: " + (100 * this.points.se.x | 0) + "%",
"high-y: " + (100 * this.points.se.y | 0) + "%"
].join("; ") + ")";
}
};
Array.from(document.images).forEach(_);
})();
</script>
</body>
</html>