mobile resize images
прошу подсказать как реализовать данную функцию есть страница загрузки логотипа и изменения его размеров загрузка логотипа все работает правильно за исключение сохранение рисунка после изменения его размеров на мобильном устройстве когда используют для масштабирования движения пальцами по экрану мобильного устройства При варианте изменения размеров рисунка передвигая угловые точки рисунка все работает также правильно.
$(document).on('click', '.user_img', function () {
$("#leftMenuImageSelect").click();
});
$(document).on('change', "#leftMenuImageSelect", function (evt) {
$(".LeftMenuLogo").removeClass('closed');
//load a file with html5 file api
var files = evt.target.files; // FileList object
var reader = new FileReader();
reader.onload = function (evt) {
imageData = reader.result;
loadData();
}
reader.readAsDataURL(files[0]);
});
$(document).on('click', '.close_btn_logo', function () {
$('.LeftMenuLogo').addClass('closed');
});
isEmpty = function (str) {
return (!str || 0 === str.length);
};
LogoSave = async function (imgLogoSrc) {
$('.LeftMenuLogo').addClass('closed');
let formData = new FormData();
formData.append('dataImage', imgLogoSrc);
alert_logo("Ваш новый логотип обновится после проверки его модератором сайта.", imgLogoSrc);
};
var resizeableImage = function (image_target) {
// Some variable and settings
var $container,
orig_src = new Image(),
image_target = $(image_target).get(0),
event_state = {},
min_width = 100,
min_height = 100,
max_width = 800,
max_height = 600,
init_height = 160, // Высота .resize-container
init_width = 160, // Ширина .resize-container
resize_canvas = document.createElement('canvas'),
crop_canvas = document.createElement('canvas');
imageData = null;
loadData = function () {
//установить цель изображения
image_target.src = imageData;
$(image_target).width(init_width);
// Назначить контейнер переменной
$container = $('.resize-container');
// Добавить события
$container.on('pointerdown touchstart', '.resize-handle', startResize);
$container.on('pointerdown touchstart', '.resize-container-ontop', startMoving);
$(document).on('click', '.btnSaveLogo', crop);
orig_src.src = image_target.src;
//установить изображение на единицу высоты
if ($(image_target).width() >= $(image_target).height()) {
$(image_target).css({
width: init_width,
height: 'auto'
});
$container.css('top', '79px');
}
else {
$(image_target).css({
width: 'auto',
height: init_height
});
$container.css('top', '68px');
}
//изменить размер холста (canvas)
$(orig_src).bind('load', function () {
resizeImageCanvas($(image_target).width(), $(image_target).height());
});
};
startResize = function (e) {
e.preventDefault();
e.stopPropagation();
saveEventState(e);
$(document).on('pointermove touchmove', resizing);
$(document).on('pointerup touchend', endResize);
};
endResize = function (e) {
resizeImageCanvas($(image_target).width(), $(image_target).height())
e.preventDefault();
$(document).off('pointerup touchend', endResize);
$(document).off('pointermove touchmove', resizing);
};
saveEventState = function (e) {
// Сохраните исходные сведения о событии и состояние контейнера.
event_state.container_width = $container.width();
event_state.container_height = $container.height();
event_state.container_left = $container.offset().left;
event_state.container_top = $container.offset().top;
event_state.mouse_x = (e.clientX || e.pageX || e.originalEvent.touches[0].clientX) + $(window).scrollLeft();
event_state.mouse_y = (e.clientY || e.pageY || e.originalEvent.touches[0].clientY) + $(window).scrollTop();
// Это исправление для мобильного сафари
// По какой-то причине он не позволяет прямую копию свойства touches
if (typeof e.originalEvent.touches !== 'undefined') {
event_state.touches = [];
$.each(e.originalEvent.touches, function (i, ob) {
event_state.touches[i] = {};
event_state.touches[i].clientX = 0 + ob.clientX;
event_state.touches[i].clientY = 0 + ob.clientY;
});
console.log(event_state.touches);
}
event_state.evnt = e;
};
resizing = function (e) {
var mouse = {}, width, height, left, top, offset = $container.offset();
mouse.x = (e.clientX || e.pageX || e.originalEvent.touches[0].clientX) + $(window).scrollLeft();
mouse.y = (e.clientY || e.pageY || e.originalEvent.touches[0].clientY) + $(window).scrollTop();
// Расположите изображение по-разному в зависимости от перетаскиваемого угла и ограничений
if ($(event_state.evnt.target).hasClass('resize-handle-se')) {
width = mouse.x - event_state.container_left;
height = mouse.y - event_state.container_top;
left = event_state.container_left;
top = event_state.container_top;
}
else if ($(event_state.evnt.target).hasClass('resize-handle-sw')) {
width = event_state.container_width - (mouse.x - event_state.container_left);
height = mouse.y - event_state.container_top;
left = mouse.x;
top = event_state.container_top;
}
else if ($(event_state.evnt.target).hasClass('resize-handle-nw')) {
width = event_state.container_width - (mouse.x - event_state.container_left);
height = event_state.container_height - (mouse.y - event_state.container_top);
left = mouse.x;
top = mouse.y;
if (e.shiftKey) {
top = mouse.y - ((width / orig_src.width * orig_src.height) - height);
}
}
else if ($(event_state.evnt.target).hasClass('resize-handle-ne')) {
width = mouse.x - event_state.container_left;
height = event_state.container_height - (mouse.y - event_state.container_top);
left = event_state.container_left;
top = mouse.y;
if (e.shiftKey) {
top = mouse.y - ((width / orig_src.width * orig_src.height) - height);
}
}
//При желании сохранить соотношение сторон
if (e.shiftKey) {
height = width / orig_src.width * orig_src.height;
}
if (width > min_width && height > min_height && width < max_width && height < max_height) {
// Для повышения производительности вы можете ограничить частоту вызова resizeImage().
resizeImage(width, height);
//Без этого Firefox не будет пересчитывать размеры изображения до конца перетаскивания.
$container.offset({ 'left': left, 'top': top });
}
};
resizeImage = function (width, height) {
$(image_target).width(width).height(height);
};
resizeImageCanvas = function (width, height) {
const ctx = resize_canvas.getContext("2d");
ctx.imageSmoothingQuality = "high";
ctx.imageSmoothingEnabled = false;
resize_canvas.width = width;
resize_canvas.height = height;
ctx.drawImage(orig_src, 0, 0, width, height);
$(image_target).attr('src', resize_canvas.toDataURL("image/png"));
};
startMoving = function (e) {
e.preventDefault();
e.stopPropagation();
saveEventState(e);
$(document).on('pointermove touchmove', moving);
$(document).on('pointerup touchend', endMoving);
};
endMoving = function (e) {
e.preventDefault();
$(document).off('pointerup touchend', endMoving);
$(document).off('pointermove touchmove', moving);
};
moving = function (e) {
var mouse = {}, touches;
e.preventDefault();
e.stopPropagation();
touches = e.originalEvent.touches;
mouse.x = (e.clientX || e.pageX || touches[0].clientX) + $(window).scrollLeft();
mouse.y = (e.clientY || e.pageY || touches[0].clientY) + $(window).scrollTop();
$container.offset({
'left': mouse.x - (event_state.mouse_x - event_state.container_left),
'top': mouse.y - (event_state.mouse_y - event_state.container_top)
});
// Следите за жестом масштабирования во время движения
if (event_state.touches && event_state.touches.length > 1 && touches.length > 1) {
var width = event_state.container_width, height = event_state.container_height;
var a = event_state.touches[0].clientX - event_state.touches[1].clientX;
a = a * a;
var b = event_state.touches[0].clientY - event_state.touches[1].clientY;
b = b * b;
var dist1 = Math.sqrt(a + b);
a = e.originalEvent.touches[0].clientX - touches[1].clientX;
a = a * a;
b = e.originalEvent.touches[0].clientY - touches[1].clientY;
b = b * b;
var dist2 = Math.sqrt(a + b);
var ratio = dist2 / dist1;
width = width * ratio;
height = height * ratio;
// Для повышения производительности вы можете ограничить частоту вызова resizeImage().
resizeImage(width, height);
}
};
crop = function () {
//Найдите часть изображения, которая находится внутри рамки обрезки
var left = $('.overlay-inner').offset().left - $container.offset().left,
top = $('.overlay-inner').offset().top - $container.offset().top,
width = $('.overlay-inner').width(),
height = $('.overlay-inner').height();
crop_canvas.width = width;
crop_canvas.height = height;
const crop_ctx = crop_canvas.getContext("2d");
crop_ctx.imageSmoothingQuality = "high"; // самое высокое качество
crop_ctx.imageSmoothingEnabled = false; // нарисовано с отключенным сглаживанием изображения
console.log(image_target);
crop_ctx.drawImage(image_target, left, top, width, height, 0, 0, width, height);
LogoSave(crop_canvas.toDataURL("image/png"));
};
};
// Целевое изображение
resizeableImage($('#resizeImage'));
// ✅ alert_logo == отображения Алерта с логотипом Юзера
alert_logo = function (content, imageScr) {
$('<div class="alertm_overlay"></div>').appendTo('body');
$('<div class="alertm_all" id="alertmAll">' +
'<div class="alertm_wrapper">' +
' <div class="alertm_h1">CHATFREE.PRO</div>' +
' <div class="floatLetf">' +
' <img class="imgLogo" title="Предварительный просмотр" src="' + imageScr + '" />' +
' </div>' +
' <div class="floatRight">' +
' <div class="alertm_text">' + content + '</div>' +
' </div>' +
'</div>' +
'<div class="alertm_but">OK</div>' +
'</div>')
.appendTo('body');
$(".alertm_overlay, .alertm_all").fadeIn("slow");
$('.alertm_but').on('click', function () {
$(".alertm_overlay, .alertm_all").remove();
});
};
// ✅ alert_logo == отображения Алерта с логотипом Юзера
.LeftMenuLogo { background-color: white; padding: 16px; z-index: 100; -webkit-transition: 400ms ease-out transform, 400ms ease-out opacity,700ms z-index; -o-transition: 400ms ease-out transform, 400ms ease-out opacity,700ms z-index; transition: 400ms ease-out transform, 400ms ease-out opacity,700ms z-index; background-color: white; width: 350px; height: 450px; position: absolute; top: 6%; left: calc(50% - 175px); text-align: center; -webkit-box-shadow: 0px 5px 11px 15px rgba(34, 60, 80, 0.31); -moz-box-shadow: 0px 5px 11px 15px rgba(34, 60, 80, 0.31); box-shadow: 0px 5px 11px 15px rgba(34, 60, 80, 0.31); }
.LeftMenuLogo .close_btn_logo { position: absolute; right: 26px; top: 8px; width: 16px; height: 16px; cursor: pointer; }
.LeftMenuLogo .close_btn_logo::after { content: ''; position: absolute; display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; width: 100%; height: 2px; border-radius: 1px; top: 50%; left: 50%; -webkit-transform: translate(50%, 50%); -ms-transform: translate(50%, 50%); transform: translate(50%, 50%); background-color: #01305c; }
.LeftMenuLogo .close_btn_logo::after { -webkit-transform: translate(50%, 50%) rotate(45deg); -ms-transform: translate(50%, 50%) rotate(45deg); transform: translate(50%, 50%) rotate(45deg); }
.LeftMenuLogo .close_btn_logo::before { content: ''; position: absolute; display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; width: 100%; height: 2px; border-radius: 1px; top: 50%; left: 50%; -webkit-transform: translate(50%, 50%); -ms-transform: translate(50%, 50%); transform: translate(50%, 50%); background-color: #01305c; }
.LeftMenuLogo .close_btn_logo::before { -webkit-transform: translate(50%, 50%) rotate(-45deg); -ms-transform: translate(50%, 50%) rotate(-45deg); transform: translate(50%, 50%) rotate(-45deg); }
.LeftMenuLogo.closed { opacity: 0; -webkit-transform: translateX(-200px); -ms-transform: translateX(-200px); transform: translateX(-200px); z-index: -1; }
.LeftMenuLogo .btnSaveLogo { cursor: pointer; z-index: 2000; position: relative; padding: 15px 0px; font-size: 10px; line-height: 16px; font-weight: 700; width: 180px; background-color: #01305c; text-align: center; display: inline-block; color: #FFFFFF; text-transform: uppercase; border: 2px solid transparent; -webkit-transition: 400ms ease-out color, 400ms ease-out background-color, 400ms ease-out border-color; -o-transition: 400ms ease-out color, 400ms ease-out background-color, 400ms ease-out border-color; transition: 400ms ease-out color, 400ms ease-out background-color, 400ms ease-out border-color; }
.LeftMenuLogo .btnSaveLogo:hover { text-decoration: none; color: #01305c; background-color: white; border-color: #01305c; }
.crop-wrapper { background-color: rgba(255,255,255,1); position: relative; width: 316px; height: 316px; overflow: hidden; margin: 26px auto; }
.crop-wrapper.closed { display: none; }
.crop-wrapper .resize-container { position: relative; display: inline-block; cursor: move; margin: 0 auto; text-align: center; }
.crop-wrapper .resize-container-ontop { position: absolute; cursor: move; background-color: rgba(5,255,5,0); z-index: 1000; width: 100%; height: 100%; }
.crop-wrapper .resize-container img { display: block; }
.crop-wrapper .resize-container:hover img, .crop-wrapper .resize-container:active img { outline: 2px dashed rgba(0,0,0,.9); }
.resize-handle-ne, .resize-handle-se, .resize-handle-nw, .resize-handle-sw { position: absolute; display: block; width: 10px; height: 10px; background: rgba(0,0,0,.9); z-index: 999; }
.crop-wrapper .resize-container .resize-handle-nw { top: -5px; left: -5px; cursor: nw-resize; }
.crop-wrapper .resize-container .resize-handle-sw { bottom: -5px; left: -5px; cursor: sw-resize; }
.crop-wrapper .resize-container .resize-handle-ne { top: -5px; right: -5px; cursor: ne-resize; }
.crop-wrapper .resize-container .resize-handle-se { bottom: -5px; right: -5px; cursor: se-resize; }
.crop-wrapper .overlay-before { position: absolute; z-index: 999; width: 316px; height: 316px; box-sizing: content-box; }
.crop-wrapper .overlay-before .overlay-inner { position: absolute; top: 25%; right: 25%; bottom: 25%; left: 25%; border-radius: 50%; -webkit-box-shadow: 0 0 0 600px rgba(0, 0, 0, .5); box-shadow: 0 0 0 600px rgba(0, 0, 0, .5); }
.crop-wrapper .overlay-before:before { top: 0; margin-left: -2px; margin-top: -40px; }
.crop-wrapper .overlay-before:after { bottom: 0; margin-left: -2px; margin-bottom: -40px; }
.crop-wrapper .overlay-before .overlay-inner:before { left: 0; margin-left: -40px; margin-top: -2px; }
.crop-wrapper .overlay-before .overlay-inner:after { right: 0; margin-right: -40px; margin-top: -2px; }
.confirm { z-index: 99999; }
.confirm_all { width: 100%; padding: 10px 20px; background: #fff; position: fixed; top: 50%; left: 50%; -webkit-transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%); transform: translate(-50%, -50%); }
@media (min-width: 767px) {
.confirm_all { max-width: 360px; }
}
.confirm_h1 { color: #2b8ff1; padding: 0px 10px 10px 10px; font-size: 19px; text-align: left; margin-top: 14px; margin-bottom: 14px; }
.confirm_text { font-size: 16px; line-height: 23px; padding: 0px 10px 10px 10px; margin-bottom: 14px; }
.confirm .confirminput { color: white; line-height: 46px; background-color: #e60f6f; padding: 0px 25px; -webkit-transition: 400ms ease-out background-color; -o-transition: 400ms ease-out background-color; transition: 400ms ease-out background-color; cursor: pointer; border: 0px; }
.confirm .confirminput.yes { margin-right: 50px; }
.confirm .confirminput.no { background-color: #2b8ff1; }
.confirm .confirminput:hover { background-color: #01305c; color: white; text-decoration: none; }
.confirm_fixed { position: fixed; width: 100%; height: 100%; background-color: rgba(1, 48, 92, 0.99); top: 0px; left: 0px; }
.confirm > div:last-of-type { min-width: 100px; }
.confirm > div:last-of-type div:last-of-type { text-align: right; }
.alertm_overlay { position: fixed; width: 100%; height: 100%; background-color: rgba(1, 48, 92, 0.99); top: 0px; left: 0px; display: none; z-index: 99999; }
.alertm_all { z-index: 99999; max-width: 360px; top: 45%; padding: 10px 20px; background: #fff; position: fixed; left: 50%; -webkit-transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%); transform: translate(-50%, -50%); }
.alertm_all .floatLetf { width: 22%; float: left; height: 100px; }
.alertm_all .alertm_wrapper .floatLetf .imgLogo { position: relative; border-radius: 50%; height: 80px; width: 80px; overflow: hidden; margin: 0 auto; -webkit-box-shadow: 0px 1px 3px 4px rgba(34, 60, 80, 0.31); -moz-box-shadow: 0px 1px 3px 4px rgba(34, 60, 80, 0.31); box-shadow: 0px 1px 3px 4px rgba(34, 60, 80, 0.31); top: 50%; left: 50%; -webkit-transform: translate(-50% -50%); -ms-transform: translate(-50% -50%); transform: translate(-50%, -50%); }
.alertm_all .floatRight { width: 74%; padding-top: 12px; float: right; height: 100px; }
.alertm_all a { -webkit-transition: all .2s ease-in-out; -o-transition: all .2s ease-in-out; transition: all .2s ease-in-out; text-decoration: none; color: #0275d8; }
.alertm_all a:hover { color: #222; }
.alertm_h1 { color: #2b8ff1; padding: 0px 10px 10px 10px; font-size: 19px; text-align: left; margin-top: 14px; margin-bottom: 14px; }
.alertm_text { font-size: 16px; line-height: 23px; padding: 0px 10px 10px 10px; margin-bottom: 14px; }
.alertm_but { color: white; line-height: 46px; background-color: #e60f6f; padding: 0px 25px; -webkit-transition: 400ms ease-out background-color; -o-transition: 400ms ease-out background-color; transition: 400ms ease-out background-color; cursor: pointer; border: 0px; width: 75px; float: right; }
.alertm_but:hover { background-color: #01305c; color: white; text-decoration: none; }
.alert_button { z-index: 99999; }
.alert_button_all { width: 100%; padding: 10px 20px; background: #fff; position: fixed; top: 50%; left: 50%; -webkit-transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%); transform: translate(-50%, -50%); }
@media (min-width: 767px) {
.alert_button_all { max-width: 360px; }
}
.alert_button_h1 { color: #2b8ff1; padding: 0px 10px 10px 10px; font-size: 19px; text-align: left; margin-top: 14px; margin-bottom: 14px; }
.alert_button_text { font-size: 16px; line-height: 23px; padding: 0px 10px 10px 10px; margin-bottom: 14px; }
.alert_button .alert_buttoninput { color: white; line-height: 46px; background-color: #e60f6f; padding: 0px 25px; -webkit-transition: 400ms ease-out background-color; -o-transition: 400ms ease-out background-color; transition: 400ms ease-out background-color; cursor: pointer; border: 0px; }
.alert_button .alert_buttoninput.ok { margin-right: 10px; }
.alert_button .alert_buttoninput:hover { background-color: #01305c; color: white; text-decoration: none; }
.alert_button_fixed { position: fixed; width: 100%; height: 100%; background-color: rgba(1, 48, 92, 0.99); top: 0px; left: 0px; }
.alert_button > div:last-of-type { min-width: 100px; }
.alert_button > div:last-of-type div:last-of-type { text-align: right; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="user_img no-photo">
<img src="" alt="Логотип организации" title="Логотип организации">
</div>
<div style="display: none">
<input type="file" name="leftMenuImageSelect" id="leftMenuImageSelect" accept="image/jpg, image/jpeg, image/png" />
</div>
<div class="LeftMenuLogo closed">
<div class="close_btn_logo"></div>
<div class="crop-wrapper">
<div class="overlay-before">
<div class="overlay-inner"></div>
</div>
<div class="resize-container">
<div class="resize-container-ontop"></div>
<span class="resize-handle resize-handle-nw"></span>
<span class="resize-handle resize-handle-ne"></span>
<img class="resize-image" alt=" " id="resizeImage" />
<span class="resize-handle resize-handle-sw"></span>
<span class="resize-handle resize-handle-se"></span>
</div>
</div>
<div class="btnSaveLogo">Сохранить</div>
</div>
С уважением Юрий