mirror of
https://github.com/iib0011/omni-tools.git
synced 2025-11-06 00:44:57 +05:30
feat: QrCode Generator 기능 구현
This commit is contained in:
parent
7498b3c1c7
commit
2f68a5bf84
7 changed files with 205 additions and 0 deletions
|
|
@ -55,11 +55,13 @@
|
|||
"omggif": "^1.0.10",
|
||||
"pdf-lib": "^1.17.1",
|
||||
"playwright": "^1.45.0",
|
||||
"qrcode.react": "^4.2.0",
|
||||
"rc-slider": "^11.1.8",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-helmet": "^6.1.0",
|
||||
"react-image-crop": "^11.0.7",
|
||||
"react-qr-code": "^2.0.15",
|
||||
"react-router-dom": "^6.23.1",
|
||||
"tesseract.js": "^6.0.0",
|
||||
"type-fest": "^4.35.0",
|
||||
|
|
|
|||
115
pnpm-lock.yaml
generated
115
pnpm-lock.yaml
generated
|
|
@ -41,6 +41,9 @@ importers:
|
|||
'@types/ffmpeg':
|
||||
specifier: ^1.0.7
|
||||
version: 1.0.7
|
||||
'@types/js-quantities':
|
||||
specifier: ^1.6.6
|
||||
version: 1.6.6
|
||||
'@types/lodash':
|
||||
specifier: ^4.17.5
|
||||
version: 4.17.16
|
||||
|
|
@ -56,12 +59,18 @@ importers:
|
|||
color:
|
||||
specifier: ^4.2.3
|
||||
version: 4.2.3
|
||||
dayjs:
|
||||
specifier: ^1.11.13
|
||||
version: 1.11.13
|
||||
formik:
|
||||
specifier: ^2.4.6
|
||||
version: 2.4.6(react@18.3.1)
|
||||
jimp:
|
||||
specifier: ^0.22.12
|
||||
version: 0.22.12
|
||||
js-quantities:
|
||||
specifier: ^1.8.0
|
||||
version: 1.8.0
|
||||
lint-staged:
|
||||
specifier: ^15.4.3
|
||||
version: 15.5.0
|
||||
|
|
@ -74,6 +83,9 @@ importers:
|
|||
morsee:
|
||||
specifier: ^1.0.9
|
||||
version: 1.0.10
|
||||
nerdamer-prime:
|
||||
specifier: ^1.2.4
|
||||
version: 1.2.4
|
||||
notistack:
|
||||
specifier: ^3.0.1
|
||||
version: 3.0.2(csstype@3.1.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
|
|
@ -86,6 +98,9 @@ importers:
|
|||
playwright:
|
||||
specifier: ^1.45.0
|
||||
version: 1.51.1
|
||||
qrcode.react:
|
||||
specifier: ^4.2.0
|
||||
version: 4.2.0(react@18.3.1)
|
||||
rc-slider:
|
||||
specifier: ^11.1.8
|
||||
version: 11.1.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
|
|
@ -101,9 +116,15 @@ importers:
|
|||
react-image-crop:
|
||||
specifier: ^11.0.7
|
||||
version: 11.0.7(react@18.3.1)
|
||||
react-qr-code:
|
||||
specifier: ^2.0.15
|
||||
version: 2.0.15(react@18.3.1)
|
||||
react-router-dom:
|
||||
specifier: ^6.23.1
|
||||
version: 6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
tesseract.js:
|
||||
specifier: ^6.0.0
|
||||
version: 6.0.1
|
||||
type-fest:
|
||||
specifier: ^4.35.0
|
||||
version: 4.38.0
|
||||
|
|
@ -1182,6 +1203,9 @@ packages:
|
|||
'@types/hoist-non-react-statics@3.3.6':
|
||||
resolution: {integrity: sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==}
|
||||
|
||||
'@types/js-quantities@1.6.6':
|
||||
resolution: {integrity: sha512-k2Q8/Avj4Oz50flfTnfVGnUCkt7OYQ3U+lfQVELE/x5mdbwChZ7fM0wpUpVWzbuSL8kIYt9ZsFQ0RFNBv8T3Qw==}
|
||||
|
||||
'@types/json-schema@7.0.15':
|
||||
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
|
||||
|
||||
|
|
@ -1684,6 +1708,9 @@ packages:
|
|||
resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
dayjs@1.11.13:
|
||||
resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==}
|
||||
|
||||
debug@4.3.4:
|
||||
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
|
||||
engines: {node: '>=6.0'}
|
||||
|
|
@ -2243,6 +2270,9 @@ packages:
|
|||
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
idb-keyval@6.2.2:
|
||||
resolution: {integrity: sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==}
|
||||
|
||||
ieee754@1.2.1:
|
||||
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
|
||||
|
||||
|
|
@ -2423,6 +2453,9 @@ packages:
|
|||
resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-url@1.2.4:
|
||||
resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==}
|
||||
|
||||
is-weakmap@2.0.2:
|
||||
resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
|
@ -2467,6 +2500,9 @@ packages:
|
|||
jpeg-js@0.4.4:
|
||||
resolution: {integrity: sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==}
|
||||
|
||||
js-quantities@1.8.0:
|
||||
resolution: {integrity: sha512-swDw9RJpXACAWR16vAKoSojAsP6NI7cZjjnjKqhOyZSdybRUdmPr071foD3fejUKSU2JMHz99hflWkRWvfLTpQ==}
|
||||
|
||||
js-tokens@4.0.0:
|
||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||
|
||||
|
|
@ -2724,6 +2760,10 @@ packages:
|
|||
ndarray@1.0.19:
|
||||
resolution: {integrity: sha512-B4JHA4vdyZU30ELBw3g7/p9bZupyew5a7tX1Y/gGeF2hafrPaQZhgrGQfsvgfYbgdFZjYwuEcnaobeM/WMW+HQ==}
|
||||
|
||||
nerdamer-prime@1.2.4:
|
||||
resolution: {integrity: sha512-oaGnI7GUTj3T2k2PkeGf/694uLY9pYwFSOkn/5aTuz1RXdJeD6hN0+2csKagB65H6R8J1Zb7UlPq7zEzQ2dumw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
node-fetch@2.7.0:
|
||||
resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
|
||||
engines: {node: 4.x || >=6.0.0}
|
||||
|
|
@ -2822,6 +2862,10 @@ packages:
|
|||
onnxruntime-web@1.21.0-dev.20250206-d981b153d3:
|
||||
resolution: {integrity: sha512-esDVQdRic6J44VBMFLumYvcGfioMh80ceLmzF1yheJyuLKq/Th8VT2aj42XWQst+2bcWnAhw4IKmRQaqzU8ugg==}
|
||||
|
||||
opencollective-postinstall@2.0.3:
|
||||
resolution: {integrity: sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==}
|
||||
hasBin: true
|
||||
|
||||
optionator@0.9.4:
|
||||
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
|
|
@ -3060,6 +3104,14 @@ packages:
|
|||
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
qr.js@0.0.0:
|
||||
resolution: {integrity: sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ==}
|
||||
|
||||
qrcode.react@4.2.0:
|
||||
resolution: {integrity: sha512-QpgqWi8rD9DsS9EP3z7BT+5lY5SFhsqGjpgW5DY/i3mK4M9DTBNz3ErMi8BWYEfI3L0d8GIbGmcdFAS1uIRGjA==}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
|
||||
queue-microtask@1.2.3:
|
||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||
|
||||
|
|
@ -3109,6 +3161,11 @@ packages:
|
|||
react-is@19.1.0:
|
||||
resolution: {integrity: sha512-Oe56aUPnkHyyDxxkvqtd7KkdQP5uIUfHxd5XTb3wE9d/kRnZLmKbDB0GWk919tdQ+mxxPtG6EAs6RMT6i1qtHg==}
|
||||
|
||||
react-qr-code@2.0.15:
|
||||
resolution: {integrity: sha512-MkZcjEXqVKqXEIMVE0mbcGgDpkfSdd8zhuzXEl9QzYeNcw8Hq2oVIzDLWuZN2PQBwM5PWjc2S31K8Q1UbcFMfw==}
|
||||
peerDependencies:
|
||||
react: '*'
|
||||
|
||||
react-router-dom@6.30.0:
|
||||
resolution: {integrity: sha512-x30B78HV5tFk8ex0ITwzC9TTZMua4jGyA9IUlH1JLQYQTFyxr/ZxwOJq7evg1JX1qGVUcvhsmQSKdPncQrjTgA==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
|
|
@ -3426,6 +3483,12 @@ packages:
|
|||
engines: {node: '>=14.0.0'}
|
||||
hasBin: true
|
||||
|
||||
tesseract.js-core@6.0.0:
|
||||
resolution: {integrity: sha512-1Qncm/9oKM7xgrQXZXNB+NRh19qiXGhxlrR8EwFbK5SaUbPZnS5OMtP/ghtqfd23hsr1ZvZbZjeuAGcMxd/ooA==}
|
||||
|
||||
tesseract.js@6.0.1:
|
||||
resolution: {integrity: sha512-/sPvMvrCtgxnNRCjbTYbr7BRu0yfWDsMZQ2a/T5aN/L1t8wUQN6tTWv6p6FwzpoEBA0jrN2UD2SX4QQFRdoDbA==}
|
||||
|
||||
text-extensions@2.4.0:
|
||||
resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==}
|
||||
engines: {node: '>=8'}
|
||||
|
|
@ -3661,6 +3724,9 @@ packages:
|
|||
engines: {node: '>=12.0.0'}
|
||||
hasBin: true
|
||||
|
||||
wasm-feature-detect@1.8.0:
|
||||
resolution: {integrity: sha512-zksaLKM2fVlnB5jQQDqKXXwYHLQUVH9es+5TOOHwGOVJOCeRBCiPjwSg+3tN2AdTCzjgli4jijCH290kXb/zWQ==}
|
||||
|
||||
webidl-conversions@3.0.1:
|
||||
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
|
||||
|
||||
|
|
@ -3781,6 +3847,9 @@ packages:
|
|||
yup@1.6.1:
|
||||
resolution: {integrity: sha512-JED8pB50qbA4FOkDol0bYF/p60qSEDQqBD0/qeIrUCG1KbPBIQ776fCUNb9ldbPcSTxA69g/47XTo4TqWiuXOA==}
|
||||
|
||||
zlibjs@0.3.1:
|
||||
resolution: {integrity: sha512-+J9RrgTKOmlxFSDHo0pI1xM6BLVUv+o0ZT9ANtCxGkjIVCCUdx9alUF8Gm+dGLKbkkkidWIHFDZHDMpfITt4+w==}
|
||||
|
||||
zod@3.24.2:
|
||||
resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==}
|
||||
|
||||
|
|
@ -4749,6 +4818,8 @@ snapshots:
|
|||
'@types/react': 18.3.3
|
||||
hoist-non-react-statics: 3.3.2
|
||||
|
||||
'@types/js-quantities@1.6.6': {}
|
||||
|
||||
'@types/json-schema@7.0.15': {}
|
||||
|
||||
'@types/lodash@4.17.16': {}
|
||||
|
|
@ -5346,6 +5417,8 @@ snapshots:
|
|||
es-errors: 1.3.0
|
||||
is-data-view: 1.0.1
|
||||
|
||||
dayjs@1.11.13: {}
|
||||
|
||||
debug@4.3.4:
|
||||
dependencies:
|
||||
ms: 2.1.2
|
||||
|
|
@ -6054,6 +6127,8 @@ snapshots:
|
|||
dependencies:
|
||||
safer-buffer: 2.1.2
|
||||
|
||||
idb-keyval@6.2.2: {}
|
||||
|
||||
ieee754@1.2.1: {}
|
||||
|
||||
ignore@5.3.1: {}
|
||||
|
|
@ -6206,6 +6281,8 @@ snapshots:
|
|||
dependencies:
|
||||
which-typed-array: 1.1.15
|
||||
|
||||
is-url@1.2.4: {}
|
||||
|
||||
is-weakmap@2.0.2: {}
|
||||
|
||||
is-weakref@1.0.2:
|
||||
|
|
@ -6266,6 +6343,8 @@ snapshots:
|
|||
|
||||
jpeg-js@0.4.4: {}
|
||||
|
||||
js-quantities@1.8.0: {}
|
||||
|
||||
js-tokens@4.0.0: {}
|
||||
|
||||
js-tokens@9.0.0: {}
|
||||
|
|
@ -6500,6 +6579,8 @@ snapshots:
|
|||
iota-array: 1.0.0
|
||||
is-buffer: 1.1.6
|
||||
|
||||
nerdamer-prime@1.2.4: {}
|
||||
|
||||
node-fetch@2.7.0:
|
||||
dependencies:
|
||||
whatwg-url: 5.0.0
|
||||
|
|
@ -6601,6 +6682,8 @@ snapshots:
|
|||
platform: 1.3.6
|
||||
protobufjs: 7.4.0
|
||||
|
||||
opencollective-postinstall@2.0.3: {}
|
||||
|
||||
optionator@0.9.4:
|
||||
dependencies:
|
||||
deep-is: 0.1.4
|
||||
|
|
@ -6822,6 +6905,12 @@ snapshots:
|
|||
|
||||
punycode@2.3.1: {}
|
||||
|
||||
qr.js@0.0.0: {}
|
||||
|
||||
qrcode.react@4.2.0(react@18.3.1):
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
|
||||
queue-microtask@1.2.3: {}
|
||||
|
||||
rc-slider@11.1.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
||||
|
|
@ -6869,6 +6958,12 @@ snapshots:
|
|||
|
||||
react-is@19.1.0: {}
|
||||
|
||||
react-qr-code@2.0.15(react@18.3.1):
|
||||
dependencies:
|
||||
prop-types: 15.8.1
|
||||
qr.js: 0.0.0
|
||||
react: 18.3.1
|
||||
|
||||
react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
||||
dependencies:
|
||||
'@remix-run/router': 1.23.0
|
||||
|
|
@ -7265,6 +7360,22 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- ts-node
|
||||
|
||||
tesseract.js-core@6.0.0: {}
|
||||
|
||||
tesseract.js@6.0.1:
|
||||
dependencies:
|
||||
bmp-js: 0.1.0
|
||||
idb-keyval: 6.2.2
|
||||
is-url: 1.2.4
|
||||
node-fetch: 2.7.0
|
||||
opencollective-postinstall: 2.0.3
|
||||
regenerator-runtime: 0.13.11
|
||||
tesseract.js-core: 6.0.0
|
||||
wasm-feature-detect: 1.8.0
|
||||
zlibjs: 0.3.1
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
text-extensions@2.4.0: {}
|
||||
|
||||
text-table@0.2.0: {}
|
||||
|
|
@ -7489,6 +7600,8 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
wasm-feature-detect@1.8.0: {}
|
||||
|
||||
webidl-conversions@3.0.1: {}
|
||||
|
||||
webidl-conversions@7.0.0: {}
|
||||
|
|
@ -7624,4 +7737,6 @@ snapshots:
|
|||
toposort: 2.0.2
|
||||
type-fest: 2.19.0
|
||||
|
||||
zlibjs@0.3.1: {}
|
||||
|
||||
zod@3.24.2: {}
|
||||
|
|
|
|||
5
pnpm-workspace.yaml
Normal file
5
pnpm-workspace.yaml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
onlyBuiltDependencies:
|
||||
- '@swc/core'
|
||||
- esbuild
|
||||
- protobufjs
|
||||
- tesseract.js
|
||||
52
src/pages/tools/string/qr-generator/index.tsx
Normal file
52
src/pages/tools/string/qr-generator/index.tsx
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
'use client';
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import ToolTextInput from '@components/input/ToolTextInput';
|
||||
import ToolTextResult from '@components/result/ToolTextResult';
|
||||
import { ToolComponentProps } from '@tools/defineTool';
|
||||
import ToolContent from '@components/ToolContent';
|
||||
import { generateQRCodeSVG } from './service';
|
||||
|
||||
const initialValues = {};
|
||||
|
||||
export default function QRGeneratorTool({
|
||||
title,
|
||||
longDescription
|
||||
}: ToolComponentProps) {
|
||||
const [input, setInput] = useState<string>('');
|
||||
const [result, setResult] = useState<string>('');
|
||||
|
||||
const computeExternal = () => {
|
||||
setResult(generateQRCodeSVG(input));
|
||||
};
|
||||
|
||||
return (
|
||||
<ToolContent
|
||||
title={title}
|
||||
initialValues={initialValues}
|
||||
getGroups={() => []} // QR은 옵션 없이 단순 입력 → 변환
|
||||
compute={computeExternal}
|
||||
input={input}
|
||||
setInput={setInput}
|
||||
inputComponent={
|
||||
<ToolTextInput
|
||||
title="QR에 넣을 텍스트"
|
||||
value={input}
|
||||
onChange={setInput}
|
||||
/>
|
||||
}
|
||||
resultComponent={
|
||||
<ToolTextResult
|
||||
title="QR 코드 결과 (SVG)"
|
||||
value={result}
|
||||
type="html" // 결과가 SVG 문자열이라면 이렇게 설정
|
||||
/>
|
||||
}
|
||||
toolInfo={{
|
||||
title: 'QR 코드 생성기란?',
|
||||
description: longDescription
|
||||
}}
|
||||
exampleCards={[]} // 예시 생략 가능
|
||||
/>
|
||||
);
|
||||
}
|
||||
14
src/pages/tools/string/qr-generator/meta.ts
Normal file
14
src/pages/tools/string/qr-generator/meta.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { defineTool } from '@tools/defineTool';
|
||||
import { lazy } from 'react';
|
||||
//import { QrCodeIcon } from '@iconify-icons/mdi/qrcode';
|
||||
|
||||
export const tool = defineTool('string', {
|
||||
path: 'qr-generator',
|
||||
name: 'QR 코드 생성기',
|
||||
icon: 'proicons:quote',
|
||||
description: '텍스트를 QR 코드로 변환합니다.',
|
||||
shortDescription: 'QR 코드 생성',
|
||||
longDescription: '입력한 문자열을 QR 코드로 생성하는 도구입니다.',
|
||||
keywords: ['qr', 'code', 'generator', 'string', '텍스트'],
|
||||
component: lazy(() => import('./index'))
|
||||
});
|
||||
0
src/pages/tools/string/qr-generator/qr-generator.tsx
Normal file
0
src/pages/tools/string/qr-generator/qr-generator.tsx
Normal file
17
src/pages/tools/string/qr-generator/service.ts
Normal file
17
src/pages/tools/string/qr-generator/service.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import QRCode from 'qrcode';
|
||||
|
||||
/**
|
||||
* 문자열을 QR 코드 SVG 문자열로 변환
|
||||
*/
|
||||
export function generateQRCodeSVG(text: string): string {
|
||||
let svg = '';
|
||||
QRCode.toString(
|
||||
text || 'https://example.com',
|
||||
{ type: 'svg' },
|
||||
(err, out) => {
|
||||
if (err) console.error(err);
|
||||
else svg = out;
|
||||
}
|
||||
);
|
||||
return svg;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue