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

View File

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