Browse Source

Fix cropper

master
Eduard Kuzmenko 4 years ago
parent
commit
97ef3b2276
  1. 218
      src/lib/cropper.ts
  2. 70
      src/scss/partials/_crop.scss
  3. 73
      src/scss/style.scss

218
src/lib/cropper.ts

@ -1,32 +1,29 @@
function resizeableImage(image_target: HTMLImageElement, resize_canvas?: HTMLCanvasElement) { function resizeableImage(originalImage: HTMLImageElement, canvas?: HTMLCanvasElement) {
var cropComponent: HTMLDivElement let cropComponent: HTMLDivElement,
, container: HTMLDivElement container: HTMLDivElement,
, crop_img: HTMLImageElement cropImage: HTMLImageElement,
, event_state: { event_state: Partial<{
mouse_x?: number, mouse_x: number,
mouse_y?: number, mouse_y: number,
container_width?: number, container_width: number,
container_height?: number, container_height: number,
container_left?: number, container_left: number,
container_top?: number container_top: number
} = {} }> = {},
, ratio = 1.0 keyZoomValue = 4.0,
, keyZoomValue = 4.0 MINWIDTH = 50,
, MINWIDTH = 50 MINHEIGHT = 50,
//, MINHEIGHT = 50 CROPWIDTH = 200,
, CROPWIDTH = 200 CROPHEIGHT = 200,
, CROPHEIGHT = 200 cropLeft = 0,
, cropLeft = 0 cropTop = 0,
, cropTop = 0 cropWidth = 0,
, cropWidth = 0 cropHeight = 0,
, cropHeight = 0; scaledRatio = 0;
if(image_target.complete) { if(originalImage.complete) init();
init(); else originalImage.onload = init;
} else {
image_target.onload = init;
}
function removeHandlers() { function removeHandlers() {
container.removeEventListener('mousedown', startMoving); container.removeEventListener('mousedown', startMoving);
@ -41,7 +38,7 @@ function resizeableImage(image_target: HTMLImageElement, resize_canvas?: HTMLCan
cropComponent.remove(); cropComponent.remove();
container.remove(); container.remove();
crop_img.remove(); cropImage.remove();
} }
function addHandlers() { function addHandlers() {
@ -54,70 +51,68 @@ function resizeableImage(image_target: HTMLImageElement, resize_canvas?: HTMLCan
} }
function init() { function init() {
var wraper, left, top; originalImage.classList.add('crop-blur');
originalImage.draggable = false;
if (image_target.dataset.isCrop) {
throw 'image is already crop'
}
image_target.dataset.isCrop = 'true'; cropImage = new Image();
image_target.classList.add('crop-blur'); cropImage.src = originalImage.src;
image_target.draggable = false; cropImage.draggable = false;
cropImage.classList.add('crop-overlay-image');
crop_img = new Image(); if(!canvas) {
crop_img.crossOrigin = image_target.crossOrigin; canvas = document.createElement('canvas');
crop_img.src = image_target.src;
crop_img.draggable = false;
if(!resize_canvas) {
resize_canvas = document.createElement('canvas');
} }
cropComponent = document.createElement('div'); cropComponent = document.createElement('div');
cropComponent.classList.add('crop-component'); cropComponent.classList.add('crop-component');
container = document.createElement('div'); container = document.createElement('div');
container.classList.add('overlay'); container.classList.add('crop-overlay');
let overlayColor = document.createElement('div'); const overlayColor = document.createElement('div');
overlayColor.classList.add('crop-overlay-color'); overlayColor.classList.add('crop-overlay-color');
cropComponent.appendChild(container); cropComponent.appendChild(container);
wraper = image_target.parentNode; const wrapper = originalImage.parentNode as HTMLElement;
wraper.appendChild(cropComponent); wrapper.appendChild(cropComponent);
cropComponent.appendChild(crop_img); cropComponent.appendChild(cropImage);
cropComponent.appendChild(image_target); cropComponent.appendChild(originalImage);
cropComponent.appendChild(overlayColor); cropComponent.appendChild(overlayColor);
container.appendChild(crop_img); container.appendChild(cropImage);
cropImage.style.maxWidth = originalImage.width + 'px';
crop_img.style.maxWidth = image_target.width + 'px'; scaledRatio = originalImage.naturalWidth / originalImage.offsetWidth;
left = image_target.offsetWidth / 2 - CROPWIDTH / 2; const left = originalImage.offsetWidth / 2 - CROPWIDTH / 2;
top = image_target.offsetHeight / 2 - CROPHEIGHT / 2; const top = originalImage.offsetHeight / 2 - CROPHEIGHT / 2;
updateCropSize(CROPWIDTH, CROPHEIGHT);
updateCropImage(left, top); updateCropImage(left, top);
updateContainer(left, top);
addHandlers(); addHandlers();
//crop();
} }
function updateCropSize(width: number, height: number) { function updateCropSize(width: number, height: number) {
cropWidth = width * scaledRatio;
cropHeight = height * scaledRatio;
container.style.width = width + 'px'; container.style.width = width + 'px';
container.style.height = height + 'px'; container.style.height = height + 'px';
} }
function updateCropImage(left: number, top: number) { function updateCropImage(left: number, top: number) {
cropLeft = -left * ratio; cropTop = top * scaledRatio;
cropTop = -top * ratio; cropLeft = left * scaledRatio;
crop_img.style.top = -top + 'px'; cropImage.style.top = -top + 'px';
crop_img.style.left = -left + 'px'; cropImage.style.left = -left + 'px';
} }
function updateContainer(left: number, top: number) { function updateContainer(left: number, top: number) {
let _top = top + (CROPWIDTH / 2) + 'px'; container.style.top = top + 'px';
let _left = left + (CROPHEIGHT / 2) + 'px'; container.style.left = left + 'px';
container.style.top = _top;
container.style.left = _left;
} }
// Save the initial event details and container state // Save the initial event details and container state
@ -134,18 +129,18 @@ function resizeableImage(image_target: HTMLImageElement, resize_canvas?: HTMLCan
function imgZoom(zoom: number) { function imgZoom(zoom: number) {
zoom = zoom * Math.PI * 2 zoom = zoom * Math.PI * 2
var newWidth = Math.floor(container.clientWidth + zoom) let newWidth = Math.floor(container.clientWidth + zoom),
, newHeight = Math.floor(container.clientHeight + zoom) newHeight = Math.floor(container.clientHeight + zoom),
, w = crop_img.clientWidth w = cropImage.clientWidth,
, h = crop_img.clientHeight h = cropImage.clientHeight,
, left left: number,
, top top: number,
, right right: number,
, bottom; bottom: number;
if(newWidth < MINWIDTH) { if(newWidth < MINWIDTH) {
return; return;
} else if (newWidth > w) { } else if(newWidth > w) {
return; return;
} }
@ -154,20 +149,11 @@ function resizeableImage(image_target: HTMLImageElement, resize_canvas?: HTMLCan
right = left + newWidth; right = left + newWidth;
bottom = top + newHeight; bottom = top + newHeight;
if(left < 0) { if(left < 0) left = 0;
left = 0; if(top < 0) top = 0;
}
if(top < 0) {
top = 0;
}
if(right > w) {
return;
}
if(bottom > h) {
return;
}
ratio = CROPWIDTH / newWidth; if(right > w) return;
if(bottom > h) return;
updateCropSize(newWidth, newWidth); updateCropSize(newWidth, newWidth);
updateCropImage(left, top); updateCropImage(left, top);
@ -215,68 +201,48 @@ function resizeableImage(image_target: HTMLImageElement, resize_canvas?: HTMLCan
} }
function moving(e: any) { function moving(e: any) {
var curuntTouch = {x: 0, y: 0} let currentTouch = {x: 0, y: 0},
, left left: number,
, top top: number,
, w w: number,
, h; h: number;
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
curuntTouch.x = e.pageX || e.touches && e.touches[0].pageX; currentTouch.x = e.pageX || e.touches && e.touches[0].pageX;
curuntTouch.y = e.pageY || e.touches && e.touches[0].pageY; currentTouch.y = e.pageY || e.touches && e.touches[0].pageY;
left = curuntTouch.x - (event_state.mouse_x - event_state.container_left); left = currentTouch.x - (event_state.mouse_x - event_state.container_left);
top = curuntTouch.y - (event_state.mouse_y - event_state.container_top); top = currentTouch.y - (event_state.mouse_y - event_state.container_top);
w = container.offsetWidth; w = container.offsetWidth;
h = container.offsetHeight; h = container.offsetHeight;
if(left < 0) { if(left < 0) left = 0;
left = 0; else if(left > cropImage.offsetWidth - w) left = cropImage.offsetWidth - w;
} else if (left > crop_img.offsetWidth - w) {
left = crop_img.offsetWidth - w; if(top < 0) top = 0;
} else if(top > cropImage.offsetHeight - h) top = cropImage.offsetHeight - h;
if(top < 0) {
top = 0;
} else if (top > crop_img.offsetHeight - h) {
top = crop_img.offsetHeight - h;
}
updateCropImage(left, top); updateCropImage(left, top);
updateContainer(left, top); updateContainer(left, top);
//crop();
} }
function crop() { function crop() {
cropWidth = crop_img.width * ratio; canvas.width = cropWidth;
cropHeight = crop_img.height * ratio; canvas.height = cropHeight;
resize_canvas.width = CROPWIDTH;
resize_canvas.height = CROPHEIGHT;
var ctx = resize_canvas.getContext('2d'); const ctx = canvas.getContext('2d');
ctx.drawImage(crop_img, ctx.drawImage(originalImage,
cropLeft, cropTop, cropLeft, cropTop,
cropWidth, cropHeight,
0, 0,
cropWidth, cropHeight cropWidth, cropHeight
); );
} }
return {crop, removeHandlers}; return {crop, removeHandlers};
/* function openCropCanvasImg() {
crop();
try {
var base64Img = resize_canvas.toDataURL('image/png', 1.0);
window.open(base64Img);
} catch(e) {
alert(e);
} finally {
// removeHandlers();
}
} */
} }
//resizeableImage(document.querySelector('.crop-image'));
export default resizeableImage; export default resizeableImage;

70
src/scss/partials/_crop.scss

@ -0,0 +1,70 @@
.crop {
.overlay::selection,
&-component::selection {
background: transparent;
}
/* .crop-blur {
-webkit-filter: blur(10px) sepia(0.2);
filter: blur(10px) sepia(0.2);
} */
&-image,
&-overlay-image {
width: auto;
height: auto;
/* можно явно указать либо ширину, либо высоту */
/* width: 500px; */
/*либо height: 300px;*/
display: block;
object-fit: contain;
object-position: center;
}
/*add stretch*/
&-image {
display: block;
position: relative;
pointer-events: none;
}
&-component {
position: relative;
z-index: 999;
background-color: white;
margin: 0 auto;
overflow: hidden;
> img {
max-width: 100%;
}
}
&-overlay {
position: absolute;
z-index: 999;
/* box-shadow: 0 0 0 3px white; */
overflow: hidden;
box-sizing: content-box;
border-radius: 50%;
html.no-touch &:hover, &:active {
cursor: move;
}
&-image {
position: absolute;
display: block;
}
&-color {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, .7);
border-radius: $border-radius;
}
}
}

73
src/scss/style.scss

@ -145,6 +145,7 @@ $chat-padding-handhelds: .5rem;
@import "partials/chatMarkupTooltip"; @import "partials/chatMarkupTooltip";
@import "partials/chatStickersHelper"; @import "partials/chatStickersHelper";
@import "partials/chatDrop"; @import "partials/chatDrop";
@import "partials/crop";
@import "partials/sidebar"; @import "partials/sidebar";
@import "partials/leftSidebar"; @import "partials/leftSidebar";
@import "partials/rightSidebar"; @import "partials/rightSidebar";
@ -651,78 +652,6 @@ img.emoji {
vertical-align: middle; vertical-align: middle;
} }
.overlay::selection {
background: transparent;
}
.crop-component::selection {
background: transparent;
}
/* .crop-blur {
-webkit-filter: blur(10px) sepia(0.2);
filter: blur(10px) sepia(0.2);
} */
.crop-image,
.overlay > img {
width: auto;
height: auto;
/* можно явно указать либо ширину, либо высоту */
/* width: 500px; */
/*либо height: 300px;*/
display: block;
object-fit: contain;
object-position: center;
}
/*add stretch*/
.crop-image {
display: block;
position: relative;
pointer-events: none;
}
.crop-component {
position: relative;
z-index: 999;
background-color: white;
margin: 0 auto;
overflow: hidden;
> img {
max-width: 100%;
}
.crop-overlay-color {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.7);
border-radius: $border-radius;
}
}
.overlay {
position: absolute;
left: 50%;
top: 50%;
z-index: 999;
margin-left: -100px;
margin-top: -100px;
width: 200px;
height: 200px;
/* box-shadow: 0 0 0 3px white; */
overflow: hidden;
box-sizing: content-box;
border-radius: 50%;
html.no-touch &:hover, &:active {
cursor: move;
}
> img {
position: absolute;
display: block;
}
}
[contenteditable=true] { [contenteditable=true] {
user-select: text; user-select: text;
outline: none; outline: none;

Loading…
Cancel
Save