Fix cropper
This commit is contained in:
parent
fe8a54ea62
commit
97ef3b2276
@ -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) {
|
cropImage = new Image();
|
||||||
throw 'image is already crop'
|
cropImage.src = originalImage.src;
|
||||||
}
|
cropImage.draggable = false;
|
||||||
|
cropImage.classList.add('crop-overlay-image');
|
||||||
|
|
||||||
image_target.dataset.isCrop = 'true';
|
if(!canvas) {
|
||||||
image_target.classList.add('crop-blur');
|
canvas = document.createElement('canvas');
|
||||||
image_target.draggable = false;
|
|
||||||
|
|
||||||
crop_img = new Image();
|
|
||||||
crop_img.crossOrigin = image_target.crossOrigin;
|
|
||||||
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);
|
||||||
|
|
||||||
crop_img.style.maxWidth = image_target.width + 'px';
|
cropImage.style.maxWidth = originalImage.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,21 +149,12 @@ 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) {
|
if(right > w) return;
|
||||||
top = 0;
|
if(bottom > h) return;
|
||||||
}
|
|
||||||
if(right > w) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(bottom > h) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ratio = CROPWIDTH / newWidth;
|
|
||||||
|
|
||||||
updateCropSize(newWidth, newWidth);
|
updateCropSize(newWidth, newWidth);
|
||||||
updateCropImage(left, top);
|
updateCropImage(left, top);
|
||||||
updateContainer(left, top);
|
updateContainer(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;
|
const ctx = canvas.getContext('2d');
|
||||||
resize_canvas.height = CROPHEIGHT;
|
ctx.drawImage(originalImage,
|
||||||
|
|
||||||
var ctx = resize_canvas.getContext('2d');
|
|
||||||
ctx.drawImage(crop_img,
|
|
||||||
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
Normal file
70
src/scss/partials/_crop.scss
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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…
x
Reference in New Issue
Block a user