fix: replace svg-to-url, ui improve and build

This commit is contained in:
ShareVB 2024-11-10 19:49:01 +01:00
parent e55d4fa5b2
commit 28699f7b5d
8 changed files with 283 additions and 167 deletions

View file

@ -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';
@ -21,9 +47,8 @@ async function fileToDataUrl(file: File) {
});
}
function svgToDataUrl(image: string) {
const getUrlFromSvgString = stringToUrl({});
return getUrlFromSvgString(image);
function svgToDataUrl(svg: string) {
return encodeStr(svgo({})(svg));
}
export async function imageToCSS(

View file

@ -10,12 +10,18 @@ const typeOptions = [
{ label: 'CSS Data Url', value: 'Url' },
];
const inputType = ref<'file' | 'content'>('file');
const type = ref('Background');
const svgContent = ref('');
const fileInput = ref() as Ref<File | null>;
const cssCode = computedAsync(async () => {
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) {
return e.toString();
@ -37,15 +43,31 @@ watch(svgContent, (_, newValue) => {
<template>
<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
v-if="inputType === 'file'"
title="Drag and drop an image here, or click to select a file"
paste-image
@file-upload="onUpload"
/>
<n-p>OR</n-p>
<c-input-text
v-if="inputType === 'content'"
v-model:value="svgContent"
multiline
rows="5"
label="SVG Content"
placeholder="Paste your SVG content here"
mb-2