update at 2026-02-14 16:11:35
This commit is contained in:
@@ -1 +1 @@
|
|||||||
import{_ as v}from"./index-DIWcLmcM.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-BuyS14I8.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};
|
||||||
1
frontend/dist/assets/index-BgnhMzsV.css
vendored
Normal file
1
frontend/dist/assets/index-BgnhMzsV.css
vendored
Normal file
File diff suppressed because one or more lines are too long
4
frontend/dist/assets/index-BuyS14I8.js
vendored
Normal file
4
frontend/dist/assets/index-BuyS14I8.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
frontend/dist/assets/index-CmSlhqXj.css
vendored
1
frontend/dist/assets/index-CmSlhqXj.css
vendored
File diff suppressed because one or more lines are too long
4
frontend/dist/assets/index-DIWcLmcM.js
vendored
4
frontend/dist/assets/index-DIWcLmcM.js
vendored
File diff suppressed because one or more lines are too long
4
frontend/dist/index.html
vendored
4
frontend/dist/index.html
vendored
@@ -8,8 +8,8 @@
|
|||||||
<link rel="apple-touch-icon" href="/favicon_new.png" />
|
<link rel="apple-touch-icon" href="/favicon_new.png" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Font2SVG - 字体转SVG工具</title>
|
<title>Font2SVG - 字体转SVG工具</title>
|
||||||
<script type="module" crossorigin src="/assets/index-DIWcLmcM.js"></script>
|
<script type="module" crossorigin src="/assets/index-BuyS14I8.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-CmSlhqXj.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-BgnhMzsV.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ type SvgPreviewExpose = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const svgPreviewRef = ref<SvgPreviewExpose | null>(null)
|
const svgPreviewRef = ref<SvgPreviewExpose | null>(null)
|
||||||
|
const showWeixinQrModal = ref(false)
|
||||||
|
|
||||||
const fontSizePercent = computed(() => {
|
const fontSizePercent = computed(() => {
|
||||||
const raw = ((uiStore.fontSize - 10) / (500 - 10)) * 100
|
const raw = ((uiStore.fontSize - 10) / (500 - 10)) * 100
|
||||||
@@ -312,10 +313,33 @@ console.log('App.vue: script setup completed')
|
|||||||
<img src="./assets/icons/export-png.svg" alt="导出PNG" class="w-12 h-12 object-contain" />
|
<img src="./assets/icons/export-png.svg" alt="导出PNG" class="w-12 h-12 object-contain" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="w-[54px] h-[42px] shrink-0" title="微信小程序">
|
<button
|
||||||
|
@click="showWeixinQrModal = true"
|
||||||
|
class="w-[54px] h-[42px] shrink-0 cursor-pointer hover:opacity-85 transition-opacity p-0 border-0 bg-transparent"
|
||||||
|
title="微信小程序"
|
||||||
|
>
|
||||||
<img src="./assets/icons/weixin.svg" alt="微信小程序二维码" class="w-full h-full object-contain" />
|
<img src="./assets/icons/weixin.svg" alt="微信小程序二维码" class="w-full h-full object-contain" />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 微信小程序二维码弹窗 -->
|
||||||
|
<div
|
||||||
|
v-if="showWeixinQrModal"
|
||||||
|
class="fixed inset-0 z-50 flex items-center justify-center bg-black/50"
|
||||||
|
@click.self="showWeixinQrModal = false"
|
||||||
|
>
|
||||||
|
<div class="bg-white rounded-xl p-6 shadow-xl relative max-w-[320px]">
|
||||||
|
<button
|
||||||
|
@click="showWeixinQrModal = false"
|
||||||
|
class="absolute top-2 right-2 w-8 h-8 flex items-center justify-center text-gray-400 hover:text-gray-600 transition-colors border-0 bg-transparent cursor-pointer text-xl"
|
||||||
|
title="关闭"
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</button>
|
||||||
|
<h3 class="text-center text-gray-800 font-medium mb-4">微信扫码使用小程序</h3>
|
||||||
|
<img src="./assets/icons/weixin.svg" alt="微信小程序二维码" class="w-64 h-64 object-contain" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Frame 9: 主内容区 -->
|
<!-- Frame 9: 主内容区 -->
|
||||||
|
|||||||
Reference in New Issue
Block a user