diff --git a/css/style.css b/css/style.css
index 534f3ce..dc6a774 100644
--- a/css/style.css
+++ b/css/style.css
@@ -2,6 +2,15 @@ body {
font-family: 'Inter', sans-serif;
}
+/* 统一处理 Iconify 图标的对齐方式,避免在按钮与文字中出现垂直偏移 */
+iconify-icon {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ vertical-align: middle;
+ line-height: 1;
+}
+
/* 狂野线条效果 */
.wild-border {
border: 3px solid;
@@ -223,9 +232,22 @@ body {
transition: color 0.2s ease;
}
+.svg-placeholder-block {
+ position: relative;
+}
+
+@keyframes svg-active-pulse {
+ 0% { box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.35), 0 6px 12px rgba(15, 23, 42, 0.15); }
+ 50% { box-shadow: 0 0 0 6px rgba(37, 99, 235, 0.15), 0 10px 18px rgba(15, 23, 42, 0.2); }
+ 100% { box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.35), 0 6px 12px rgba(15, 23, 42, 0.15); }
+}
+
.svg-placeholder-active {
- border-color: #2563eb;
- box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.2);
+ border-color: #1d4ed8;
+ background: linear-gradient(135deg, #e0f2fe 0%, #dbeafe 100%);
+ color: #1e3a8a;
+ transform: translateY(-2px);
+ /* animation: svg-active-pulse 1.6s ease-in-out infinite; */
}
.svg-content-wrapper {
diff --git a/index.html b/index.html
index ea09c65..6ed2897 100644
--- a/index.html
+++ b/index.html
@@ -25,6 +25,7 @@
@@ -43,10 +44,10 @@
-
+
-
+
@@ -85,7 +86,7 @@
-
+
diff --git a/js/app.js b/js/app.js
index c32a068..95aeff0 100644
--- a/js/app.js
+++ b/js/app.js
@@ -26,6 +26,8 @@ class ProductCanvasApp {
this.pendingSvgId = null;
this.pendingCancel = false;
this.copyClipboardSupported = typeof ClipboardItem !== 'undefined' && !!navigator.clipboard;
+ const deviceScale = typeof window !== 'undefined' ? (window.devicePixelRatio || 1) : 1;
+ this.imageExportScale = Math.min(4, Math.max(2, deviceScale));
this.initElements();
this.initEventListeners();
@@ -1214,7 +1216,7 @@ class ProductCanvasApp {
});
}
- async convertSvgToPngBlob(svgContent) {
+ async convertSvgToPngBlob(svgContent, options = {}) {
const { width, height } = this.parseSvgDimensions(svgContent);
const svgBlob = new Blob([svgContent], { type: 'image/svg+xml' });
const url = URL.createObjectURL(svgBlob);
@@ -1222,14 +1224,16 @@ class ProductCanvasApp {
try {
const img = await this.loadImageFromUrl(url);
const canvas = document.createElement('canvas');
- const canvasWidth = Math.max(1, img.naturalWidth || width || 1024);
- const canvasHeight = Math.max(1, img.naturalHeight || height || 768);
- canvas.width = canvasWidth;
- canvas.height = canvasHeight;
+ const baseWidth = Math.max(1, img.naturalWidth || width || 1024);
+ const baseHeight = Math.max(1, img.naturalHeight || height || 768);
+ const preferredScale = options.scale || this.imageExportScale || 1;
+ const exportScale = Math.min(4, Math.max(1, preferredScale));
+ canvas.width = Math.round(baseWidth * exportScale);
+ canvas.height = Math.round(baseHeight * exportScale);
const ctx = canvas.getContext('2d');
- ctx.clearRect(0, 0, canvasWidth, canvasHeight);
- ctx.drawImage(img, 0, 0, canvasWidth, canvasHeight);
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
return await new Promise((resolve, reject) => {
canvas.toBlob((blob) => {