pixedi 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -60
- package/README.npm.md +80 -0
- package/dist/lib/index.js +1602 -0
- package/dist/lib/index.umd.js +28 -0
- package/package.json +9 -4
- package/.github/workflows/deploy.yml +0 -54
- package/.prettierr +0 -9
- package/.storybook/main.ts +0 -16
- package/.storybook/preview.ts +0 -53
- package/.vscode/extensions.json +0 -6
- package/eslint.config.js +0 -22
- package/index.html +0 -13
- package/pnpm-workspace.yaml +0 -2
- package/public/favicon.svg +0 -1
- package/src/app/App.tsx +0 -10
- package/src/app/entries/index.ts +0 -145
- package/src/app/providers/RouterProvider.tsx +0 -6
- package/src/app/providers/index.ts +0 -1
- package/src/app/router/AppRouter.tsx +0 -12
- package/src/app/router/index.ts +0 -0
- package/src/app/styles/index.css +0 -4
- package/src/features/gallery/GalleryPage.tsx +0 -33
- package/src/features/gallery/ImageEditPage.tsx +0 -37
- package/src/features/gallery/index.ts +0 -2
- package/src/main.tsx +0 -10
- package/src/shared/components/ImageCard/ImageCard.tsx +0 -54
- package/src/shared/components/ImageCard/index.ts +0 -1
- package/src/shared/components/ImageEditor/ImageEditor.tsx +0 -48
- package/src/shared/components/ImageEditor/assets/icons.tsx +0 -114
- package/src/shared/components/ImageEditor/constants.ts +0 -118
- package/src/shared/components/ImageEditor/crop/Crop.tsx +0 -60
- package/src/shared/components/ImageEditor/crop/CropBorders.tsx +0 -28
- package/src/shared/components/ImageEditor/crop/CropLines.tsx +0 -8
- package/src/shared/components/ImageEditor/crop/CropPointer.tsx +0 -21
- package/src/shared/components/ImageEditor/crop/CropPointers.tsx +0 -44
- package/src/shared/components/ImageEditor/crop/CropTools.tsx +0 -138
- package/src/shared/components/ImageEditor/crop/crop.css +0 -180
- package/src/shared/components/ImageEditor/crop/index.ts +0 -8
- package/src/shared/components/ImageEditor/crop/useCropInteraction.ts +0 -230
- package/src/shared/components/ImageEditor/eventBus.ts +0 -8
- package/src/shared/components/ImageEditor/frame/Frame.tsx +0 -48
- package/src/shared/components/ImageEditor/frame/frame.css +0 -40
- package/src/shared/components/ImageEditor/frame/index.ts +0 -1
- package/src/shared/components/ImageEditor/header/Header.tsx +0 -81
- package/src/shared/components/ImageEditor/header/header.css +0 -27
- package/src/shared/components/ImageEditor/header/index.ts +0 -1
- package/src/shared/components/ImageEditor/hooks/index.ts +0 -5
- package/src/shared/components/ImageEditor/hooks/useAbove.tsx +0 -18
- package/src/shared/components/ImageEditor/hooks/useBellow.tsx +0 -18
- package/src/shared/components/ImageEditor/hooks/useImageLoader.tsx +0 -110
- package/src/shared/components/ImageEditor/hooks/useImageProcessor.test.tsx +0 -147
- package/src/shared/components/ImageEditor/hooks/useImageProcessor.ts +0 -225
- package/src/shared/components/ImageEditor/hooks/useMobile.tsx +0 -33
- package/src/shared/components/ImageEditor/index.css +0 -145
- package/src/shared/components/ImageEditor/index.ts +0 -1
- package/src/shared/components/ImageEditor/provider/ImageEditorProvider.test.tsx +0 -126
- package/src/shared/components/ImageEditor/provider/ImageEditorProvider.tsx +0 -107
- package/src/shared/components/ImageEditor/provider/StoreContext.tsx +0 -20
- package/src/shared/components/ImageEditor/provider/initialState.ts +0 -30
- package/src/shared/components/ImageEditor/provider/useImageEditorContext.tsx +0 -12
- package/src/shared/components/ImageEditor/resize/ResizeTools.tsx +0 -183
- package/src/shared/components/ImageEditor/resize/index.ts +0 -1
- package/src/shared/components/ImageEditor/resize/resize.css +0 -56
- package/src/shared/components/ImageEditor/sidebar/Sidebar.tsx +0 -54
- package/src/shared/components/ImageEditor/sidebar/SidebarCrop.tsx +0 -57
- package/src/shared/components/ImageEditor/sidebar/SidebarPresets.tsx +0 -54
- package/src/shared/components/ImageEditor/sidebar/SidebarResize.tsx +0 -26
- package/src/shared/components/ImageEditor/sidebar/index.ts +0 -1
- package/src/shared/components/ImageEditor/sidebar/sidebar.css +0 -101
- package/src/shared/components/ImageEditor/types.ts +0 -59
- package/src/shared/components/ImageEditor/ui/button/Button.stories.tsx +0 -42
- package/src/shared/components/ImageEditor/ui/button/Button.tsx +0 -21
- package/src/shared/components/ImageEditor/ui/button/button.css +0 -69
- package/src/shared/components/ImageEditor/ui/button-crop/ButtonCrop.stories.tsx +0 -26
- package/src/shared/components/ImageEditor/ui/button-crop/ButtonCrop.tsx +0 -29
- package/src/shared/components/ImageEditor/ui/button-crop/button-crop.css +0 -38
- package/src/shared/components/ImageEditor/ui/index.ts +0 -6
- package/src/shared/components/ImageEditor/ui/input/Input.stories.tsx +0 -45
- package/src/shared/components/ImageEditor/ui/input/Input.tsx +0 -20
- package/src/shared/components/ImageEditor/ui/input/input.css +0 -48
- package/src/shared/components/ImageEditor/ui/input-pixel/InputPixel.stories.tsx +0 -33
- package/src/shared/components/ImageEditor/ui/input-pixel/InputPixel.tsx +0 -23
- package/src/shared/components/ImageEditor/ui/input-pixel/input-pixel.css +0 -24
- package/src/shared/components/ImageEditor/ui/select/Select.stories.tsx +0 -67
- package/src/shared/components/ImageEditor/ui/select/Select.tsx +0 -161
- package/src/shared/components/ImageEditor/ui/select/select.css +0 -147
- package/src/shared/components/ImageEditor/ui/separator/Separator.stories.tsx +0 -37
- package/src/shared/components/ImageEditor/ui/separator/Separator.tsx +0 -27
- package/src/shared/components/ImageEditor/ui/separator/separator.css +0 -19
- package/src/shared/components/ImageEditor/utils.test.ts +0 -136
- package/src/shared/components/ImageEditor/utils.ts +0 -497
- package/src/shared/components/ui/index.ts +0 -1
- package/src/shared/components/ui/preloader.tsx +0 -78
- package/src/shared/config/index.ts +0 -3
- package/src/shared/config/routes.ts +0 -4
- package/src/shared/features/gallery/GalleryPage.tsx +0 -33
- package/src/shared/features/gallery/ImageEditPage.tsx +0 -37
- package/src/shared/features/gallery/index.ts +0 -2
- package/src/shared/hooks/index.ts +0 -1
- package/src/shared/hooks/useImagePreload.tsx +0 -49
- package/src/shared/types/index.ts +0 -11
- package/src/test/setup.ts +0 -14
- package/src/virtual-css-injected-by-js.d.ts +0 -8
- package/src/widget.tsx +0 -119
- package/tsconfig.app.json +0 -29
- package/tsconfig.json +0 -12
- package/tsconfig.lib.json +0 -18
- package/tsconfig.node.json +0 -23
- package/vite-env.d.ts +0 -1
- package/vite.config.ts +0 -24
- package/vite.lib.config.ts +0 -33
- package/vite.widget.config.ts +0 -39
- package/wrangler.json +0 -5
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { useParams, useNavigate } from "react-router";
|
|
2
|
-
import { imagesData } from "@/app/entries";
|
|
3
|
-
import { ImageEditor } from "@/shared/components/ImageEditor";
|
|
4
|
-
|
|
5
|
-
export const ImageEditPage = () => {
|
|
6
|
-
const navigate = useNavigate();
|
|
7
|
-
const { id } = useParams<{ id: string }>();
|
|
8
|
-
const image = imagesData.find((img) => img.id === id);
|
|
9
|
-
|
|
10
|
-
if (!image) {
|
|
11
|
-
return <div>Image not found</div>;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const handleSave = async (base64: string) => {
|
|
15
|
-
return new Promise<void>((resolve) => {
|
|
16
|
-
setTimeout(() => {
|
|
17
|
-
// TODO: Save the image
|
|
18
|
-
console.log(base64);
|
|
19
|
-
resolve();
|
|
20
|
-
}, 2000);
|
|
21
|
-
});
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
const handleCancel = () => {
|
|
25
|
-
navigate("/");
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
<div className="w-full h-screen" style={{ width: "100%", height: "100vh" }}>
|
|
30
|
-
<ImageEditor
|
|
31
|
-
image={image.original}
|
|
32
|
-
onBack={handleCancel}
|
|
33
|
-
onSave={handleSave}
|
|
34
|
-
/>
|
|
35
|
-
</div>
|
|
36
|
-
);
|
|
37
|
-
};
|
package/src/main.tsx
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
// import { motion, type Variants } from "motion/react";
|
|
2
|
-
// import { Link } from "react-router";
|
|
3
|
-
// import type { Image } from "@/shared/types";
|
|
4
|
-
|
|
5
|
-
// type ImageCardProps = {
|
|
6
|
-
// image: Image;
|
|
7
|
-
// };
|
|
8
|
-
|
|
9
|
-
// export const ImageCard = ({ image }: ImageCardProps) => {
|
|
10
|
-
// const imageVariants: Variants = {
|
|
11
|
-
// rest: { scale: 1, opacity: 0.5 },
|
|
12
|
-
// hover: {
|
|
13
|
-
// scale: 1.1,
|
|
14
|
-
// opacity: 1,
|
|
15
|
-
// },
|
|
16
|
-
// };
|
|
17
|
-
|
|
18
|
-
// return (
|
|
19
|
-
// <Link to={`/images/${image.id}`}>
|
|
20
|
-
// <motion.div
|
|
21
|
-
// className={`
|
|
22
|
-
// relative
|
|
23
|
-
// w-full aspect-4/3
|
|
24
|
-
// overflow-hidden cursor-pointer box-border
|
|
25
|
-
// border border-neutral-400
|
|
26
|
-
// `}
|
|
27
|
-
// whileHover="hover"
|
|
28
|
-
// initial="rest"
|
|
29
|
-
// animate="rest"
|
|
30
|
-
// >
|
|
31
|
-
// <motion.div
|
|
32
|
-
// className="absolute inset-0 opacity-50"
|
|
33
|
-
// variants={imageVariants}
|
|
34
|
-
// transition={{ duration: 0.3, ease: "easeIn" }}
|
|
35
|
-
// style={{
|
|
36
|
-
// backgroundImage: `url(${image.thumbnail})`,
|
|
37
|
-
// backgroundSize: "cover",
|
|
38
|
-
// backgroundPosition: "center",
|
|
39
|
-
// }}
|
|
40
|
-
// />
|
|
41
|
-
// </motion.div>
|
|
42
|
-
// </Link>
|
|
43
|
-
// );
|
|
44
|
-
// };
|
|
45
|
-
|
|
46
|
-
type ImageCardProps = {
|
|
47
|
-
image: {
|
|
48
|
-
id: string;
|
|
49
|
-
};
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
export const ImageCard = ({ image }: ImageCardProps) => {
|
|
53
|
-
return <div>{image.id}</div>;
|
|
54
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { ImageCard } from "./ImageCard";
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { Preloader } from "@/shared/components/ui";
|
|
2
|
-
import { ImageEditorProvider } from "./provider/ImageEditorProvider";
|
|
3
|
-
import { useImageLoader } from "./hooks";
|
|
4
|
-
import { Header } from "./header";
|
|
5
|
-
import { Frame } from "./frame";
|
|
6
|
-
import { Sidebar } from "./sidebar";
|
|
7
|
-
import type { FuncSaveArgs } from "./types";
|
|
8
|
-
import "./index.css";
|
|
9
|
-
|
|
10
|
-
type ImageEditorProps = {
|
|
11
|
-
image: string;
|
|
12
|
-
onSave: FuncSaveArgs;
|
|
13
|
-
onBack: () => void;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export const ImageEditor = ({ image, onSave, onBack }: ImageEditorProps) => {
|
|
17
|
-
const { loading, error, width, height, base64, extension } =
|
|
18
|
-
useImageLoader(image);
|
|
19
|
-
|
|
20
|
-
if (loading || error || !base64 || !extension) {
|
|
21
|
-
return (
|
|
22
|
-
<div className="picedi sys">
|
|
23
|
-
{loading && <Preloader size={48} />}
|
|
24
|
-
{error && <div className="text-red">{error}</div>}
|
|
25
|
-
{!loading && !error && (!base64 || !extension) && (
|
|
26
|
-
<div className="text-red">Failed to load image.</div>
|
|
27
|
-
)}
|
|
28
|
-
</div>
|
|
29
|
-
);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return (
|
|
33
|
-
<ImageEditorProvider
|
|
34
|
-
base64={base64}
|
|
35
|
-
width={width}
|
|
36
|
-
height={height}
|
|
37
|
-
ext={extension}
|
|
38
|
-
>
|
|
39
|
-
<div className="picedi main">
|
|
40
|
-
<Header onSave={onSave} onBack={onBack} />
|
|
41
|
-
<div className="grid">
|
|
42
|
-
<Frame />
|
|
43
|
-
<Sidebar />
|
|
44
|
-
</div>
|
|
45
|
-
</div>
|
|
46
|
-
</ImageEditorProvider>
|
|
47
|
-
);
|
|
48
|
-
};
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
|
|
3
|
-
const baseSvgProps: React.ComponentPropsWithoutRef<"svg"> = {
|
|
4
|
-
xmlns: "http://w3.org",
|
|
5
|
-
width: "24",
|
|
6
|
-
height: "24",
|
|
7
|
-
viewBox: "0 0 24 24",
|
|
8
|
-
fill: "none",
|
|
9
|
-
stroke: "currentColor",
|
|
10
|
-
strokeWidth: "2",
|
|
11
|
-
strokeLinecap: "round",
|
|
12
|
-
strokeLinejoin: "round",
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export const Check = (props: React.ComponentPropsWithoutRef<"svg">) => (
|
|
16
|
-
<svg {...baseSvgProps} {...props}>
|
|
17
|
-
<path d="M20 6 9 17l-5-5" />
|
|
18
|
-
</svg>
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
export const X = (props: React.ComponentPropsWithoutRef<"svg">) => (
|
|
22
|
-
<svg {...baseSvgProps} {...props}>
|
|
23
|
-
<path d="M18 6 6 18" />
|
|
24
|
-
<path d="m6 6 12 12" />
|
|
25
|
-
</svg>
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
export const Lock = (props: React.ComponentPropsWithoutRef<"svg">) => (
|
|
29
|
-
<svg {...baseSvgProps} {...props}>
|
|
30
|
-
<rect width="18" height="11" x="3" y="11" rx="2" ry="2" />
|
|
31
|
-
<path d="M7 11V7a5 5 0 0 1 10 0v4" />
|
|
32
|
-
</svg>
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
export const ArrowLeft = (props: React.ComponentPropsWithoutRef<"svg">) => (
|
|
36
|
-
<svg {...baseSvgProps} {...props}>
|
|
37
|
-
<path d="m12 19-7-7 7-7" />
|
|
38
|
-
<path d="M19 12H5" />
|
|
39
|
-
</svg>
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
export const ChevronDown = (props: React.ComponentPropsWithoutRef<"svg">) => (
|
|
43
|
-
<svg {...baseSvgProps} {...props}>
|
|
44
|
-
<path d="m6 9 6 6 6-6" />
|
|
45
|
-
</svg>
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
export const Undo = (props: React.ComponentPropsWithoutRef<"svg">) => (
|
|
49
|
-
<svg {...baseSvgProps} {...props}>
|
|
50
|
-
<path d="M3 7v6h6" />
|
|
51
|
-
<path d="M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13" />
|
|
52
|
-
</svg>
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
export const Redo = (props: React.ComponentPropsWithoutRef<"svg">) => (
|
|
56
|
-
<svg {...baseSvgProps} {...props}>
|
|
57
|
-
<path d="M21 7v6h-6" />
|
|
58
|
-
<path d="M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3l3 2.7" />
|
|
59
|
-
</svg>
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
export const Settings = (props: React.ComponentPropsWithoutRef<"svg">) => (
|
|
63
|
-
<svg {...baseSvgProps} {...props}>
|
|
64
|
-
<path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915" />
|
|
65
|
-
<circle cx="12" cy="12" r="3" />
|
|
66
|
-
</svg>
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
export const Crop = (props: React.ComponentPropsWithoutRef<"svg">) => (
|
|
70
|
-
<svg {...baseSvgProps} {...props}>
|
|
71
|
-
<path d="M6 2v14a2 2 0 0 0 2 2h14" />
|
|
72
|
-
<path d="M18 22V8a2 2 0 0 0-2-2H2" />
|
|
73
|
-
</svg>
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
export const Image = (props: React.ComponentPropsWithoutRef<"svg">) => (
|
|
77
|
-
<svg {...baseSvgProps} {...props}>
|
|
78
|
-
<rect width="18" height="18" x="3" y="3" rx="2" ry="2" />
|
|
79
|
-
<circle cx="9" cy="9" r="2" />
|
|
80
|
-
<path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" />
|
|
81
|
-
</svg>
|
|
82
|
-
);
|
|
83
|
-
|
|
84
|
-
export const Square = (props: React.ComponentPropsWithoutRef<"svg">) => (
|
|
85
|
-
<svg {...baseSvgProps} {...props}>
|
|
86
|
-
<rect width="18" height="18" x="3" y="3" rx="2" />
|
|
87
|
-
</svg>
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
export const Fullscreen = (props: React.ComponentPropsWithoutRef<"svg">) => (
|
|
91
|
-
<svg {...baseSvgProps} {...props}>
|
|
92
|
-
<path d="M3 7V5a2 2 0 0 1 2-2h2" />
|
|
93
|
-
<path d="M17 3h2a2 2 0 0 1 2 2v2" />
|
|
94
|
-
<path d="M21 17v2a2 2 0 0 1-2 2h-2" />
|
|
95
|
-
<path d="M7 21H5a2 2 0 0 1-2-2v-2" />
|
|
96
|
-
<rect width="10" height="8" x="7" y="8" rx="1" />
|
|
97
|
-
</svg>
|
|
98
|
-
);
|
|
99
|
-
|
|
100
|
-
export const Loader = (props: React.ComponentPropsWithoutRef<"svg">) => (
|
|
101
|
-
<svg {...baseSvgProps} {...props}>
|
|
102
|
-
<path d="M21 12a9 9 0 1 1-6.219-8.56">
|
|
103
|
-
<animateTransform
|
|
104
|
-
attributeType="xml"
|
|
105
|
-
attributeName="transform"
|
|
106
|
-
type="rotate"
|
|
107
|
-
from="0 12 12"
|
|
108
|
-
to="360 12 12"
|
|
109
|
-
dur="0.8s"
|
|
110
|
-
repeatCount="indefinite"
|
|
111
|
-
/>
|
|
112
|
-
</path>
|
|
113
|
-
</svg>
|
|
114
|
-
);
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
export type PresetOptions = {
|
|
2
|
-
value: string;
|
|
3
|
-
label: string;
|
|
4
|
-
w: number;
|
|
5
|
-
h: number;
|
|
6
|
-
rightLabel?: string;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export type Preset = {
|
|
10
|
-
value: string;
|
|
11
|
-
label: string;
|
|
12
|
-
options: Array<PresetOptions>;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export const presetsData: Array<Preset> = [
|
|
16
|
-
{
|
|
17
|
-
label: "Facebook",
|
|
18
|
-
value: "facebook",
|
|
19
|
-
options: [
|
|
20
|
-
{
|
|
21
|
-
value: "facebook-post",
|
|
22
|
-
label: "Post",
|
|
23
|
-
w: 1200,
|
|
24
|
-
h: 630,
|
|
25
|
-
rightLabel: "1200 x 630",
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
value: "facebook-cover",
|
|
29
|
-
label: "Cover",
|
|
30
|
-
w: 851,
|
|
31
|
-
h: 315,
|
|
32
|
-
rightLabel: "851 x 315",
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
value: "facebook-profile",
|
|
36
|
-
label: "Profile",
|
|
37
|
-
w: 170,
|
|
38
|
-
h: 170,
|
|
39
|
-
rightLabel: "170 x 170",
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
value: "facebook-story",
|
|
43
|
-
label: "Story",
|
|
44
|
-
w: 1080,
|
|
45
|
-
h: 1920,
|
|
46
|
-
rightLabel: "1080 x 1920",
|
|
47
|
-
},
|
|
48
|
-
],
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
label: "Instagram",
|
|
52
|
-
value: "instagram",
|
|
53
|
-
options: [
|
|
54
|
-
{
|
|
55
|
-
value: "instagram-landscape",
|
|
56
|
-
label: "Landscape",
|
|
57
|
-
w: 1080,
|
|
58
|
-
h: 566,
|
|
59
|
-
rightLabel: "1080 x 566",
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
value: "instagram-portait",
|
|
63
|
-
label: "Portait",
|
|
64
|
-
w: 1080,
|
|
65
|
-
h: 1350,
|
|
66
|
-
rightLabel: "1080 x 1350",
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
value: "instagram-square",
|
|
70
|
-
label: "Square",
|
|
71
|
-
w: 1080,
|
|
72
|
-
h: 1080,
|
|
73
|
-
rightLabel: "1080 x 1080",
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
value: "instagram-story",
|
|
77
|
-
label: "Story",
|
|
78
|
-
w: 1080,
|
|
79
|
-
h: 1920,
|
|
80
|
-
rightLabel: "1080 x 1920",
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
value: "instagram-thumbnail",
|
|
84
|
-
label: "Thumbnail",
|
|
85
|
-
w: 161,
|
|
86
|
-
h: 161,
|
|
87
|
-
rightLabel: "161 x 161",
|
|
88
|
-
},
|
|
89
|
-
],
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
label: "LinkedIn",
|
|
93
|
-
value: "linkedin",
|
|
94
|
-
options: [
|
|
95
|
-
{
|
|
96
|
-
value: "linkedin-blog-post",
|
|
97
|
-
label: "Blog Post",
|
|
98
|
-
w: 1200,
|
|
99
|
-
h: 627,
|
|
100
|
-
rightLabel: "1200 x 627",
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
value: "linkedin-cover",
|
|
104
|
-
label: "Cover",
|
|
105
|
-
w: 1128,
|
|
106
|
-
h: 191,
|
|
107
|
-
rightLabel: "1128 x 191",
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
value: "linkedin-profile",
|
|
111
|
-
label: "Profile",
|
|
112
|
-
w: 400,
|
|
113
|
-
h: 400,
|
|
114
|
-
rightLabel: "400 x 400",
|
|
115
|
-
},
|
|
116
|
-
],
|
|
117
|
-
},
|
|
118
|
-
];
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { useRef } from "react";
|
|
2
|
-
import { useImageEditorContext } from "../provider/useImageEditorContext";
|
|
3
|
-
import {
|
|
4
|
-
CropBorders,
|
|
5
|
-
useCropInteraction,
|
|
6
|
-
CropPointers,
|
|
7
|
-
CropLines,
|
|
8
|
-
CropPointer,
|
|
9
|
-
} from "../crop";
|
|
10
|
-
import { getInitalCrop } from "../utils";
|
|
11
|
-
import { useMobile } from "../hooks";
|
|
12
|
-
import "./crop.css";
|
|
13
|
-
|
|
14
|
-
export const Crop = () => {
|
|
15
|
-
const { getCurrentAction, getLastHistoryItem } = useImageEditorContext();
|
|
16
|
-
const currentAction = getCurrentAction();
|
|
17
|
-
const mobile = useMobile();
|
|
18
|
-
|
|
19
|
-
const imgRef = useRef<HTMLImageElement>(null);
|
|
20
|
-
const cropRef = useRef<HTMLDivElement>(null);
|
|
21
|
-
|
|
22
|
-
const { handleCropStart } = useCropInteraction({
|
|
23
|
-
imgRef,
|
|
24
|
-
cropRef,
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
if (!currentAction || currentAction.name !== "crop") {
|
|
28
|
-
return null;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const { width, height, base64 } = getLastHistoryItem();
|
|
32
|
-
const { x, y, w, h } = getInitalCrop(currentAction.args.ratio, width, height);
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<>
|
|
36
|
-
<img
|
|
37
|
-
ref={imgRef}
|
|
38
|
-
src={base64}
|
|
39
|
-
alt="Image"
|
|
40
|
-
className="crop-image"
|
|
41
|
-
style={{ clipPath: `xywh(${x}% ${y}% ${w}% ${h}%)` }}
|
|
42
|
-
/>
|
|
43
|
-
<div
|
|
44
|
-
ref={cropRef}
|
|
45
|
-
className="crop-box"
|
|
46
|
-
style={{ width: `${w}%`, height: `${h}%`, top: `${y}%`, left: `${x}%` }}
|
|
47
|
-
>
|
|
48
|
-
<CropLines />
|
|
49
|
-
{mobile ? (
|
|
50
|
-
<CropPointer onMouseDown={handleCropStart} />
|
|
51
|
-
) : (
|
|
52
|
-
<>
|
|
53
|
-
<CropBorders onMouseDown={handleCropStart} />
|
|
54
|
-
<CropPointers onMouseDown={handleCropStart} />
|
|
55
|
-
</>
|
|
56
|
-
)}
|
|
57
|
-
</div>
|
|
58
|
-
</>
|
|
59
|
-
);
|
|
60
|
-
};
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { Direction } from "../types";
|
|
2
|
-
|
|
3
|
-
type CropBordersProps = {
|
|
4
|
-
onMouseDown: (e: React.MouseEvent, type: Direction, cursor: string) => void;
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
export const CropBorders = ({ onMouseDown }: CropBordersProps) => {
|
|
8
|
-
return (
|
|
9
|
-
<>
|
|
10
|
-
<span
|
|
11
|
-
className="crop-b crop-b-t"
|
|
12
|
-
onMouseDown={(e: React.MouseEvent) => onMouseDown(e, "t", "ns")}
|
|
13
|
-
/>
|
|
14
|
-
<span
|
|
15
|
-
className="crop-b crop-b-r"
|
|
16
|
-
onMouseDown={(e) => onMouseDown(e, "r", "ew")}
|
|
17
|
-
/>
|
|
18
|
-
<span
|
|
19
|
-
className="crop-b crop-b-b"
|
|
20
|
-
onMouseDown={(e) => onMouseDown(e, "b", "ns")}
|
|
21
|
-
/>
|
|
22
|
-
<span
|
|
23
|
-
className="crop-b crop-b-l"
|
|
24
|
-
onMouseDown={(e) => onMouseDown(e, "l", "ew")}
|
|
25
|
-
/>
|
|
26
|
-
</>
|
|
27
|
-
);
|
|
28
|
-
};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import type { Direction } from "../types";
|
|
3
|
-
|
|
4
|
-
type CropPointerProps = {
|
|
5
|
-
onMouseDown: (
|
|
6
|
-
e: React.MouseEvent | React.TouchEvent,
|
|
7
|
-
type: Direction,
|
|
8
|
-
cursor?: string,
|
|
9
|
-
) => void;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export const CropPointer = ({ onMouseDown }: CropPointerProps) => {
|
|
13
|
-
return (
|
|
14
|
-
<div className="crop-p-b">
|
|
15
|
-
<div
|
|
16
|
-
className="crop-p-p"
|
|
17
|
-
onTouchStart={(e) => onMouseDown(e, "br", "nwse")}
|
|
18
|
-
/>
|
|
19
|
-
</div>
|
|
20
|
-
);
|
|
21
|
-
};
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import type { Direction } from "../types";
|
|
2
|
-
|
|
3
|
-
type CropPointersProps = {
|
|
4
|
-
onMouseDown: (e: React.MouseEvent, type: Direction, cursor: string) => void;
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
export const CropPointers = ({ onMouseDown }: CropPointersProps) => {
|
|
8
|
-
return (
|
|
9
|
-
<>
|
|
10
|
-
<span
|
|
11
|
-
className="crop-ps crop-ps-tl"
|
|
12
|
-
onMouseDown={(e) => onMouseDown(e, "tl", "nwse")}
|
|
13
|
-
/>
|
|
14
|
-
<span
|
|
15
|
-
className="crop-ps crop-ps-t"
|
|
16
|
-
onMouseDown={(e) => onMouseDown(e, "t", "ns")}
|
|
17
|
-
/>
|
|
18
|
-
<span
|
|
19
|
-
className="crop-ps crop-ps-tr"
|
|
20
|
-
onMouseDown={(e) => onMouseDown(e, "tr", "nesw")}
|
|
21
|
-
/>
|
|
22
|
-
<span
|
|
23
|
-
className="crop-ps crop-ps-r"
|
|
24
|
-
onMouseDown={(e) => onMouseDown(e, "r", "ew")}
|
|
25
|
-
/>
|
|
26
|
-
<span
|
|
27
|
-
className="crop-ps crop-ps-br"
|
|
28
|
-
onMouseDown={(e) => onMouseDown(e, "br", "nwse")}
|
|
29
|
-
/>
|
|
30
|
-
<span
|
|
31
|
-
className="crop-ps crop-ps-b"
|
|
32
|
-
onMouseDown={(e) => onMouseDown(e, "b", "ns")}
|
|
33
|
-
/>
|
|
34
|
-
<span
|
|
35
|
-
className="crop-ps crop-ps-bl"
|
|
36
|
-
onMouseDown={(e) => onMouseDown(e, "bl", "nesw")}
|
|
37
|
-
/>
|
|
38
|
-
<span
|
|
39
|
-
className="crop-ps crop-ps-l"
|
|
40
|
-
onMouseDown={(e) => onMouseDown(e, "l", "ew")}
|
|
41
|
-
/>
|
|
42
|
-
</>
|
|
43
|
-
);
|
|
44
|
-
};
|