This commit is contained in:
Ilya Kantor 2014-10-26 22:10:13 +03:00
parent 06f61d8ce8
commit f301cb744d
2271 changed files with 103162 additions and 0 deletions

View file

@ -0,0 +1,21 @@
# HTML/CSS
Область выделения можно оформить как `DIV`, серого цвета, полупрозрачный, с рамкой:
```css
.crop-area {
position: absolute;
border: 1px dashed black;
background: #F5DEB3;
opacity: 0.3;
filter:alpha(opacity=30); /* IE opacity */
}
```
# Решение
[edit src="solution"]Открыть в песочнице[/edit]
Обратите внимание: обработчики `mousemove/mouseup` ставятся на `document`, не на элемент.
Это для того, чтобы посетитель мог начать выделение на элементе, а продолжить и завершить его, двигая зажатой мышкой снаружи, вне его границ.

View file

@ -0,0 +1 @@
{"name":"croppable","plunk":"jfa42pG0GXeZUOgHK6MQ"}

View file

@ -0,0 +1 @@
{"name":"croppable","plunk":"jfa42pG0GXeZUOgHK6MQ"}

View file

@ -0,0 +1,130 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://code.jquery.com/jquery.min.js"></script>
<style>
.crop-area {
position: absolute;
border: 1px dashed black;
background: #F5DEB3;
opacity: 0.3;
filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30); /* IE opacity */
}
</style>
</head>
<body>
<img width="500" height="282" id="heroes" src="http://js.cx/clipart/heroes.jpg">
<div id="info"></div>
<script>
function Croppable(options) {
var self = this;
var elem = options.elem;
var cropArea;
var cropStartX, cropStartY;
elem.on('selectstart dragstart', false)
.on('mousedown', onImgMouseDown);
function initCropArea(pageX, pageY) {
cropArea = $('<div class="crop-area"/>')
.appendTo('body');
cropStartX = pageX;
cropStartY = pageY;
}
function onDocumentMouseMove(e) {
drawCropArea(e.pageX, e.pageY);
}
function onDocumentMouseUp(e) {
endCrop(e.pageX, e.pageY);
cropArea.remove();
$(document).off('.croppable');
}
function onImgMouseDown(e) {
initCropArea(e.pageX, e.pageY);
$(document).on({
'mousemove.croppable': onDocumentMouseMove,
'mouseup.croppable': onDocumentMouseUp
});
return false;
};
function drawCropArea(pageX, pageY) {
var dims = getCropDimensions(pageX, pageY);
cropArea.css(dims);
// вычитаем 2, т.к. ширина будет дополнена рамкой
// если не вычесть, то рамка может вылезти за изображение
cropArea.css({
height: Math.max(dims.height-2, 0),
width: Math.max(dims.width-2,0)
});
// здесь мы просто рисуем полупрозрачный квадрат
// альтернативный подход - накладывать на каждую часть изображения div'ы с opacity и черным цветом, чтобы только кроп был ярким
}
function endCrop(pageX, pageY) {
var dims = getCropDimensions(pageX, pageY);
var coords = elem.offset();
// получить координаты относительно изображения
dims.left -= coords.left;
dims.top -= coords.top;
$(self).triggerHandler($.extend({ type: "crop" }, dims));
}
function getCropDimensions(pageX, pageY) {
// 1. Делаем квадрат из координат нажатия и текущих
// 2. Ограничиваем размерами img, если мышь за его пределами
var left = Math.min(cropStartX, pageX);
var right = Math.max(cropStartX, pageX);
var top = Math.min(cropStartY, pageY);
var bottom = Math.max(cropStartY, pageY);
var coords = elem.offset();
left = Math.max(left, coords.left);
top = Math.max(top, coords.top);
right = Math.min(right, coords.left + elem.outerWidth());
bottom = Math.min(bottom, coords.top + elem.outerHeight());
return { left: left, top: top, width: right-left, height: bottom-top };
}
}
var croppable = new Croppable({
elem: $('#heroes')
});
$(croppable).on("crop", function(event) {
// вывести координаты и размеры crop-квадрата относительно изображения
var str = "";
$(['left','top','width','height']).each(function() {
str += this+":"+event[this]+" ";
});
$('#info').html("Crop: " + str);
});
</script>
</body>
</html>

View file

