Skip to content

Commit 694b9b2

Browse files
committed
Add blur support and add cropper package in package.json file
1 parent 42f314a commit 694b9b2

File tree

8 files changed

+127
-23
lines changed

8 files changed

+127
-23
lines changed

components/editor/SnippngCodeArea.tsx

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ const SnippngCodeArea = () => {
5555
editorWidth,
5656
uid,
5757
bgImageVisiblePatch,
58+
bgBlur,
5859
} = editorConfig;
5960

6061
const saveSnippet = async () => {
@@ -100,19 +101,6 @@ const SnippngCodeArea = () => {
100101
}
101102
};
102103

103-
const getEditorBackground = () => {
104-
if (bgImageVisiblePatch) {
105-
return {
106-
backgroundImage: `url(${bgImageVisiblePatch})`,
107-
backgroundSize: "cover",
108-
};
109-
} else {
110-
return {
111-
background: getEditorWrapperBg(wrapperBg, gradients, gradientAngle),
112-
};
113-
}
114-
};
115-
116104
return (
117105
<>
118106
<section
@@ -139,14 +127,26 @@ const SnippngCodeArea = () => {
139127
id="code-wrapper"
140128
ref={wrapperRef}
141129
className={clsx(
142-
"overflow-auto p-16 max-w-full",
130+
"overflow-auto p-16 max-w-full relative",
143131
editorWidth ? "w-fit" : "w-full"
144132
)}
145133
style={{
146-
...getEditorBackground(),
134+
background: bgImageVisiblePatch
135+
? "none"
136+
: getEditorWrapperBg(wrapperBg, gradients, gradientAngle),
147137
padding: `${paddingVertical}px ${paddingHorizontal}px`,
148138
}}
149139
>
140+
{bgImageVisiblePatch ? (
141+
<img
142+
src={bgImageVisiblePatch}
143+
alt="bg-image"
144+
className="w-full h-full object-cover z-0 absolute inset-0"
145+
style={{
146+
filter: `blur(${bgBlur || 0}px)`,
147+
}}
148+
/>
149+
) : null}
150150
<div
151151
ref={editorRef}
152152
data-testid="editor-container"

components/editor/SnippngControlHeader.tsx

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import { useSnippngEditor } from "@/context/SnippngEditorContext";
22
import { useToast } from "@/context/ToastContext";
33
import { ColorPicker } from "@/lib/color-picker";
4-
import { DOWNLOAD_OPTIONS, LANGUAGES, THEMES } from "@/lib/constants";
4+
import {
5+
defaultEditorConfig,
6+
DOWNLOAD_OPTIONS,
7+
LANGUAGES,
8+
THEMES,
9+
} from "@/lib/constants";
510
import { ImagePicker } from "@/lib/image-picker";
611
import { SelectOptionInterface } from "@/types";
712
import { getEditorWrapperBg } from "@/utils";
@@ -45,6 +50,8 @@ const SnippngControlHeader: React.FC<{
4550
gradients,
4651
gradientAngle,
4752
snippetsName,
53+
bgBlur = 0,
54+
bgImageVisiblePatch,
4855
} = editorConfig;
4956

5057
const downloadImage = (type: SelectOptionInterface) => {
@@ -238,6 +245,51 @@ const SnippngControlHeader: React.FC<{
238245
}}
239246
/>
240247
</div>
248+
<div className="py-1 px-2">
249+
<Checkbox
250+
label="Remove background"
251+
id="remove-bg"
252+
data-testid="remove-bg"
253+
checked={
254+
wrapperBg === "transparent" &&
255+
!gradients.length &&
256+
!bgBlur &&
257+
!bgImageVisiblePatch
258+
}
259+
onChange={(e) => {
260+
if (!e.target.checked) {
261+
handleConfigChange("bgImageVisiblePatch")(
262+
defaultEditorConfig.bgImageVisiblePatch
263+
);
264+
handleConfigChange("bgBlur")(defaultEditorConfig.bgBlur);
265+
handleConfigChange("gradients")(
266+
defaultEditorConfig.gradients
267+
);
268+
handleConfigChange("wrapperBg")(
269+
defaultEditorConfig.wrapperBg
270+
);
271+
} else {
272+
handleConfigChange("bgImageVisiblePatch")(null);
273+
handleConfigChange("bgBlur")(0);
274+
handleConfigChange("gradients")([]);
275+
handleConfigChange("wrapperBg")("transparent");
276+
}
277+
}}
278+
/>
279+
</div>
280+
<div className="py-1 px-2 z-30">
281+
<Range
282+
label={`Bg blur (${bgBlur}px)`}
283+
value={bgBlur}
284+
max={20}
285+
min={0}
286+
rangeMax="20"
287+
rangeMin="0"
288+
onChange={(e) => {
289+
handleConfigChange("bgBlur")(+e.target.value);
290+
}}
291+
/>
292+
</div>
241293
<div className="py-1 px-2 z-30">
242294
<Range
243295
label={`Font size (${editorFontSize}px)`}

components/form/Range.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ interface Props extends React.InputHTMLAttributes<HTMLInputElement> {
88
}
99
const Range: React.FC<Props> = ({ rangeMax, rangeMin, label, ...props }) => {
1010
return (
11-
<div className="w-full my-2">
11+
<div className="w-full my-2 dark:text-white text-zinc-900">
1212
<div>
1313
<p>{label}</p>
1414
</div>

lib/constants.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,10 +463,37 @@ export const PEXELS_QUERY_STRINGS = [
463463
"gradient",
464464
"landscape",
465465
"sky",
466-
"nightsky",
466+
"night-sky",
467467
"galaxy",
468468
"coding",
469469
"abstract",
470+
"texture",
471+
"beautiful-zoom-backgrounds",
472+
"colors",
473+
"rainbow",
474+
"programming",
475+
"gray",
476+
"teal",
477+
"blue",
478+
"red",
479+
"fruits",
480+
"orange",
481+
"shine",
482+
"stars",
483+
"green",
484+
"food",
485+
"coffee",
486+
"ice",
487+
"ocean",
488+
"plane",
489+
"seascapes",
490+
"art",
491+
"creative",
492+
"summer",
493+
"tea",
494+
"water",
495+
"juice",
496+
"ice-cream",
470497
];
471498

472499
export const defaultEditorConfig: SnippngEditorConfigInterface = {
@@ -491,6 +518,7 @@ export const defaultEditorConfig: SnippngEditorConfigInterface = {
491518
gradientAngle: 140,
492519
editorWidth: 0,
493520
bgImageVisiblePatch: null,
521+
bgBlur: 0,
494522
};
495523

496524
export const DEFAULT_BASE_SETUP = {

lib/image-picker/ImagePicker.tsx

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import ReactCrop, {
88
PixelCrop,
99
} from "react-image-crop";
1010

11-
import { Button, Input } from "@/components";
11+
import { Button, Input, Range } from "@/components";
1212
import { useToast } from "@/context/ToastContext";
1313
import {
1414
CursorArrowRaysIcon,
@@ -35,6 +35,8 @@ const centerAspectCrop = (
3535
{
3636
unit: "%",
3737
width: 100,
38+
x: 0,
39+
y: 0,
3840
},
3941
aspect,
4042
mediaWidth,
@@ -140,6 +142,7 @@ const ImagePicker: React.FC<Props> = ({ aspect, children, onChange }) => {
140142

141143
const fetchImageFromPexels = async () => {
142144
try {
145+
setFetchingImage(true);
143146
const headers = new Headers();
144147
headers.append(
145148
"Authorization",
@@ -158,10 +161,15 @@ const ImagePicker: React.FC<Props> = ({ aspect, children, onChange }) => {
158161
);
159162
const pictures = await res.json();
160163
if (pictures?.photos.length) {
161-
getBase64FromUrl(pictures?.photos[0]?.src?.medium);
164+
await getBase64FromUrl(
165+
pictures?.photos[0]?.src?.medium +
166+
"?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2"
167+
);
162168
}
163169
} catch (error) {
164170
console.log("Error while fetching images from pexels ", error);
171+
} finally {
172+
setFetchingImage(false);
165173
}
166174
};
167175

@@ -218,16 +226,18 @@ const ImagePicker: React.FC<Props> = ({ aspect, children, onChange }) => {
218226
onChange={onSelectFile}
219227
/>
220228
<button
229+
disabled={fetchingImage}
221230
onClick={fetchImageFromPexels}
222-
className="w-full mt-3 inline-flex items-center text-center dark:border-zinc-400 border-zinc-400 rounded-sm px-2 py-1 border-[1px] text-zinc-900 dark:text-white"
231+
className="w-full disabled:opacity-40 mt-3 inline-flex items-center text-center dark:border-zinc-400 border-zinc-400 rounded-sm px-2 py-1 border-[1px] text-zinc-900 dark:text-white"
223232
>
224-
<PhotoIcon className="h-4 w-4 mr-2" /> From pexels
233+
<PhotoIcon className="h-4 w-4 mr-2" /> Random img (pexels)
225234
</button>
226235
{!!src && (
227236
<div className="w-full flex flex-col justify-start items-end">
228237
<button onClick={resetImageSelection}>
229-
<XCircleIcon className="h-6 w-6 my-2 dark:text-white text-zinc-900" />
238+
<XCircleIcon className="h-6 my-2 w-6 dark:text-white text-zinc-900" />
230239
</button>
240+
231241
<ReactCrop
232242
crop={crop}
233243
onChange={(_, percentCrop) => setCrop(percentCrop)}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"next-pwa": "^5.6.0",
2929
"react": "18.2.0",
3030
"react-dom": "18.2.0",
31+
"react-image-crop": "^10.0.9",
3132
"typescript": "4.9.4"
3233
},
3334
"devDependencies": {

types/editor.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export interface SnippngEditorConfigInterface {
2828
snippetsName: string;
2929
wrapperBg: string;
3030
bgImageVisiblePatch: string | null;
31+
bgBlur: number;
3132
}
3233

3334
export interface SnippngEditorContextInterface {

yarn.lock

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3335,6 +3335,11 @@ cliui@^8.0.1:
33353335
strip-ansi "^6.0.1"
33363336
wrap-ansi "^7.0.0"
33373337

3338+
clsx@^1.2.1:
3339+
version "1.2.1"
3340+
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12"
3341+
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
3342+
33383343
co@^4.6.0:
33393344
version "4.6.0"
33403345
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
@@ -6168,6 +6173,13 @@ [email protected]:
61686173
loose-envify "^1.1.0"
61696174
scheduler "^0.23.0"
61706175

6176+
react-image-crop@^10.0.9:
6177+
version "10.0.9"
6178+
resolved "https://registry.yarnpkg.com/react-image-crop/-/react-image-crop-10.0.9.tgz#94c65833d4e8ed16fe645227ff26915bba177359"
6179+
integrity sha512-fqn6a811cx/sE7jtu8txL4lBTwgZYuEVNvy7UPKMNMWeRcZa6v0ja11+Gd9nZQiBfaxDal3PBcKhGBLQ956UNg==
6180+
dependencies:
6181+
clsx "^1.2.1"
6182+
61716183
react-is@^16.13.1:
61726184
version "16.13.1"
61736185
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"

0 commit comments

Comments
 (0)