From ae66ecee9b335fad258bb2cb366d7de9165e2b64 Mon Sep 17 00:00:00 2001 From: R1fl33 Date: Sun, 17 Nov 2024 01:35:40 -0800 Subject: [PATCH 1/3] custom dimension thingy added --- pnpm-lock.yaml | 8 +-- src/app/(tools)/svg-to-png/svg-tool.tsx | 95 ++++++++++++++++++++----- src/components/option-selector.tsx | 66 +++++++++++++++++ 3 files changed, 149 insertions(+), 20 deletions(-) create mode 100644 src/components/option-selector.tsx diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 30439a1..d0fd7d7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2697,7 +2697,7 @@ snapshots: debug: 4.3.7 enhanced-resolve: 5.17.1 eslint: 8.57.1 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.13.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.13.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.13.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 @@ -2710,7 +2710,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.13.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.13.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.13.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: @@ -2732,7 +2732,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.13.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.13.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.13.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -3923,4 +3923,4 @@ snapshots: dependencies: zod: 3.23.8 - zod@3.23.8: {} \ No newline at end of file + zod@3.23.8: {} diff --git a/src/app/(tools)/svg-to-png/svg-tool.tsx b/src/app/(tools)/svg-to-png/svg-tool.tsx index 137d778..541e1a5 100644 --- a/src/app/(tools)/svg-to-png/svg-tool.tsx +++ b/src/app/(tools)/svg-to-png/svg-tool.tsx @@ -5,9 +5,12 @@ import { useLocalStorage } from "@/hooks/use-local-storage"; import { UploadBox } from "@/components/shared/upload-box"; import { SVGScaleSelector } from "@/components/svg-scale-selector"; +import { OptionSelector } from "@/components/option-selector"; export type Scale = "custom" | number; +type ResolutionMode = "scale" | "dimensions"; + function scaleSvg(svgContent: string, scale: number) { const parser = new DOMParser(); const svgDoc = parser.parseFromString(svgContent, "image/svg+xml"); @@ -141,15 +144,44 @@ function SVGToolCore(props: { fileUploaderProps: FileUploaderResult }) { const { rawContent, imageMetadata, handleFileUploadEvent, cancel } = props.fileUploaderProps; + const [resolutionMode, setResolutionMode] = useLocalStorage( + "svgTool_resolutionMode", + "scale" + ); const [scale, setScale] = useLocalStorage("svgTool_scale", 1); const [customScale, setCustomScale] = useLocalStorage( "svgTool_customScale", - 1, + 1 + ); + const [customWidth, setCustomWidth] = useLocalStorage( + "svgTool_customWidth", + imageMetadata?.width ?? 0 + ); + const [customHeight, setCustomHeight] = useLocalStorage( + "svgTool_customHeight", + imageMetadata?.height ?? 0 ); // Get the actual numeric scale value const effectiveScale = scale === "custom" ? customScale : scale; + // Calculate dimensions based on mode + const finalDimensions = useMemo(() => { + if (!imageMetadata) return { width: 0, height: 0 }; + + if (resolutionMode === "scale") { + return { + width: imageMetadata.width * effectiveScale, + height: imageMetadata.height * effectiveScale, + }; + } else { + return { + width: customWidth, + height: customHeight, + }; + } + }, [imageMetadata, resolutionMode, effectiveScale, customWidth, customHeight]); + if (!imageMetadata) return ( -

- {imageMetadata.name} -

+

{imageMetadata.name}

{/* Size Information */} @@ -180,24 +210,57 @@ function SVGToolCore(props: { fileUploaderProps: FileUploaderResult }) {
- Scaled + Output - {imageMetadata.width * effectiveScale} ×{" "} - {imageMetadata.height * effectiveScale} + {Math.round(finalDimensions.width)} × {Math.round(finalDimensions.height)}
- {/* Scale Controls */} - + option === "scale" ? "Scale Factor" : "Custom Dimensions" + } /> + {/* Scale Controls */} + {resolutionMode === "scale" ? ( + + ) : ( +
+ Dimensions (px) +
+ setCustomWidth(Math.max(1, parseInt(e.target.value) || 0))} + className="w-24 rounded-lg bg-white/5 px-3 py-1.5 text-sm text-white" + placeholder="Width" + /> + × + setCustomHeight(Math.max(1, parseInt(e.target.value) || 0))} + className="w-24 rounded-lg bg-white/5 px-3 py-1.5 text-sm text-white" + placeholder="Height" + /> +
+
+ )} + {/* Action Buttons */}
diff --git a/src/components/option-selector.tsx b/src/components/option-selector.tsx new file mode 100644 index 0000000..157f617 --- /dev/null +++ b/src/components/option-selector.tsx @@ -0,0 +1,66 @@ +import { useEffect, useRef } from "react"; + +interface OptionSelectorProps { + title: string; + options: T[]; + selected: T; + onChange: (option: T) => void; + formatOption?: (option: T) => string; +} + +export function OptionSelector({ + title, + options, + selected, + onChange, + formatOption = (option) => `${option}`, +}: OptionSelectorProps) { + const containerRef = useRef(null); + const selectedRef = useRef(null); + const highlightRef = useRef(null); + + useEffect(() => { + if (selectedRef.current && highlightRef.current && containerRef.current) { + const container = containerRef.current; + const selected = selectedRef.current; + const highlight = highlightRef.current; + + const containerRect = container.getBoundingClientRect(); + const selectedRect = selected.getBoundingClientRect(); + + highlight.style.left = `${selectedRect.left - containerRect.left}px`; + highlight.style.width = `${selectedRect.width}px`; + } + }, [selected]); + + return ( +
+ {title} +
+
+
+ {options.map((option) => ( + + ))} +
+
+
+ ); +} \ No newline at end of file From 612518fce700a72353c0560b536b4c0170c09144 Mon Sep 17 00:00:00 2001 From: R1fl33 Date: Mon, 18 Nov 2024 20:27:14 -0800 Subject: [PATCH 2/3] Made pnmp-lock.yaml the same because no change needed --- README.md | 2 +- pnpm-lock.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5d4d844..890443d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ ## QuickPic - Tools For Pictures (By Theo) -I wanted a better way to upscale svgs as pngs so I built it. Also wanted a better way to make images into squares. Open source because why not. Free because it only runs on client. +I wanted a better way to upscale svgs as pngs so I built it. Also wanted a better way to make images into squares. Open source because why not. Free because it only runs on client. Added Custom dimensions cause why not. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d0fd7d7..e93917c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1844,7 +1844,7 @@ packages: hasBin: true word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDu9q03wN5cLbpW3RhrVD7I3+sDW1khJxi+bayAZuGx03R5qNV9y/EA==} engines: {node: '>=0.10.0'} wrap-ansi@7.0.0: From b4b31fe6bc6e9bd501fc2daf908b26c617e08206 Mon Sep 17 00:00:00 2001 From: R1fl33 Date: Tue, 19 Nov 2024 17:58:47 -0800 Subject: [PATCH 3/3] no change to README.md the same because no change needed --- README.md | 2 +- pnpm-lock.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 890443d..5d4d844 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ ## QuickPic - Tools For Pictures (By Theo) -I wanted a better way to upscale svgs as pngs so I built it. Also wanted a better way to make images into squares. Open source because why not. Free because it only runs on client. Added Custom dimensions cause why not. +I wanted a better way to upscale svgs as pngs so I built it. Also wanted a better way to make images into squares. Open source because why not. Free because it only runs on client. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e93917c..30439a1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1844,7 +1844,7 @@ packages: hasBin: true word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDu9q03wN5cLbpW3RhrVD7I3+sDW1khJxi+bayAZuGx03R5qNV9y/EA==} + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} wrap-ansi@7.0.0: @@ -2697,7 +2697,7 @@ snapshots: debug: 4.3.7 enhanced-resolve: 5.17.1 eslint: 8.57.1 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.13.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.13.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.13.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 @@ -2710,7 +2710,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.13.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.13.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.13.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: @@ -2732,7 +2732,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.13.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.13.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.13.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -3923,4 +3923,4 @@ snapshots: dependencies: zod: 3.23.8 - zod@3.23.8: {} + zod@3.23.8: {} \ No newline at end of file