From 566f9c3bf9889980c67c2e943e81de84d286e00a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9=20=D0=9C=D0=B0?=
 =?UTF-8?q?=D0=BB=D1=8E=D0=B3=D0=B8=D0=BD?= <d.malygin@iqdev.digital>
Date: Thu, 6 Feb 2025 20:47:48 +0500
Subject: [PATCH] feat: add icons and edit crop-borders in 'Cropper'

---
 src/App.vue                              |  8 ++++++
 src/common/constants/icons.ts            |  8 ++++++
 src/components/Cropper/Cropper.vue       | 32 ++++++++++++++++++------
 src/icons/Mono/CornerLeftBottomIcon.vue  | 26 +++++++++++++++++++
 src/icons/Mono/CornerRightBottomIcon.vue | 26 +++++++++++++++++++
 src/icons/Mono/CornerRightTopIcon.vue    | 26 +++++++++++++++++++
 6 files changed, 118 insertions(+), 8 deletions(-)
 create mode 100644 src/icons/Mono/CornerLeftBottomIcon.vue
 create mode 100644 src/icons/Mono/CornerRightBottomIcon.vue
 create mode 100644 src/icons/Mono/CornerRightTopIcon.vue

diff --git a/src/App.vue b/src/App.vue
index ebb55d4..81a1ef6 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -115,6 +115,10 @@ import ArrowLeftShortIcon from '@icons/Mono/ArrowLeftShortIcon.vue';
 import ArrowDoubleLeftShortIcon from '@icons/Mono/ArrowDoubleLeftShortIcon.vue';
 import ArrowRightShortIcon from '@icons/Mono/ArrowRightShortIcon.vue';
 import ArrowDoubleRightShortIcon from '@icons/Mono/ArrowDoubleRightShortIcon.vue';
