feat(Mask.svelte-ImageShow.svelte): crop image
BREAKING CHANGE:
This commit is contained in:
parent
60ed3faf63
commit
701549f752
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Reference in New Issue