Почему мышь плохо цепляется за элемент?

314
10 декабря 2016, 10:42

Картинка разделена на 9 квадратиков, если взяться за правый нижний и потянуть, то потянется сам контент, а потом, когда отпустишь, область будет "преследовать" курсор. Как этого избежать?

Так же будут ценны советы, что можно улучшить или упростить в коде, ибо пишу нечто подобное первый раз.

Не использую готовые библиотеки т.к. очень ценю трафик пользователей, видя вселенские библиотеки функционал которых мне использовать вообще не надо, меня начинает душить жаба

https://jsfiddle.net/yhpke1aw/

<head>
    <title>Cropper</title>
    <script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js?ver=3.4.2'></script>
</head>
<body>

<div class="image-crop">
    <div class="fide">
        <img src="picture.jpg">
        <div class="background"></div>
        <div class="select">
            <img src="picture.jpg">
            <div class="marking-x"></div>
            <div class="marking-y"></div>
        </div>
    </div>
    <div class="box">
        <img src="picture.jpg">
    </div>
</div>
<style type="text/css">
.image-crop {
}
.image-crop .background {
    background: rgba(0, 0, 0, 0.5);
    position: absolute;
    height: 100%;
    width: 100%;
    left: 0;
    top: 0;
}
.image-crop .select {
    display: block; 
    outline: 1px solid rgba(102, 153, 255, 0.75);
    background: rgba(255, 255, 255, 0.4);
    cursor: all-scroll;
    position: absolute;
    overflow: hidden;
    z-index: 2;
}
.image-crop .select img {
}
.image-crop .select .marking-x {
    border-bottom: 1px dashed rgba(255, 255, 255, 0.6);
    border-top: 1px dashed rgba(255, 255, 255, 0.6);
    height: 33.3333%;
    left: 0;
    position: absolute;
    top: 33.3333%;
    width: 100%;
}
.image-crop .select .marking-y {
    border-left: 1px dashed rgba(255, 255, 255, 0.6);
    border-right: 1px dashed rgba(255, 255, 255, 0.6);
    height: 100%;
    left: 33.3333%;
    position: absolute;
    top: 0;
    width: 33.3333%;
}
.image-crop .select .marking-y {
}
.image-crop .fide {
    display: inline-block; 
    position: relative;
    overflow: hidden;
    z-index: 1;
}
.image-crop .fide > img {
}
.image-crop .box {
    overflow: hidden;
    position: fixed;
    right: 0;
    top: 0;
}
.image-crop .box img {
}
</style>
<script type='text/javascript'>
var $imageCrop = $('.image-crop');
var $select = $imageCrop.find('.select');
var $fide = $imageCrop.find('.fide');
// Оригинал
// Уменьшеный оригинал - тот, который попорционально уменьшается, чтобы влезть на страницу
// Первью - изображение, которое обрезает див за счет overflow hidden
// Фон первью - уменьшеный оригинал под дивом внутри квадрата с первью
// Выделеный квадрат - див, который показывает, что мы выделели
// Фон выделеного квадрата изображения - уменьшеный оригинал под дивом внутри квадрата который показывает, что мы выделили
// Огигинальный выделеный квадрат - размер квадрата, которое мы реально будем вырезать если отбросить все уменьшения

var previewSize = 200; // Максимальная ширина и высота первью
//-- фикс. потом должно просчитываться само (пока что задаются тупо в лоб, чтоб не усложнять читаемость кода)
var originalImage = {w: 1280, h: 720}; // Размеры оригинала 
var reducedImage = {w: 500, h: 281}; // Размеры уменьшеного оригинала
//--
var reducedMaxSize = 500; // Максимальная ширина и высота уменьшеного оригинала

var cropX = 730; // Координата X выделеного квадрата
var cropY = 130; // Координата X выделеного квадрата
var selectdSize = 400; // Ширина и высота оригинального выделеного квадрата
// Поправка по координатам при клике, чтобы окошко выделения не уехало
var correctX = 0;
var correctY = 0;
// На сколько уменьшеный оригинал меньше самого оригинала
var selectRatio = originalImage.w / reducedImage.w;


// Обновление выделеной области
function UpdateSelected(){
    // На сколько уменьшеный оригинал меньше самого оригинала
    selectRatio = originalImage.w / reducedImage.w;

    // Не даем выделеному квадрату выйти за пределы
    if(cropX + selectdSize - correctX * selectRatio >= originalImage.w){
        cropX = originalImage.w - selectdSize + correctX * selectRatio;
    }else if(cropX - correctX * selectRatio <= 0){
        cropX = correctX * selectRatio;
    }
    if(cropY + selectdSize - correctY * selectRatio >= originalImage.h){
        cropY = originalImage.h - selectdSize + correctY * selectRatio;
    }else if(cropY - correctY * selectRatio <= 0){
        cropY = correctY * selectRatio;
    }

    // Корекция фона выделеного квадрата
    $select.find('img').css({
        width: originalImage.w / selectRatio,
        height: originalImage.h / selectRatio,
        marginLeft: -(cropX / selectRatio) + correctX,
        marginTop: -(cropY / selectRatio) + correctY
    });
    // Корекция выделеного квадрата
    $select.css({
        width: selectdSize / selectRatio,
        height: selectdSize / selectRatio,
        left: (cropX / selectRatio) - correctX,
        top: (cropY / selectRatio) - correctY
    });
}

// Обновление превью
function UpdatePreview(){
    var boxRatio = selectdSize / previewSize;
    var width = originalImage.w / boxRatio;
    var height = originalImage.h / boxRatio;
    // Корекция фона превью
    $imageCrop.find('.box img').css({
        width: width,
        height: height,
        marginLeft: -(cropX / boxRatio) + correctX / (reducedImage.w / width),
        marginTop: -(cropY / boxRatio) + correctY / (reducedImage.h / height)
    });
}

// Главное окно
$fide.find('img').css({
    maxWidth: reducedMaxSize,
    maxHeight: reducedMaxSize
});
// Размер блока превью
$imageCrop.find('.box').css({
    height: previewSize,
    width: previewSize
});


$fide.mousemove(function(e){
    if($select.data('active')){
        cropX = (e.pageX - $(this).offset().left) * selectRatio;
        cropY = (e.pageY - $(this).offset().top) * selectRatio;
        UpdateSelected();
        UpdatePreview();
    }
});
$select.mousedown(function(e){
    $(this).data('active', true);
    correctX = e.pageX - $(this).offset().left;
    correctY = e.pageY - $(this).offset().top;
}).mouseup(function(){
    $(this).data('active', false);
});

UpdateSelected();
UpdatePreview();
</script>

</body>
READ ALSO
Добавление превью картинки к видео в iframe

Добавление превью картинки к видео в iframe

В iframe загружается видео <iframe width="585" height="345" src="//wwwyoutube

1396
Как вывести значения функции Javascript в HTML?

Как вывести значения функции Javascript в HTML?

Как вывести значение first_name в блок div?

459
Проблемы с адаптивной версткой

Проблемы с адаптивной версткой

Всем доброго времени сутокПри верстке своей портфолио страницы столкнулся с проблемой

297
Использование html в базе данных sqlite

Использование html в базе данных sqlite

В strings использовать html можно, достаточно поместить тест с html тегами между <![CDATA[ и ]]>, а дальше вызывая из strings в TextView подключить html, если необходимы...

314