+import CornerLeftBottomIcon from '@icons/Mono/CornerLeftBottomIcon.vue';
+import CornerLeftTopIcon from '@icons/Mono/CornerLeftTopIcon.vue';
+import CornerRightBottomIcon from '@icons/Mono/CornerRightBottomIcon.vue';
+import CornerRightTopIcon from '@icons/Mono/CornerRightTopIcon.vue';
 
 const gentleIcons = {
   Age18Icon,
@@ -164,6 +168,10 @@ const gentleIcons = {
   CompassIcon,
   ConstructionWorkerIcon,
   ContactsIcon,
+  CornerLeftBottomIcon,
+  CornerLeftTopIcon,
+  CornerRightBottomIcon,
+  CornerRightTopIcon,
   CropIcon,
   CrossIcon,
   CrossCircleIcon,
diff --git a/src/common/constants/icons.ts b/src/common/constants/icons.ts
index 9ae57d6..45babbb 100644
--- a/src/common/constants/icons.ts
+++ b/src/common/constants/icons.ts
@@ -111,6 +111,10 @@ import ArrowShortDownIcon from '@icons/Mono/ArrowDownShortIcon.vue';
 import SearchIcon from '@icons/Mono/SearchIcon.vue';
 import StarIcon from '@icons/Mono/StarIcon.vue';
 import StarFilledIcon from '@icons/Mono/StarFilledIcon.vue';
+import CornerLeftBottomIcon from '@icons/Mono/CornerLeftBottomIcon.vue';
+import CornerLeftTopIcon from '@icons/Mono/CornerLeftTopIcon.vue';
+import CornerRightBottomIcon from '@icons/Mono/CornerRightBottomIcon.vue';
+import CornerRightTopIcon from '@icons/Mono/CornerRightTopIcon.vue';
 
 export const iconsSet: Record<string, Component> = {
   Age18: Age18Icon,
@@ -156,6 +160,10 @@ export const iconsSet: Record<string, Component> = {
   Compass: CompassIcon,
   ConstructionWorker: ConstructionWorkerIcon,
   Contacts: ContactsIcon,
+  CornerLeftBottom: CornerLeftBottomIcon,
+  CornerLeftTop: CornerLeftTopIcon,
+  CornerRightBottom: CornerRightBottomIcon,
+  CornerRightTop: CornerRightTopIcon,
   Crop: CropIcon,
   Cross: CrossIcon,
   CrossCircle: CrossCircleIcon,
diff --git a/src/components/Cropper/Cropper.vue b/src/components/Cropper/Cropper.vue
index 946c3aa..7b868e9 100644
--- a/src/components/Cropper/Cropper.vue
+++ b/src/components/Cropper/Cropper.vue
@@ -5,6 +5,9 @@ import Button from '@components/Button/Button.vue';
 import { convertThemeToTextColor } from '@helpers/common';
 import SaveIcon from '@icons/Mono/SaveIcon.vue';
 import CornerLeftTopIcon from '@icons/Mono/CornerLeftTopIcon.vue';
+import CornerRightTopIcon from '@icons/Mono/CornerRightTopIcon.vue';
+import CornerLeftBottomIcon from '@icons/Mono/CornerLeftBottomIcon.vue';
+import CornerRightBottomIcon from '@icons/Mono/CornerRightBottomIcon.vue';
 
 const props = withDefaults(defineProps<ICropperProps>(), {
   width: 300,
@@ -28,7 +31,7 @@ watch(
     if (!imageSource.value) return;
 
     const img = new Image();
-    img.src = props.src ?? URL.createObjectURL(props.file);
+    img.src = props.src ?? URL.createObjectURL(props.file!);
 
     img.onload = () => {
       canvas.value.width = width.value ?? 0;
@@ -52,11 +55,15 @@ watch(
     <div class="canvas-container">
       <canvas ref="canvas" id="cropper-canvas"> </canvas>
       <div class="crop-border left top">
-        <CornerLeftTopIcon size="16" />
+        <CornerLeftTopIcon color="white" />
+      </div>
+      <div class="crop-border right top"><CornerRightTopIcon color="white" /></div>
+      <div class="crop-border left bottom">
+        <CornerLeftBottomIcon color="white" />
+      </div>
+      <div class="crop-border right bottom">
+        <CornerRightBottomIcon color="white" />
       </div>
-      <div class="crop-border right top"></div>
-      <div class="crop-border left bottom"></div>
-      <div class="crop-border right bottom"></div>
     </div>
     <div
       v-show="imageSource"
@@ -97,9 +104,18 @@ watch(
 .crop-border {
   position: absolute;
   z-index: 50;
-  width: 20px;
-  height: 20px;
-  background-color: gray;
+  width: 40px;
+  height: 40px;
+  border: 2px dashed white;
+  opacity: 0.6;
+  transition: opacity 0.1s ease;
+  cursor: pointer;
+}
+.crop-border:hover {
+  opacity: 0.8;
+}
+.crop-border:active {
+  opacity: 1;
 }
 .top {
   top: 0;
diff --git a/src/icons/Mono/CornerLeftBottomIcon.vue b/src/icons/Mono/CornerLeftBottomIcon.vue
new file mode 100644
index 0000000..7998e80
--- /dev/null
+++ b/src/icons/Mono/CornerLeftBottomIcon.vue
@@ -0,0 +1,26 @@
+<script setup lang="ts">
+interface Props {
+  color?: string;
+  size?: string | number;
+}
+defineProps<Props>();
+</script>
+
+<template>
+  <svg
+    :width="`${size ?? 40}px`"
+    :height="`${size ?? 40}px`"
+    viewBox="0 0 15 15"
+    fill="none"
+    xmlns="http://www.w3.org/2000/svg"
+  >
+    <path
+      fill-rule="evenodd"
+      clip-rule="evenodd"
+      d="M10.3161 15c-1.6515 0-2.9368 0-3.968-.0843-1.0469-.0855-1.8975-.2616-2.6626-.6515C2.4154 13.6171 1.3829 12.5846.7358 11.3145.3459 10.5494.1698 9.6987.0843 8.6518 0 7.6207 0 6.3354 0 4.6839V4.65 1.438C.01 1.03.23.7.8.7s.78.341.78.769V4.65c0 1.6926.0006 2.9169.0792 3.8798.078.9542.2289 1.5854.493 2.1038.5032.9877 1.3065 1.791 2.2942 2.2942.5184.2641 1.1496.4151 2.1038.493C7.4331 13.4994 8.6574 13.5 10.35 13.5H13.259c.4142 0 .75.3358.75.75s-.3358.75-.973.731H10.35 10.3161Z"
+      :fill="color ?? '#000000'"
+    />
+  </svg>
+</template>
+
+<style scoped></style>
diff --git a/src/icons/Mono/CornerRightBottomIcon.vue b/src/icons/Mono/CornerRightBottomIcon.vue
new file mode 100644
index 0000000..78eec7a
--- /dev/null
+++ b/src/icons/Mono/CornerRightBottomIcon.vue
@@ -0,0 +1,26 @@
+<script setup lang="ts">
+interface Props {
+  color?: string;
+  size?: string | number;
+}
+defineProps<Props>();
+</script>
+
+<template>
+  <svg
+    :width="`${size ?? 40}px`"
+    :height="`${size ?? 40}px`"
+    viewBox="0 0 15 15"
+    fill="none"
+    xmlns="http://www.w3.org/2000/svg"
+  >
+    <path
+      fill-rule="evenodd"
+      clip-rule="evenodd"
+      d="M4.6839 15H4.65 1.753c-.4142 0-.75-.3359-.75-.75s.3358-.75.75-.75h2.905c1.6925 0 2.9168-.0006 3.8797-.0792.9541-.078 1.5854-.2289 2.1038-.4931.9878-.5032 1.791-1.3064 2.2942-2.2942.2642-.5184.4151-1.1497.4931-2.1038.0786-.9629.0792-2.1872.0792-3.8797V1.555c0-.4142.3359-.75.75-.75s.75.3358.75.75v2.4.0339c0 1.6515 0 2.9369-.139 4.6721-.0855 1.0469-.2616 1.8975-.6515 2.6625-.6471 1.2702-1.6796 2.3027-2.9498 2.9498-.765.3899-1.6156.566-2.6625.6515C7.28 14.996 5.82 15.006 4.6839 15Z"
+      :fill="color ?? '#000000'"
+    />
+  </svg>
+</template>
+
+<style scoped></style>
diff --git a/src/icons/Mono/CornerRightTopIcon.vue b/src/icons/Mono/CornerRightTopIcon.vue
new file mode 100644
index 0000000..3e9955e
--- /dev/null
+++ b/src/icons/Mono/CornerRightTopIcon.vue
@@ -0,0 +1,26 @@
+<script setup lang="ts">
+interface Props {
+  color?: string;
+  size?: string | number;
+}
+defineProps<Props>();
+</script>
+
+<template>
+  <svg
+    :width="`${size ?? 40}px`"
+    :height="`${size ?? 40}px`"
+    viewBox="0 0 15 15"
+    fill="none"
+    xmlns="http://www.w3.org/2000/svg"
+  >
+    <path
+      fill-rule="evenodd"
+      clip-rule="evenodd"
+      d="M4.6839 0H4.65 1.671c-.4142 0-.75.3358-.75.75s.3358.75.75.75H4.65c1.6926 0 2.9169.0006 3.8798.0792.9542.078 1.5854.2289 2.1038.4929.9879.5034 1.791 1.3065 2.2942 2.2944.2641.5184.4151 1.1496.493 2.1038C13.4994 7.4331 13.5 8.6574 13.5 10.35v2.85c0 .4142.3358.75.75.75s.75-.3358.75-.75V10.35 10.3161c0-1.6515 0-2.9368-.0843-3.968-.0855-1.0469-.2616-1.8975-.6515-2.6626-.6471-1.27-1.6797-2.3026-2.9497-2.9499-.7651-.3899-1.6157-.566-2.6626-.6515C7.6208 0 6.3354 0 4.6839 0Z"
+      :fill="color ?? '#000000'"
+    />
+  </svg>
+</template>
+
+<style scoped></style>
-- 
GitLab