update at 2026-02-14 16:35:57

This commit is contained in:
douboer
2026-02-14 16:35:57 +08:00
parent e4e552cca6
commit 1fb3b51beb
7 changed files with 10 additions and 10 deletions

View File

@@ -1 +1 @@
import{_ as v}from"./index-DE_yi3QH.js";function p(t,e,n="text/plain"){const o=new Blob([t],{type:n});s(o,e)}function s(t,e){const n=URL.createObjectURL(t),o=document.createElement("a");o.href=n,o.download=e,document.body.appendChild(o),o.click(),document.body.removeChild(o),URL.revokeObjectURL(n)}function P(t,e){p(t,e,"image/svg+xml")}async function F(t,e="font2svg-export.zip"){const n=(await v(async()=>{const{default:r}=await import("./jszip.min-D7KnG0-e.js").then(i=>i.j);return{default:r}},[])).default,o=new n;for(const r of t)o.file(r.name,r.content);const a=await o.generateAsync({type:"blob"});s(a,e)}function d(t){if(!t)return null;const e=t.match(/-?\d+(\.\d+)?/);if(!e)return null;const n=Number(e[0]);return Number.isFinite(n)?n:null}function x(t){const n=new DOMParser().parseFromString(t,"image/svg+xml").documentElement,o=d(n.getAttribute("width")),a=d(n.getAttribute("height"));if(o&&a)return{width:o,height:a};const r=n.getAttribute("viewBox");if(r){const i=r.trim().split(/[\s,]+/).map(Number);if(i.length===4&&Number.isFinite(i[2])&&Number.isFinite(i[3]))return{width:Math.max(1,i[2]),height:Math.max(1,i[3])}}return{width:1024,height:1024}}async function _(t,e){const n=x(t),o=e?.scale??1,a=Math.max(1,Math.round((e?.width??n.width)*o)),r=Math.max(1,Math.round((e?.height??n.height)*o)),i=document.createElement("canvas");i.width=a,i.height=r;const l=i.getContext("2d");if(!l)throw new Error("无法创建 PNG 画布");e?.backgroundColor?(l.fillStyle=e.backgroundColor,l.fillRect(0,0,a,r)):l.clearRect(0,0,a,r);const f=new Blob([t],{type:"image/svg+xml;charset=utf-8"}),u=URL.createObjectURL(f);try{const c=new Image;await new Promise((w,b)=>{c.onload=()=>w(),c.onerror=()=>b(new Error("SVG 转 PNG 失败")),c.src=u}),l.drawImage(c,0,0,a,r)}finally{URL.revokeObjectURL(u)}const g=await new Promise(c=>{i.toBlob(c,"image/png")});if(!g)throw new Error("PNG 编码失败");return g}async function R(t,e,n){const o=await _(t,n);s(o,e)}function m(t){return t.replace(/[<>:"/\\|?*\x00-\x1F]/g,"_").replace(/\s+/g,"_").substring(0,200)}function h(t,e){const n=m(Array.from(t).slice(0,8).join(""));return`${m(e.substring(0,20))}_${n}`}function B(t,e){return`${h(t,e)}.svg`}function L(t,e){return`${h(t,e)}.png`}export{_ as convertSvgToPngBlob,s as downloadBlob,F as downloadMultipleFiles,R as downloadPngFromSvg,P as downloadSvg,p as downloadText,L as generatePngFilename,B as generateSvgFilename,m as sanitizeFilename};
import{_ as v}from"./index-BOK_W8r_.js";function p(t,e,n="text/plain"){const o=new Blob([t],{type:n});s(o,e)}function s(t,e){const n=URL.createObjectURL(t),o=document.createElement("a");o.href=n,o.download=e,document.body.appendChild(o),o.click(),document.body.removeChild(o),URL.revokeObjectURL(n)}function P(t,e){p(t,e,"image/svg+xml")}async function F(t,e="font2svg-export.zip"){const n=(await v(async()=>{const{default:r}=await import("./jszip.min-D7KnG0-e.js").then(i=>i.j);return{default:r}},[])).default,o=new n;for(const r of t)o.file(r.name,r.content);const a=await o.generateAsync({type:"blob"});s(a,e)}function d(t){if(!t)return null;const e=t.match(/-?\d+(\.\d+)?/);if(!e)return null;const n=Number(e[0]);return Number.isFinite(n)?n:null}function x(t){const n=new DOMParser().parseFromString(t,"image/svg+xml").documentElement,o=d(n.getAttribute("width")),a=d(n.getAttribute("height"));if(o&&a)return{width:o,height:a};const r=n.getAttribute("viewBox");if(r){const i=r.trim().split(/[\s,]+/).map(Number);if(i.length===4&&Number.isFinite(i[2])&&Number.isFinite(i[3]))return{width:Math.max(1,i[2]),height:Math.max(1,i[3])}}return{width:1024,height:1024}}async function _(t,e){const n=x(t),o=e?.scale??1,a=Math.max(1,Math.round((e?.width??n.width)*o)),r=Math.max(1,Math.round((e?.height??n.height)*o)),i=document.createElement("canvas");i.width=a,i.height=r;const l=i.getContext("2d");if(!l)throw new Error("无法创建 PNG 画布");e?.backgroundColor?(l.fillStyle=e.backgroundColor,l.fillRect(0,0,a,r)):l.clearRect(0,0,a,r);const f=new Blob([t],{type:"image/svg+xml;charset=utf-8"}),u=URL.createObjectURL(f);try{const c=new Image;await new Promise((w,b)=>{c.onload=()=>w(),c.onerror=()=>b(new Error("SVG 转 PNG 失败")),c.src=u}),l.drawImage(c,0,0,a,r)}finally{URL.revokeObjectURL(u)}const g=await new Promise(c=>{i.toBlob(c,"image/png")});if(!g)throw new Error("PNG 编码失败");return g}async function R(t,e,n){const o=await _(t,n);s(o,e)}function m(t){return t.replace(/[<>:"/\\|?*\x00-\x1F]/g,"_").replace(/\s+/g,"_").substring(0,200)}function h(t,e){const n=m(Array.from(t).slice(0,8).join(""));return`${m(e.substring(0,20))}_${n}`}function B(t,e){return`${h(t,e)}.svg`}function L(t,e){return`${h(t,e)}.png`}export{_ as convertSvgToPngBlob,s as downloadBlob,F as downloadMultipleFiles,R as downloadPngFromSvg,P as downloadSvg,p as downloadText,L as generatePngFilename,B as generateSvgFilename,m as sanitizeFilename};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -8,8 +8,8 @@
<link rel="apple-touch-icon" href="/favicon_new.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Font2SVG - 字体转SVG工具</title>
<script type="module" crossorigin src="/assets/index-DE_yi3QH.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-YLPL_W4p.css">
<script type="module" crossorigin src="/assets/index-BOK_W8r_.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-BgOAveGB.css">
</head>
<body>
<div id="app"></div>

View File

@@ -325,12 +325,12 @@ console.log('App.vue: script setup completed')
<!-- 移动端输入栏 (仅移动端显示) -->
<div class="input-row-mobile hidden px-2 py-1 shrink-0">
<div class="flex-1 bg-[#f7f8fa] rounded-lg px-2 h-6">
<div class="flex-1 bg-[#f7f8fa] rounded-lg px-2 h-[30px]">
<textarea
:value="uiStore.inputText"
@input="handleTextInput"
placeholder="此处输入内容"
class="w-full h-full bg-transparent border-none outline-none text-sm text-[#4e5969] placeholder-[#4e5969] resize-none leading-6 overflow-hidden"
class="w-full h-full bg-transparent border-none outline-none text-sm text-[#4e5969] placeholder-[#4e5969] resize-none leading-[30px] overflow-hidden"
/>
</div>
</div>
@@ -414,7 +414,6 @@ console.log('App.vue: script setup completed')
<div class="bottom-section-mobile hidden">
<!-- 字体选择 -->
<div class="font-selector-mobile border border-solid border-[#3EE4C3] rounded-lg p-1.5 flex flex-col gap-1 overflow-hidden">
<h2 class="text-sm text-black shrink-0 leading-none">选择</h2>
<div v-overflow-aware class="scrollbar-hover flex-1 overflow-y-auto overflow-x-hidden">
<FontSelector />
</div>
@@ -574,7 +573,7 @@ console.log('App.vue: script setup completed')
/* 显示移动端底部区域 */
.bottom-section-mobile {
display: flex !important;
flex-direction: row;
flex-direction: column;
gap: 8px;
flex: 1;
min-height: 0;
@@ -584,6 +583,7 @@ console.log('App.vue: script setup completed')
.favorites-mobile {
flex: 1;
min-width: 0;
min-height: 0;
}
.font-selector-mobile h2,

View File

@@ -56,7 +56,7 @@ const hasMatchedFonts = computed(() => {
<div class="sticky top-0 z-10 bg-white pt-1 pb-1">
<div class="flex items-center gap-3">
<div class="text-[16px] leading-none text-black font-bold shrink-0">
选择预览字体
选择字体
</div>
<div class="flex-1 min-w-0">
<div class="h-8 rounded-[10px] bg-[#F3EDF7] pl-2 flex items-center">