feat(Mask.svelte-ImageShow.svelte): crop image

BREAKING CHANGE:
This commit is contained in:
songsenand 2023-01-08 00:37:17 +08:00
parent 60ed3faf63
commit 701549f752
2 changed files with 331 additions and 118 deletions

View File

@ -21,6 +21,7 @@
let canvas_height = 0; let canvas_height = 0;
let mask_tag = false; let mask_tag = false;
let crop_rect = {};
function LabelItem(label, items) { function LabelItem(label, items) {
this.label = label; this.label = label;
@ -65,9 +66,9 @@
"裁剪", "裁剪",
"mdi mdi-crop", "mdi mdi-crop",
() => { () => {
console.log(mask_tag); image_process.roi_init();
show_image();
mask_tag = mask_tag ? false : true; mask_tag = mask_tag ? false : true;
console.log(mask_tag);
}, },
], ],
[ [
@ -281,7 +282,13 @@
<div class="column" style="text-align:center"> <div class="column" style="text-align:center">
<div> <div>
{#if mask_tag} {#if mask_tag}
<Mask {canvas_dom} /> <Mask
{canvas_dom}
on:maskclose={(e) => {
mask_tag = false;
console.log(e);
}}
/>
{/if} {/if}
<canvas <canvas
bind:this={canvas_dom} bind:this={canvas_dom}

View File

@ -1,14 +1,22 @@
<script> <script>
import { onMount } from "svelte"; import { onMount, createEventDispatcher } from "svelte";
// 应该确定四个点
export let canvas_dom; export let canvas_dom;
const dispatch = createEventDispatcher();
let mask_top = canvas_dom.offsetTop; let mask_top = canvas_dom.offsetTop;
let mask_left = canvas_dom.offsetLeft; let mask_left = canvas_dom.offsetLeft;
let mask_width = canvas_dom.clientWidth; let mask_width = canvas_dom.clientWidth;
let mask_height = canvas_dom.clientHeight; let mask_height = canvas_dom.clientHeight;
let crop_rect = {
x: 0,
y: 0,
width: mask_width,
height: mask_height,
};
let button_y_coord = "0px";
let cursor = "default"; let cursor = "default";
let crop_tag = false; let crop_tag = false;
@ -26,26 +34,23 @@
height: rects[4][3], height: rects[4][3],
}; };
} else { } else {
return {}; return crop_rect;
} }
} }
export let crop_rect = {};
let crop_rect_with_offset = { let crop_rect_with_offset = {
x: mask_left + mask_width * 0.2, x: mask_left + mask_width * 0.1,
y: mask_top, y: mask_top + mask_height * 0.1,
width: mask_width * 0.6, width: mask_width * 0.8,
height: mask_height * 0.6, height: mask_height * 0.8,
}; };
$: { $: {
crop_rect = get_crop_rect(mask_rects); crop_rect = get_crop_rect(mask_rects);
console.log(crop_rect); button_y_coord = get_button_y_coord(crop_rect_with_offset);
} }
function init_mask_rects() { function init_mask_rects() {
// TODO:
return [ return [
[ [
mask_left, mask_left,
@ -62,14 +67,17 @@
[ [
crop_rect_with_offset.x + crop_rect_with_offset.width, crop_rect_with_offset.x + crop_rect_with_offset.width,
mask_top, mask_top,
mask_left + mask_width, mask_left +
mask_width -
crop_rect_with_offset.x -
crop_rect_with_offset.width,
crop_rect_with_offset.y - mask_top, crop_rect_with_offset.y - mask_top,
], ],
[ [
mask_left, mask_left,
crop_rect_with_offset.y, crop_rect_with_offset.y,
crop_rect_with_offset.x - mask_left, crop_rect_with_offset.x - mask_left,
crop_rect_with_offset.y - mask_top, crop_rect_with_offset.height,
], ],
[ [
crop_rect_with_offset.x, crop_rect_with_offset.x,
@ -77,192 +85,392 @@
crop_rect_with_offset.width, crop_rect_with_offset.width,
crop_rect_with_offset.height, crop_rect_with_offset.height,
], ],
[
crop_rect_with_offset.x + crop_rect_with_offset.width,
crop_rect_with_offset.y,
mask_left +
mask_width -
crop_rect_with_offset.x -
crop_rect_with_offset.width,
crop_rect_with_offset.height,
],
[
mask_left,
crop_rect_with_offset.y + crop_rect_with_offset.height,
crop_rect_with_offset.x - mask_left,
mask_top +
mask_height -
crop_rect_with_offset.y -
crop_rect_with_offset.height,
],
[
crop_rect_with_offset.x,
crop_rect_with_offset.y + crop_rect_with_offset.height,
crop_rect_with_offset.width,
mask_top +
mask_height -
crop_rect_with_offset.y -
crop_rect_with_offset.height,
],
[
crop_rect_with_offset.x + crop_rect_with_offset.width,
crop_rect_with_offset.y + crop_rect_with_offset.height,
mask_left +
mask_width -
crop_rect_with_offset.x -
crop_rect_with_offset.width,
mask_top +
mask_height -
crop_rect_with_offset.y -
crop_rect_with_offset.height,
],
]; ];
} }
function _set_crop_rect(e) { function set_x_and_width(x, width) {
if (width <= mask_width * 0.3) {
return;
}
if (x + width >= mask_left + mask_width) {
return;
}
if (x <= mask_left) {
crop_rect_with_offset.width =
crop_rect_with_offset.x + crop_rect_with_offset.width - mask_left;
crop_rect_with_offset.x = mask_left;
return;
}
crop_rect_with_offset.x = x;
crop_rect_with_offset.width = width;
}
function set_y_and_height(y, height) {
if (height <= mask_height * 0.3) {
return;
}
if (y + height >= mask_top + mask_height) {
return;
}
if (y <= mask_top) {
return;
}
crop_rect_with_offset.y = y;
crop_rect_with_offset.height = height;
}
function set_crop_rect(e) {
let width;
let height;
if (crop_area < 0) { if (crop_area < 0) {
return; return;
} }
switch (crop_area) { switch (crop_area) {
case 0: case 0:
console.log("mask_rects.4:" + mask_rects[4]); width =
crop_rect_with_offset.x = e.clientX; crop_rect_with_offset.width + (crop_rect_with_offset.x - e.clientX);
crop_rect_with_offset.y = e.clientY; height =
crop_rect_with_offset.width = crop_rect_with_offset.height + (crop_rect_with_offset.y - e.clientY);
mask_rects[4][2] - (mask_rects[4][0] - e.clientX);
crop_rect_with_offset.height = set_x_and_width(e.clientX, width);
mask_rects[4][3] - (mask_rects[4][1] - e.clientY); set_y_and_height(e.clientY, height);
mask_rects = init_mask_rects(); mask_rects = init_mask_rects();
return; return;
/*mask_rects[4][2] = r4[3] - (r4[0] - e.clientX);
mask_rects[4][3] = r4[4] - (r4[1] - e.clientY);
case 1: case 1:
mask_rects[4][1] = e.clientY; height =
mask_rects[4][3] = r4[4] - (r4[1] - e.clientY);*/ crop_rect_with_offset.height + (crop_rect_with_offset.y - e.clientY);
set_y_and_height(e.clientY, height);
mask_rects = init_mask_rects();
return;
case 2:
set_x_and_width(
crop_rect_with_offset.x,
e.clientX - crop_rect_with_offset.x
);
set_y_and_height(
e.clientY,
crop_rect_with_offset.height + (crop_rect_with_offset.y - e.clientY)
);
mask_rects = init_mask_rects();
return;
case 3:
set_x_and_width(
e.clientX,
crop_rect_with_offset.width + (crop_rect_with_offset.x - e.clientX)
);
mask_rects = init_mask_rects();
return;
case 4:
set_x_and_width(
crop_rect_with_offset.x,
e.clientX - crop_rect_with_offset.x
);
mask_rects = init_mask_rects();
return;
case 5:
set_x_and_width(
e.clientX,
crop_rect_with_offset.width + (crop_rect_with_offset.x - e.clientX)
);
set_y_and_height(
crop_rect_with_offset.y,
e.clientY - crop_rect_with_offset.y
);
mask_rects = init_mask_rects();
return;
case 6:
set_y_and_height(
crop_rect_with_offset.y,
e.clientY - crop_rect_with_offset.y
);
mask_rects = init_mask_rects();
return;
case 7:
set_x_and_width(
crop_rect_with_offset.x,
e.clientX - crop_rect_with_offset.x
);
set_y_and_height(
crop_rect_with_offset.y,
e.clientY - crop_rect_with_offset.y
);
mask_rects = init_mask_rects();
return;
} }
} }
function set_crop_rect(e, i) { function set_mask(e, i) {
console.log(crop_tag);
if (crop_tag) { if (crop_tag) {
_set_crop_rect(e); set_crop_rect(e);
return; return;
} }
if (i != 4) { if (i != 4) {
crop_area = -1; crop_area = -1;
cursor = "default";
return; return;
} }
if ( if (
e.clientX - mask_rects[4][1] <= mask_width * 0.01 && Math.abs(e.clientX - crop_rect_with_offset.x) <=
e.clientY - mask_rects[4][0] <= mask_height * 0.01 crop_rect_with_offset.width * 0.01 &&
Math.abs(e.clientY - crop_rect_with_offset.y) <=
crop_rect_with_offset.height * 0.01
) { ) {
cursor = "nwse-resize"; cursor = "nwse-resize";
crop_area = 0; crop_area = 0;
return; return;
} }
if (e.clientY - mask_rects[4][0] <= mask_height * 0.01) { if (
Math.abs(e.clientY - crop_rect_with_offset.y) <=
crop_rect_with_offset.height * 0.01 &&
Math.abs(
e.clientX - crop_rect_with_offset.x - crop_rect_with_offset.width * 0.5
) <=
crop_rect_with_offset.width * 0.49
) {
cursor = "ns-resize"; cursor = "ns-resize";
crop_area = 1; crop_area = 1;
return; return;
} }
if ( if (
e.clientX - mask_rects[4][1] <= mask_width * 0.01 && Math.abs(
e.clientY - mask_rects[4][0] - mask_rects[4][3] >= -mask_height * 0.01 e.clientX - crop_rect_with_offset.x - crop_rect_with_offset.width
) <=
crop_rect_with_offset.width * 0.01 &&
Math.abs(e.clientY - crop_rect_with_offset.y) <=
crop_rect_with_offset.height * 0.01
) { ) {
cursor = "nesw-resize"; cursor = "nesw-resize";
crop_area = 2; crop_area = 2;
return; return;
} }
if (e.clientX - mask_rects[4][1] <= mask_width * 0.01) { if (
Math.abs(e.clientX - crop_rect_with_offset.x) <=
crop_rect_with_offset.width * 0.01 &&
Math.abs(
e.clientY - crop_rect_with_offset.y - crop_rect_with_offset.height * 0.5
) <=
crop_rect_with_offset.height * 0.49
) {
cursor = "ew-resize"; cursor = "ew-resize";
crop_area = 3; crop_area = 3;
return; return;
} }
if (e.clientX - mask_rects[4][1] - mask_rects[4][2] >= -mask_width * 0.01) { if (
Math.abs(
e.clientX - crop_rect_with_offset.x - crop_rect_with_offset.width
) <=
crop_rect_with_offset.width * 0.01 &&
Math.abs(
e.clientY - crop_rect_with_offset.y - crop_rect_with_offset.height * 0.5
) <=
crop_rect_with_offset.height * 0.49
) {
cursor = "ew-resize"; cursor = "ew-resize";
crop_area = 4; crop_area = 4;
return; return;
} }
if ( if (
e.clientX - mask_rects[4][1] - mask_rects[4][2] >= -mask_width * 0.01 && Math.abs(e.clientX - crop_rect_with_offset.x) <=
e.clientY - mask_rects[4][0] <= mask_height * 0.01 crop_rect_with_offset.width * 0.01 &&
Math.abs(
e.clientY - crop_rect_with_offset.y - crop_rect_with_offset.height
) <=
crop_rect_with_offset.height * 0.01
) { ) {
cursor = "nesw-resize"; cursor = "nesw-resize";
crop_area = 5; crop_area = 5;
return; return;
} }
if ( if (
e.clientY - mask_rects[4][0] - mask_rects[4][3] >= Math.abs(
-mask_height * 0.01 e.clientY - crop_rect_with_offset.y - crop_rect_with_offset.height
) <=
crop_rect_with_offset.height * 0.01 &&
Math.abs(
e.clientX - crop_rect_with_offset.x - crop_rect_with_offset.width * 0.5
) <=
crop_rect_with_offset.width * 0.49
) { ) {
cursor = "ns-resize"; cursor = "ns-resize";
crop_area = 6; crop_area = 6;
return; return;
} }
if ( if (
e.clientX - mask_rects[4][1] - mask_rects[4][2] >= -mask_width * 0.01 && Math.abs(
e.clientY - mask_rects[4][0] - mask_rects[4][3] >= -mask_height * 0.01 e.clientX - crop_rect_with_offset.x - crop_rect_with_offset.width
) <=
crop_rect_with_offset.width * 0.01 &&
Math.abs(
e.clientY - crop_rect_with_offset.y - crop_rect_with_offset.height
) <=
crop_rect_with_offset.height * 0.01
) { ) {
cursor = "nwse-resize"; cursor = "nwse-resize";
crop_area = 7; crop_area = 7;
return; return;
} }
cursor = "default";
crop_area = -1; crop_area = -1;
} }
onMount(() => { onMount(() => {
for (let i = 0; i < 9; i++) { mask_rects = init_mask_rects();
mask_rects[i] = [
mask_top_pos(i),
mask_left_pos(i),
mask_width_pos(i),
mask_height_pos(i),
];
}
}); });
function mask_top_pos(index) { function class_mask(i) {
let k = Math.floor(index / 3); if (i === 4) {
switch (k) { return "mask-center";
case 0:
return mask_top;
case 1:
return mask_top + mask_height * 0.2;
case 2:
return mask_top + mask_height * 0.8;
} }
return "mask";
} }
function mask_left_pos(index) { function get_button_y_coord(rect) {
let k = index % 3; if (rect.y - 35 >= 60) {
switch (k) { return rect.y - 35 + "px";
case 0:
return mask_left;
case 1:
return mask_left + mask_width * 0.2;
case 2:
return mask_left + mask_width * 0.8;
} }
} if (rect.y + rect.height + 40 <= mask_height + mask_top) {
console.log(rect.y + rect.height + 60, mask_height + mask_top);
function mask_width_pos(index) { return rect.y + rect.height + 5 + "px";
let k = index % 3;
switch (k) {
case 0:
return mask_width * 0.2;
case 1:
return mask_width * 0.6;
case 2:
return mask_width * 0.2;
}
}
function mask_height_pos(index) {
let k = Math.floor(index / 3);
switch (k) {
case 0:
return mask_height * 0.2;
case 1:
return mask_height * 0.6;
case 2:
return mask_height * 0.2;
} }
return rect.y + rect.height - 35 + "px";
} }
</script> </script>
{#each mask_rects as r, i} <!-- svelte-ignore a11y-mouse-events-have-key-events -->
<!-- svelte-ignore a11y-click-events-have-key-events --> <div
<div on:mouseleave={() => {
class={i != 4 ? "mask" : "mask-center"} crop_tag = false;
style:top={r[0] + "px"} }}
style:left={r[1] + "px"} >
style:width={r[2] + "px"} {#each mask_rects as r, i}
style:height={r[3] + "px"} <!-- svelte-ignore a11y-click-events-have-key-events -->
style:cursor <div
on:mousemove={(e) => { class={class_mask(i)}
set_crop_rect(e, i); style:left={r[0] + "px"}
}} style:top={r[1] + "px"}
on:mousedown={() => { style:width={r[2] + "px"}
if (i == 4) { style:height={r[3] + "px"}
style:cursor
on:mousemove={(e) => {
set_mask(e, i);
}}
on:mousedown={() => {
crop_tag = true; crop_tag = true;
} }}
}} on:mouseup={() => {
on:mouseup={() => { crop_tag = false;
crop_tag = false; }}
}} />
{/each}
<div
class="field has-addons btn-control is-rounded"
style:left={crop_rect_with_offset.x + 40 + "px"}
style:top={button_y_coord}
> >
<div class="mask-inner" /> <p class="control">
<button
class="button is-small is-info "
on:click={() => {
dispatch("maskclose", {
type: "success",
rect: crop_rect,
image_size: {
width: mask_width,
height: mask_height,
},
});
}}
>
剪切完成
</button>
</p>
<p class="control">
<button
class="button is-small is-info"
on:click={() => {
crop_rect_with_offset = {
x: mask_left + mask_width * 0.1,
y: mask_top + mask_height * 0.1,
width: mask_width * 0.8,
height: mask_height * 0.8,
};
mask_rects = init_mask_rects();
}}
>
还原选择框
</button>
</p>
<p class="control">
<button
class="button is-small is-info"
on:click={() => {
dispatch("maskclose", {
type: "cancel",
});
}}
>
取消
</button>
</p>
</div> </div>
{/each} </div>
<style> <style>
.btn-control {
position: fixed;
opacity: 0.6;
}
.btn-control:hover {
opacity: 1;
}
.mask { .mask {
position: fixed; position: fixed;
background-color: gray; background-color: cadetblue;
opacity: 0.6; opacity: 0.6;
} }
@ -272,12 +480,10 @@
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
background-color: red;
} }
.mask-inner { .mask-inner {
width: 98%; width: 99%;
height: 98%; height: 99%;
cursor: default;
} }
</style> </style>