mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-05-04 05:19:12 -04:00
fix: replace svg-to-url, ui improve and build
This commit is contained in:
parent
e55d4fa5b2
commit
28699f7b5d
8 changed files with 283 additions and 167 deletions
|
@ -286,6 +286,9 @@
|
||||||
"watchTriggerable": true,
|
"watchTriggerable": true,
|
||||||
"watchWithFilter": true,
|
"watchWithFilter": true,
|
||||||
"whenever": true,
|
"whenever": true,
|
||||||
"toValue": true
|
"toValue": true,
|
||||||
|
"injectLocal": true,
|
||||||
|
"provideLocal": true,
|
||||||
|
"useClipboardItems": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
3
auto-imports.d.ts
vendored
3
auto-imports.d.ts
vendored
|
@ -36,6 +36,7 @@ declare global {
|
||||||
const h: typeof import('vue')['h']
|
const h: typeof import('vue')['h']
|
||||||
const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch']
|
const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch']
|
||||||
const inject: typeof import('vue')['inject']
|
const inject: typeof import('vue')['inject']
|
||||||
|
const injectLocal: typeof import('@vueuse/core')['injectLocal']
|
||||||
const isDefined: typeof import('@vueuse/core')['isDefined']
|
const isDefined: typeof import('@vueuse/core')['isDefined']
|
||||||
const isProxy: typeof import('vue')['isProxy']
|
const isProxy: typeof import('vue')['isProxy']
|
||||||
const isReactive: typeof import('vue')['isReactive']
|
const isReactive: typeof import('vue')['isReactive']
|
||||||
|
@ -65,6 +66,7 @@ declare global {
|
||||||
const onUpdated: typeof import('vue')['onUpdated']
|
const onUpdated: typeof import('vue')['onUpdated']
|
||||||
const pausableWatch: typeof import('@vueuse/core')['pausableWatch']
|
const pausableWatch: typeof import('@vueuse/core')['pausableWatch']
|
||||||
const provide: typeof import('vue')['provide']
|
const provide: typeof import('vue')['provide']
|
||||||
|
const provideLocal: typeof import('@vueuse/core')['provideLocal']
|
||||||
const reactify: typeof import('@vueuse/core')['reactify']
|
const reactify: typeof import('@vueuse/core')['reactify']
|
||||||
const reactifyObject: typeof import('@vueuse/core')['reactifyObject']
|
const reactifyObject: typeof import('@vueuse/core')['reactifyObject']
|
||||||
const reactive: typeof import('vue')['reactive']
|
const reactive: typeof import('vue')['reactive']
|
||||||
|
@ -128,6 +130,7 @@ declare global {
|
||||||
const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation']
|
const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation']
|
||||||
const useCached: typeof import('@vueuse/core')['useCached']
|
const useCached: typeof import('@vueuse/core')['useCached']
|
||||||
const useClipboard: typeof import('@vueuse/core')['useClipboard']
|
const useClipboard: typeof import('@vueuse/core')['useClipboard']
|
||||||
|
const useClipboardItems: typeof import('@vueuse/core')['useClipboardItems']
|
||||||
const useCloned: typeof import('@vueuse/core')['useCloned']
|
const useCloned: typeof import('@vueuse/core')['useCloned']
|
||||||
const useColorMode: typeof import('@vueuse/core')['useColorMode']
|
const useColorMode: typeof import('@vueuse/core')['useColorMode']
|
||||||
const useConfirmDialog: typeof import('@vueuse/core')['useConfirmDialog']
|
const useConfirmDialog: typeof import('@vueuse/core')['useConfirmDialog']
|
||||||
|
|
3
components.d.ts
vendored
3
components.d.ts
vendored
|
@ -166,8 +166,11 @@ declare module '@vue/runtime-core' {
|
||||||
NMenu: typeof import('naive-ui')['NMenu']
|
NMenu: typeof import('naive-ui')['NMenu']
|
||||||
NP: typeof import('naive-ui')['NP']
|
NP: typeof import('naive-ui')['NP']
|
||||||
NProgress: typeof import('naive-ui')['NProgress']
|
NProgress: typeof import('naive-ui')['NProgress']
|
||||||
|
NRadio: typeof import('naive-ui')['NRadio']
|
||||||
|
NRadioGroup: typeof import('naive-ui')['NRadioGroup']
|
||||||
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
||||||
NSlider: typeof import('naive-ui')['NSlider']
|
NSlider: typeof import('naive-ui')['NSlider']
|
||||||
|
NSpace: typeof import('naive-ui')['NSpace']
|
||||||
NSpin: typeof import('naive-ui')['NSpin']
|
NSpin: typeof import('naive-ui')['NSpin']
|
||||||
NStatistic: typeof import('naive-ui')['NStatistic']
|
NStatistic: typeof import('naive-ui')['NStatistic']
|
||||||
NSwitch: typeof import('naive-ui')['NSwitch']
|
NSwitch: typeof import('naive-ui')['NSwitch']
|
||||||
|
|
|
@ -82,13 +82,12 @@
|
||||||
"plausible-tracker": "^0.3.8",
|
"plausible-tracker": "^0.3.8",
|
||||||
"qrcode": "^1.5.1",
|
"qrcode": "^1.5.1",
|
||||||
"sql-formatter": "^13.0.0",
|
"sql-formatter": "^13.0.0",
|
||||||
"svg-to-url": "^4.0.0",
|
"svgo": "^3.3.2",
|
||||||
"ua-parser-js": "^1.0.35",
|
"ua-parser-js": "^1.0.35",
|
||||||
"ulid": "^2.3.0",
|
"ulid": "^2.3.0",
|
||||||
"unicode-emoji-json": "^0.4.0",
|
"unicode-emoji-json": "^0.4.0",
|
||||||
"unplugin-auto-import": "^0.16.4",
|
"unplugin-auto-import": "^0.16.4",
|
||||||
"uuid": "^9.0.0",
|
"uuid": "^9.0.0",
|
||||||
"vite-plugin-node-polyfills": "^0.22.0",
|
|
||||||
"vue": "^3.3.4",
|
"vue": "^3.3.4",
|
||||||
"vue-i18n": "^9.9.1",
|
"vue-i18n": "^9.9.1",
|
||||||
"vue-router": "^4.1.6",
|
"vue-router": "^4.1.6",
|
||||||
|
@ -134,6 +133,7 @@
|
||||||
"unplugin-icons": "^0.17.0",
|
"unplugin-icons": "^0.17.0",
|
||||||
"unplugin-vue-components": "^0.25.0",
|
"unplugin-vue-components": "^0.25.0",
|
||||||
"vite": "^4.4.9",
|
"vite": "^4.4.9",
|
||||||
|
"vite-plugin-node-polyfills": "^0.22.0",
|
||||||
"vite-plugin-pwa": "^0.16.0",
|
"vite-plugin-pwa": "^0.16.0",
|
||||||
"vite-plugin-vue-markdown": "^0.23.5",
|
"vite-plugin-vue-markdown": "^0.23.5",
|
||||||
"vite-svg-loader": "^4.0.0",
|
"vite-svg-loader": "^4.0.0",
|
||||||
|
|
373
pnpm-lock.yaml
generated
373
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,30 @@
|
||||||
import { stringToUrl } from 'svg-to-url';
|
import { type Config, type PluginConfig, optimize } from 'svgo';
|
||||||
|
|
||||||
|
function svgo(config: Config) {
|
||||||
|
return (data: string) => {
|
||||||
|
const { plugins = [], ...rest } = config || {};
|
||||||
|
return optimize(data, {
|
||||||
|
...rest,
|
||||||
|
plugins: [
|
||||||
|
...(plugins.length > 0 ? plugins : ['preset-default']),
|
||||||
|
'removeXMLNS',
|
||||||
|
] as PluginConfig[],
|
||||||
|
}).data.replace(/^<svg/g, '<svg xmlns="http://www.w3.org/2000/svg"');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function encodeStr(svgStr: string) {
|
||||||
|
const encoded = encodeURIComponent(svgStr)
|
||||||
|
.replace(/%20/g, ' ')
|
||||||
|
.replace(/%3D/g, '=')
|
||||||
|
.replace(/%3B/g, ';')
|
||||||
|
.replace(/%3A/g, ':')
|
||||||
|
.replace(/%2F/g, '/')
|
||||||
|
.replace(/%2C/g, ',')
|
||||||
|
.replace(/%22/g, '\'');
|
||||||
|
|
||||||
|
return `data:image/svg+xml,${encoded}`;
|
||||||
|
}
|
||||||
|
|
||||||
export type CSSType = 'Background' | 'Border' | 'ListItemBullet' | 'Url';
|
export type CSSType = 'Background' | 'Border' | 'ListItemBullet' | 'Url';
|
||||||
|
|
||||||
|
@ -21,9 +47,8 @@ async function fileToDataUrl(file: File) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function svgToDataUrl(image: string) {
|
function svgToDataUrl(svg: string) {
|
||||||
const getUrlFromSvgString = stringToUrl({});
|
return encodeStr(svgo({})(svg));
|
||||||
return getUrlFromSvgString(image);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function imageToCSS(
|
export async function imageToCSS(
|
||||||
|
|
|
@ -10,12 +10,18 @@ const typeOptions = [
|
||||||
{ label: 'CSS Data Url', value: 'Url' },
|
{ label: 'CSS Data Url', value: 'Url' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const inputType = ref<'file' | 'content'>('file');
|
||||||
const type = ref('Background');
|
const type = ref('Background');
|
||||||
const svgContent = ref('');
|
const svgContent = ref('');
|
||||||
const fileInput = ref() as Ref<File | null>;
|
const fileInput = ref() as Ref<File | null>;
|
||||||
const cssCode = computedAsync(async () => {
|
const cssCode = computedAsync(async () => {
|
||||||
try {
|
try {
|
||||||
return (await imageToCSS(fileInput.value || svgContent.value, type.value as CSSType));
|
if (inputType.value === 'file' && fileInput.value) {
|
||||||
|
return (await imageToCSS(fileInput.value, type.value as CSSType));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return (await imageToCSS(svgContent.value, type.value as CSSType));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (e: any) {
|
catch (e: any) {
|
||||||
return e.toString();
|
return e.toString();
|
||||||
|
@ -37,15 +43,31 @@ watch(svgContent, (_, newValue) => {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
<n-radio-group v-model:value="inputType" name="radiogroup" mb-2 flex justify-center>
|
||||||
|
<n-space>
|
||||||
|
<n-radio
|
||||||
|
value="file"
|
||||||
|
label="File"
|
||||||
|
/>
|
||||||
|
<n-radio
|
||||||
|
value="content"
|
||||||
|
label="Content"
|
||||||
|
/>
|
||||||
|
</n-space>
|
||||||
|
</n-radio-group>
|
||||||
|
|
||||||
<c-file-upload
|
<c-file-upload
|
||||||
|
v-if="inputType === 'file'"
|
||||||
title="Drag and drop an image here, or click to select a file"
|
title="Drag and drop an image here, or click to select a file"
|
||||||
paste-image
|
paste-image
|
||||||
@file-upload="onUpload"
|
@file-upload="onUpload"
|
||||||
/>
|
/>
|
||||||
<n-p>OR</n-p>
|
|
||||||
|
|
||||||
<c-input-text
|
<c-input-text
|
||||||
|
v-if="inputType === 'content'"
|
||||||
v-model:value="svgContent"
|
v-model:value="svgContent"
|
||||||
|
multiline
|
||||||
|
rows="5"
|
||||||
label="SVG Content"
|
label="SVG Content"
|
||||||
placeholder="Paste your SVG content here"
|
placeholder="Paste your SVG content here"
|
||||||
mb-2
|
mb-2
|
||||||
|
|
|
@ -114,8 +114,5 @@ export default defineConfig({
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
target: 'esnext',
|
target: 'esnext',
|
||||||
rollupOptions: {
|
|
||||||
external: ['node:fs/promises', 'fs'],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
Loading…
Add table
Add a link
Reference in a new issue