@ -0,0 +1,130 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://code.jquery.com/jquery.min.js"></script>
<style>
.crop-area {
position: absolute;
border: 1px dashed black;
background: #F5DEB3;
opacity: 0.3;
filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30); /* IE opacity */
}
</style>
</head>
<body>
<img width="500" height="282" id="heroes" src="http://js.cx/clipart/heroes.jpg">
<div id="info"></div>
<script>
function Croppable(options) {
var self = this;
var elem = options.elem;
var cropArea;
var cropStartX, cropStartY;
elem.on('selectstart dragstart', false)
.on('mousedown', onImgMouseDown);
function initCropArea(pageX, pageY) {
cropArea = $('<div class="crop-area"/>')
.appendTo('body');
cropStartX = pageX;
cropStartY = pageY;
}
function onDocumentMouseMove(e) {
drawCropArea(e.pageX, e.pageY);
}
function onDocumentMouseUp(e) {
endCrop(e.pageX, e.pageY);
cropArea.remove();
$(document).off('.croppable');
}
function onImgMouseDown(e) {
initCropArea(e.pageX, e.pageY);
$(document).on({
'mousemove.croppable': onDocumentMouseMove,
'mouseup.croppable': onDocumentMouseUp
});
return false;
};
function drawCropArea(pageX, pageY) {
var dims = getCropDimensions(pageX, pageY);
cropArea.css(dims);
// вычитаем 2, т.к. ширина будет дополнена рамкой
// если не вычесть, то рамка может вылезти за изображение
cropArea.css({
height: Math.max(dims.height-2, 0),
width: Math.max(dims.width-2,0)
});
// здесь мы просто рисуем полупрозрачный квадрат
// альтернативный подход - накладывать на каждую часть изображения div'ы с opacity и черным цветом, чтобы только кроп был ярким
}
function endCrop(pageX, pageY) {
var dims = getCropDimensions(pageX, pageY);
var coords = elem.offset();
// получить координаты относительно изображения
dims.left -= coords.left;
dims.top -= coords.top;
$(self).triggerHandler($.extend({ type: "crop" }, dims));
}
function getCropDimensions(pageX, pageY) {
// 1. Делаем квадрат из координат нажатия и текущих
// 2. Ограничиваем размерами img, если мышь за его пределами
var left = Math.min(cropStartX, pageX);
var right = Math.max(cropStartX, pageX);
var top = Math.min(cropStartY, pageY);
var bottom = Math.max(cropStartY, pageY);
var coords = elem.offset();
left = Math.max(left, coords.left);
top = Math.max(top, coords.top);
right = Math.min(right, coords.left + elem.outerWidth());
bottom = Math.min(bottom, coords.top + elem.outerHeight());
return { left: left, top: top, width: right-left, height: bottom-top };
}
}
var croppable = new Croppable({
elem: $('#heroes')
});
$(croppable).on("crop", function(event) {
// вывести координаты и размеры crop-квадрата относительно изображения
var str = "";
$(['left','top','width','height']).each(function() {
str += this+":"+event[this]+" ";
});
$('#info').html("Crop: " + str);
});
</script>
</body>
</html>

View file

@ -0,0 +1,31 @@
# Выбор фрагмента картинки мышью
[importance 3]
Реализуйте интерфейс для выбора фрагмента изображения мышью.
Нажмите на изображении и проведите мышью для выбора:
[iframe height=350 src="solution" link]
По окончании смены размеров должно быть событие `crop` c `left/top` координатами и `width/height` размерами выбранной области.
Синтаксис:
```js
var croppable = new Croppable({
elem: $('#heroes')
});
$(croppable).on("crop", function(e) {
// вывести crop-квадрат, left/top - относительно изображения
// e.left, e.top, e.width, e.height
});
```
<ul>
<li>Область можно выбирать, двигая курсором в любую сторону от исходной точки.</li>
<li>Область не может вылезать за пределы изображения.</li>
</ul>
[edit src="task" task/]

View file

@ -0,0 +1 @@
{"name":"croppable-src","plunk":"kjVYThtx5sIyEmV8MhGT"}

View file

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://code.jquery.com/jquery.min.js"></script>
</head>
<body>
<img width="500" height="282" id="heroes" src="http://js.cx/clipart/heroes.jpg">
<div id="info"></div>
<script>
function Croppable(options) {
/* ваш код */
}
var croppable = new Croppable({
elem: $('#heroes')
});
$(croppable).on("crop", function(event) {
// вывести координаты и размеры crop-квадрата относительно изображения
var str = "";
$(['left','top','width','height']).each(function() {
str += this+":"+event[this]+" ";
});
$('#info').html("Crop: " + str);
});
</script>
</body>
</html>