diff --git a/hunliji-api/hotelwelcome/welcome.go b/hunliji-api/hotelwelcome/welcome.go
index a01bbda..c4b9b03 100644
--- a/hunliji-api/hotelwelcome/welcome.go
+++ b/hunliji-api/hotelwelcome/welcome.go
@@ -19,33 +19,47 @@ var (
)
var allowedTemplates = map[string]bool{
- "banner-bottom": true,
- "banner-top": true,
- "banner-center": true,
- "banner-names": true,
+ "banner-bottom": true,
+ "banner-top": true,
+ "banner-center": true,
+ "banner-names": true,
+ "banner-lower-third": true,
+ "banner-split-names": true,
+ "banner-frame-bottom": true,
+ "banner-minimal": true,
+ "art-welcome-brush": true,
+ "art-love-life": true,
+ "art-gaobai": true,
+ "art-married": true,
+ "art-hand-love": true,
+ "art-like-you": true,
+ "art-give-home": true,
+ "art-xi-welcome": true,
+ "art-wujia": true,
+ "art-tianci": true,
+ "art-tianzuo": true,
+ "art-welcome-v": true,
+ "art-longest": true,
+ "art-just-love": true,
+ "custom": true,
+ // 旧 key 兼容
"banner-zh": true,
- "banner-lower-third": true,
"banner-upper-third": true,
"banner-mid-band": true,
"banner-left-stack": true,
"banner-right-stack": true,
- "banner-split-names": true,
"banner-vertical-left": true,
"banner-vertical-right": true,
"banner-hero-name": true,
"banner-date-focus": true,
"banner-welcome-en": true,
- "banner-minimal": true,
"banner-xi-corner": true,
"banner-top-bottom": true,
- "banner-frame-bottom": true,
- "custom": true,
- // 旧 key 兼容
- "welcome-bottom": true,
- "welcome-top": true,
- "welcome-left": true,
- "welcome-right": true,
- "welcome-center": true,
+ "welcome-bottom": true,
+ "welcome-top": true,
+ "welcome-left": true,
+ "welcome-right": true,
+ "welcome-center": true,
}
// Register 酒店迎宾海报 CRUD(均需管理员)
diff --git a/vite-tailwindcss/package-lock.json b/vite-tailwindcss/package-lock.json
index 41cde13..b114bb0 100644
--- a/vite-tailwindcss/package-lock.json
+++ b/vite-tailwindcss/package-lock.json
@@ -11,8 +11,14 @@
"@ant-design-vue/pro-layout": "^3.2.5",
"@ant-design/icons-vue": "^7.0.1",
"@fingerprintjs/fingerprintjs": "^5.2.0",
+ "@fontsource/cinzel": "^5.3.0",
"@fontsource/great-vibes": "^5.3.0",
+ "@fontsource/liu-jian-mao-cao": "^5.3.0",
+ "@fontsource/long-cang": "^5.3.0",
"@fontsource/ma-shan-zheng": "^5.3.0",
+ "@fontsource/pinyon-script": "^5.3.0",
+ "@fontsource/playfair-display": "^5.3.0",
+ "@fontsource/zhi-mang-xing": "^5.3.0",
"@fortawesome/fontawesome-free": "^6.7.2",
"@tailwindcss/vite": "^4.1.4",
"@vueuse/head": "^2.0.0",
@@ -588,6 +594,15 @@
"integrity": "sha512-j+2nInkwCQNTJcNhOjvkGM/nLRTuGJTC6xai4quqvUpjob2ssrGwBZjS7k55nOmKvge7qvJT2nS3i/IRvQSTQA==",
"license": "MIT"
},
+ "node_modules/@fontsource/cinzel": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/@fontsource/cinzel/-/cinzel-5.3.0.tgz",
+ "integrity": "sha512-KEOYTsrRppW0uRIPWBDPrQgunCS6f8u4nzZxYRBfo9SCknKojLYjK7B0ZoVmJhyVLefz271ZQRF9EOpHZlfhRw==",
+ "license": "OFL-1.1",
+ "funding": {
+ "url": "https://github.com/sponsors/ayuhito"
+ }
+ },
"node_modules/@fontsource/great-vibes": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/@fontsource/great-vibes/-/great-vibes-5.3.0.tgz",
@@ -597,6 +612,24 @@
"url": "https://github.com/sponsors/ayuhito"
}
},
+ "node_modules/@fontsource/liu-jian-mao-cao": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/@fontsource/liu-jian-mao-cao/-/liu-jian-mao-cao-5.3.0.tgz",
+ "integrity": "sha512-OaFm4okm77XoGA9jp1J89tDjdWlzb68yJCUL7LV75QxUWF/qOBRVqmhP7XFFsgcn/PL+nc2dPvRGT/8yit5LZg==",
+ "license": "OFL-1.1",
+ "funding": {
+ "url": "https://github.com/sponsors/ayuhito"
+ }
+ },
+ "node_modules/@fontsource/long-cang": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/@fontsource/long-cang/-/long-cang-5.3.0.tgz",
+ "integrity": "sha512-lCcBJb+LWZpYCVtGvQRiZPy5/EaGPuYLycpJXUIOz28EYGGqhTVWBRqY6ucaW8l1F8gvfjutY1PoAPUrFiP0wg==",
+ "license": "OFL-1.1",
+ "funding": {
+ "url": "https://github.com/sponsors/ayuhito"
+ }
+ },
"node_modules/@fontsource/ma-shan-zheng": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/@fontsource/ma-shan-zheng/-/ma-shan-zheng-5.3.0.tgz",
@@ -606,6 +639,33 @@
"url": "https://github.com/sponsors/ayuhito"
}
},
+ "node_modules/@fontsource/pinyon-script": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/@fontsource/pinyon-script/-/pinyon-script-5.3.0.tgz",
+ "integrity": "sha512-ilhy4l5apzyDkfuKb7PZBUT5Sf6nfxucdXT5TQ0wQDyWtDPlouLy1lQq3lMEPk1lPsHHVrd11EkPnEG8FqDgUA==",
+ "license": "OFL-1.1",
+ "funding": {
+ "url": "https://github.com/sponsors/ayuhito"
+ }
+ },
+ "node_modules/@fontsource/playfair-display": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/@fontsource/playfair-display/-/playfair-display-5.3.0.tgz",
+ "integrity": "sha512-uJSABalvdWc10fEPppQjQocamT21LEyRfzzWfRfqbkPz+sRv+kKpYDKyluBUskvJREkJTos9epj1WjQROGu99Q==",
+ "license": "OFL-1.1",
+ "funding": {
+ "url": "https://github.com/sponsors/ayuhito"
+ }
+ },
+ "node_modules/@fontsource/zhi-mang-xing": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/@fontsource/zhi-mang-xing/-/zhi-mang-xing-5.3.0.tgz",
+ "integrity": "sha512-V21yCCm5o2PHdXF2P9KKh7uiqL8QFFuII4DRQkpG24tfyDzJPchXKsxkcvKM43xEPvQKdbhHCBbXEFjcm/TUCQ==",
+ "license": "OFL-1.1",
+ "funding": {
+ "url": "https://github.com/sponsors/ayuhito"
+ }
+ },
"node_modules/@fortawesome/fontawesome-free": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.7.2.tgz",
diff --git a/vite-tailwindcss/package.json b/vite-tailwindcss/package.json
index 2cb3432..8bcb065 100644
--- a/vite-tailwindcss/package.json
+++ b/vite-tailwindcss/package.json
@@ -12,8 +12,14 @@
"@ant-design-vue/pro-layout": "^3.2.5",
"@ant-design/icons-vue": "^7.0.1",
"@fingerprintjs/fingerprintjs": "^5.2.0",
+ "@fontsource/cinzel": "^5.3.0",
"@fontsource/great-vibes": "^5.3.0",
+ "@fontsource/liu-jian-mao-cao": "^5.3.0",
+ "@fontsource/long-cang": "^5.3.0",
"@fontsource/ma-shan-zheng": "^5.3.0",
+ "@fontsource/pinyon-script": "^5.3.0",
+ "@fontsource/playfair-display": "^5.3.0",
+ "@fontsource/zhi-mang-xing": "^5.3.0",
"@fortawesome/fontawesome-free": "^6.7.2",
"@tailwindcss/vite": "^4.1.4",
"@vueuse/head": "^2.0.0",
diff --git a/vite-tailwindcss/src/composables/hotelWelcomeDefaults.js b/vite-tailwindcss/src/composables/hotelWelcomeDefaults.js
index 708337d..bb66092 100644
--- a/vite-tailwindcss/src/composables/hotelWelcomeDefaults.js
+++ b/vite-tailwindcss/src/composables/hotelWelcomeDefaults.js
@@ -1,15 +1,40 @@
-/** 酒店迎宾易拉宝:婚礼欢迎海报模板与文字图层(非按贵宾制) */
+/** 酒店迎宾易拉宝:普通文字 + 艺术字模板 */
+
+/** 字体预设:key 存库,css 用于渲染 */
+export const TEXT_FONTS = [
+ { value: 'serif', label: '衬线正文', css: 'var(--font-serif)', sample: '新郎新娘' },
+ { value: 'sans', label: '无衬线', css: 'var(--font-sans)', sample: 'WEDDING' },
+ { value: 'display', label: '西文衬线', css: 'var(--font-display)', sample: 'Wedding' },
+ { value: 'cinzel', label: '典雅大写', css: 'var(--font-cinzel)', sample: 'WEDDING' },
+ { value: 'script', label: '英文手写', css: 'var(--font-calligraphy)', sample: 'Wedding' },
+ { value: 'mashan', label: '马善政体', css: 'var(--font-mashan)', sample: '囍' },
+ { value: 'brush', label: '芝麻行书', css: 'var(--font-brush)', sample: '我们结婚啦' },
+ { value: 'longcang', label: '龙藏体', css: 'var(--font-longcang)', sample: '吾家有喜' },
+ { value: 'liujian', label: '刘建毛草', css: 'var(--font-liujian)', sample: '以爱之名' },
+ { value: 'kai', label: '楷体', css: 'var(--font-kai)', sample: '欢迎光临' },
+]
+
+const FONT_MAP = Object.fromEntries(TEXT_FONTS.map((f) => [f.value, f]))
+
+export function resolveFontCss(key) {
+ return FONT_MAP[key]?.css || FONT_MAP.serif.css
+}
+
+export function fontLabel(key) {
+ return FONT_MAP[key]?.label || key || '衬线正文'
+}
/**
- * zones: 模态框预览用的文字占位区域(百分比)
- * texts 由 defaultTextsForTemplate 提供,可与 zones 大致对应
+ * zones: 模态预览占位
+ * artistic: 是否艺术字模板(分组展示)
*/
export const HOTEL_WELCOME_TEMPLATES = [
+ // —— 普通文字 ——
{
value: 'banner-bottom',
label: '底部信息',
- group: '经典',
- desc: '全幅婚纱照 + 底部 WEDDING / 姓名 / 日期',
+ group: '普通文字',
+ desc: 'WEDDING / 姓名 / 日期叠底部',
zones: [
{ x: 18, y: 66, w: 64, h: 7, label: 'WEDDING' },
{ x: 22, y: 76, w: 56, h: 6, label: '姓名' },
@@ -20,8 +45,8 @@ export const HOTEL_WELCOME_TEMPLATES = [
{
value: 'banner-top',
label: '顶部欢迎',
- group: '经典',
- desc: '顶部 Welcome 与姓名,适合下半画面主体',
+ group: '普通文字',
+ desc: '顶部 Welcome 与姓名',
zones: [
{ x: 16, y: 8, w: 68, h: 5, label: 'Welcome' },
{ x: 20, y: 16, w: 60, h: 7, label: '姓名' },
@@ -31,8 +56,8 @@ export const HOTEL_WELCOME_TEMPLATES = [
{
value: 'banner-center',
label: '居中大字',
- group: '经典',
- desc: '画面中部叠 WEDDING 与新人名',
+ group: '普通文字',
+ desc: '中部 WEDDING + 姓名',
zones: [
{ x: 14, y: 40, w: 72, h: 9, label: 'WEDDING' },
{ x: 22, y: 52, w: 56, h: 6, label: '姓名' },
@@ -42,217 +67,278 @@ export const HOTEL_WELCOME_TEMPLATES = [
{
value: 'banner-names',
label: '姓名主视觉',
- group: '经典',
- desc: '新人姓名作主标题,辅以日期场地',
+ group: '普通文字',
+ desc: '姓名作主标题',
zones: [
{ x: 28, y: 56, w: 44, h: 4, label: 'OUR WEDDING' },
{ x: 30, y: 64, w: 40, h: 7, label: '新郎' },
{ x: 46, y: 74, w: 8, h: 4, label: '&' },
{ x: 30, y: 81, w: 40, h: 7, label: '新娘' },
- { x: 22, y: 92, w: 56, h: 4, label: '日期·场地' },
- ],
- },
- {
- value: 'banner-zh',
- label: '中式欢迎',
- group: '中式',
- desc: '囍 + 中文欢迎语 + 姓名日期',
- zones: [
- { x: 42, y: 8, w: 16, h: 8, label: '囍' },
- { x: 16, y: 70, w: 68, h: 6, label: '欢迎光临' },
- { x: 22, y: 80, w: 56, h: 6, label: '姓名' },
- { x: 24, y: 90, w: 52, h: 4, label: '日期' },
+ { x: 22, y: 92, w: 56, h: 4, label: '日期' },
],
},
{
value: 'banner-lower-third',
label: '下三分之一',
- group: '分区',
- desc: '文字集中在画面底部三分之一',
+ group: '普通文字',
+ desc: '文字集中在底部',
zones: [
{ x: 20, y: 70, w: 60, h: 5, label: 'Welcome' },
{ x: 18, y: 78, w: 64, h: 8, label: '姓名' },
{ x: 30, y: 90, w: 40, h: 4, label: '日期' },
],
},
- {
- value: 'banner-upper-third',
- label: '上三分之一',
- group: '分区',
- desc: '文字集中在顶部三分之一',
- zones: [
- { x: 22, y: 8, w: 56, h: 8, label: 'WEDDING' },
- { x: 20, y: 20, w: 60, h: 6, label: '姓名' },
- { x: 30, y: 30, w: 40, h: 4, label: '日期' },
- ],
- },
- {
- value: 'banner-mid-band',
- label: '中部横带',
- group: '分区',
- desc: '中部一条信息带:标题 + 姓名 + 日期',
- zones: [
- { x: 10, y: 44, w: 80, h: 5, label: 'WEDDING' },
- { x: 18, y: 52, w: 64, h: 6, label: '姓名' },
- { x: 28, y: 61, w: 44, h: 4, label: '日期' },
- ],
- },
- {
- value: 'banner-left-stack',
- label: '左侧堆叠',
- group: '对齐',
- desc: '文字左对齐堆叠在左侧',
- zones: [
- { x: 8, y: 68, w: 42, h: 5, label: 'WEDDING' },
- { x: 8, y: 76, w: 48, h: 6, label: '姓名' },
- { x: 8, y: 86, w: 36, h: 4, label: '日期' },
- { x: 8, y: 92, w: 40, h: 4, label: '场地' },
- ],
- },
- {
- value: 'banner-right-stack',
- label: '右侧堆叠',
- group: '对齐',
- desc: '文字右对齐堆叠在右侧',
- zones: [
- { x: 50, y: 68, w: 42, h: 5, label: 'WEDDING' },
- { x: 44, y: 76, w: 48, h: 6, label: '姓名' },
- { x: 56, y: 86, w: 36, h: 4, label: '日期' },
- { x: 52, y: 92, w: 40, h: 4, label: '场地' },
- ],
- },
{
value: 'banner-split-names',
label: '左右姓名',
- group: '对齐',
- desc: '新郎 / 新娘分列两侧,中间 &',
+ group: '普通文字',
+ desc: '新郎新娘分列',
zones: [
{ x: 22, y: 72, w: 22, h: 7, label: '新郎' },
{ x: 46, y: 74, w: 8, h: 5, label: '&' },
{ x: 56, y: 72, w: 22, h: 7, label: '新娘' },
{ x: 28, y: 86, w: 44, h: 4, label: '日期' },
- { x: 24, y: 92, w: 52, h: 4, label: 'Welcome' },
- ],
- },
- {
- value: 'banner-vertical-left',
- label: '左侧竖排',
- group: '竖排',
- desc: '左侧竖排中文欢迎与姓名',
- zones: [
- { x: 8, y: 28, w: 8, h: 36, label: '欢迎', vertical: true },
- { x: 20, y: 30, w: 10, h: 40, label: '姓名', vertical: true },
- { x: 34, y: 38, w: 8, h: 24, label: '日期', vertical: true },
- ],
- },
- {
- value: 'banner-vertical-right',
- label: '右侧竖排',
- group: '竖排',
- desc: '右侧竖排中文欢迎与姓名',
- zones: [
- { x: 84, y: 28, w: 8, h: 36, label: '欢迎', vertical: true },
- { x: 70, y: 30, w: 10, h: 40, label: '姓名', vertical: true },
- { x: 58, y: 38, w: 8, h: 24, label: '日期', vertical: true },
- ],
- },
- {
- value: 'banner-hero-name',
- label: '超大姓名',
- group: '强调',
- desc: '姓名超大居中偏下,副标题精简',
- zones: [
- { x: 12, y: 62, w: 76, h: 12, label: '新郎 & 新娘' },
- { x: 28, y: 78, w: 44, h: 4, label: 'WEDDING' },
- { x: 32, y: 86, w: 36, h: 4, label: '日期' },
- ],
- },
- {
- value: 'banner-date-focus',
- label: '日期主视觉',
- group: '强调',
- desc: '大号日期居中,姓名与标题辅之',
- zones: [
- { x: 24, y: 58, w: 52, h: 5, label: 'OUR WEDDING' },
- { x: 16, y: 68, w: 68, h: 10, label: '2026.10.01' },
- { x: 22, y: 82, w: 56, h: 6, label: '姓名' },
- { x: 28, y: 92, w: 44, h: 4, label: '场地' },
- ],
- },
- {
- value: 'banner-welcome-en',
- label: '英文欢迎',
- group: '强调',
- desc: '英文 Welcome 为主,姓名日期居下',
- zones: [
- { x: 10, y: 64, w: 80, h: 6, label: 'Welcome to' },
- { x: 14, y: 73, w: 72, h: 8, label: 'our Wedding' },
- { x: 22, y: 85, w: 56, h: 5, label: '姓名' },
- { x: 32, y: 93, w: 36, h: 3, label: '日期' },
- ],
- },
- {
- value: 'banner-minimal',
- label: '极简底部',
- group: '极简',
- desc: '仅底部两行:姓名 + 日期',
- zones: [
- { x: 24, y: 82, w: 52, h: 6, label: '姓名' },
- { x: 32, y: 92, w: 36, h: 4, label: '日期' },
- ],
- },
- {
- value: 'banner-xi-corner',
- label: '角标囍',
- group: '中式',
- desc: '角落囍字 + 底部婚礼信息',
- zones: [
- { x: 8, y: 6, w: 14, h: 8, label: '囍' },
- { x: 18, y: 72, w: 64, h: 6, label: 'WEDDING' },
- { x: 22, y: 82, w: 56, h: 6, label: '姓名' },
- { x: 28, y: 92, w: 44, h: 4, label: '日期' },
- ],
- },
- {
- value: 'banner-top-bottom',
- label: '上下呼应',
- group: '分区',
- desc: '顶部标题 + 底部姓名日期',
- zones: [
- { x: 18, y: 8, w: 64, h: 6, label: 'WEDDING' },
- { x: 24, y: 16, w: 52, h: 4, label: 'Welcome' },
- { x: 20, y: 80, w: 60, h: 7, label: '姓名' },
- { x: 30, y: 91, w: 40, h: 4, label: '日期' },
],
},
{
value: 'banner-frame-bottom',
label: '底栏卡片',
- group: '分区',
- desc: '底部像信息卡:标题 / 姓名 / 日期场地',
+ group: '普通文字',
+ desc: '底部信息卡式排版',
zones: [
- { x: 12, y: 68, w: 76, h: 5, label: 'OUR WEDDING DAY' },
+ { x: 12, y: 68, w: 76, h: 5, label: 'OUR WEDDING' },
{ x: 16, y: 76, w: 68, h: 7, label: '姓名' },
{ x: 20, y: 86, w: 60, h: 4, label: '日期' },
{ x: 24, y: 92, w: 52, h: 4, label: '场地' },
],
},
+ {
+ value: 'banner-minimal',
+ label: '极简底部',
+ group: '普通文字',
+ desc: '仅姓名 + 日期',
+ zones: [
+ { x: 24, y: 82, w: 52, h: 6, label: '姓名' },
+ { x: 32, y: 92, w: 36, h: 4, label: '日期' },
+ ],
+ },
+
+ // —— 艺术字(参考易拉宝常见排版)——
+ {
+ value: 'art-welcome-brush',
+ label: '笔刷欢迎',
+ group: '艺术字',
+ artistic: true,
+ desc: '顶部书法「欢迎来我们的婚礼」+ 底部西文姓名',
+ zones: [
+ { x: 12, y: 10, w: 76, h: 14, label: '欢迎来…', art: true },
+ { x: 22, y: 78, w: 56, h: 5, label: '姓名' },
+ { x: 20, y: 86, w: 60, h: 4, label: 'WELCOME' },
+ { x: 32, y: 93, w: 36, h: 3, label: '日期' },
+ ],
+ },
+ {
+ value: 'art-love-life',
+ label: '以爱之名',
+ group: '艺术字',
+ artistic: true,
+ desc: '书法主句 + 底部 Welcome / 姓名',
+ zones: [
+ { x: 14, y: 12, w: 72, h: 16, label: '以爱之名', art: true },
+ { x: 24, y: 78, w: 52, h: 5, label: '姓名' },
+ { x: 18, y: 87, w: 64, h: 4, label: 'WELCOME' },
+ { x: 30, y: 93, w: 40, h: 3, label: '日期' },
+ ],
+ },
+ {
+ value: 'art-gaobai',
+ label: '告白',
+ group: '艺术字',
+ artistic: true,
+ desc: '英文手写 Wedding Day + 大字「告白」',
+ zones: [
+ { x: 18, y: 38, w: 50, h: 6, label: 'Wedding Day', art: true },
+ { x: 22, y: 48, w: 36, h: 16, label: '告白', art: true },
+ { x: 24, y: 86, w: 52, h: 5, label: '姓名' },
+ { x: 30, y: 93, w: 40, h: 3, label: '日期' },
+ ],
+ },
+ {
+ value: 'art-married',
+ label: '我们结婚啦',
+ group: '艺术字',
+ artistic: true,
+ desc: 'WEDDING 底字 + 笔刷「我们结婚啦」叠字',
+ zones: [
+ { x: 10, y: 14, w: 80, h: 10, label: 'WEDDING' },
+ { x: 14, y: 18, w: 72, h: 14, label: '我们结婚啦', art: true },
+ { x: 18, y: 36, w: 64, h: 4, label: '【欢迎参加】' },
+ { x: 20, y: 44, w: 60, h: 5, label: '姓名' },
+ { x: 22, y: 88, w: 56, h: 4, label: '日期·酒店' },
+ ],
+ },
+ {
+ value: 'art-hand-love',
+ label: '携手热爱',
+ group: '艺术字',
+ artistic: true,
+ desc: '行草主句「携手热爱,奔赴山海」',
+ zones: [
+ { x: 10, y: 14, w: 80, h: 14, label: '携手热爱…', art: true },
+ { x: 20, y: 32, w: 60, h: 4, label: '【欢迎参加】' },
+ { x: 22, y: 40, w: 56, h: 5, label: '姓名' },
+ { x: 24, y: 88, w: 52, h: 4, label: '日期·酒店' },
+ ],
+ },
+ {
+ value: 'art-like-you',
+ label: '就是喜欢你',
+ group: '艺术字',
+ artistic: true,
+ desc: '金色笔刷主句 + 底部信息',
+ zones: [
+ { x: 12, y: 16, w: 76, h: 14, label: '就是喜欢你', art: true },
+ { x: 20, y: 34, w: 60, h: 4, label: '【欢迎参加】' },
+ { x: 22, y: 42, w: 56, h: 5, label: '姓名' },
+ { x: 24, y: 88, w: 52, h: 4, label: '日期·酒店' },
+ ],
+ },
+ {
+ value: 'art-give-home',
+ label: '给她一个家',
+ group: '艺术字',
+ artistic: true,
+ desc: '描边 WELCOME + 现代感中文主句',
+ zones: [
+ { x: 12, y: 12, w: 76, h: 6, label: 'WELCOME' },
+ { x: 16, y: 22, w: 68, h: 12, label: '给她一个家', art: true },
+ { x: 20, y: 38, w: 60, h: 4, label: '【欢迎参加】' },
+ { x: 22, y: 46, w: 56, h: 5, label: '姓名' },
+ { x: 24, y: 88, w: 52, h: 4, label: '日期·酒店' },
+ ],
+ },
+ {
+ value: 'art-xi-welcome',
+ label: '囍·中式',
+ group: '艺术字',
+ artistic: true,
+ desc: '大囍 + 书法欢迎语',
+ zones: [
+ { x: 38, y: 8, w: 24, h: 12, label: '囍', art: true },
+ { x: 14, y: 68, w: 72, h: 10, label: '欢迎光临', art: true },
+ { x: 22, y: 82, w: 56, h: 6, label: '姓名' },
+ { x: 26, y: 92, w: 48, h: 4, label: '日期' },
+ ],
+ },
+ {
+ value: 'art-wujia',
+ label: '吾家有喜',
+ group: '艺术字',
+ artistic: true,
+ desc: '竖排书法主句 + 欢迎与日期',
+ zones: [
+ { x: 18, y: 22, w: 14, h: 48, label: '吾家有喜', art: true, vertical: true },
+ { x: 40, y: 30, w: 10, h: 36, label: '欢迎', vertical: true },
+ { x: 58, y: 72, w: 32, h: 5, label: '姓名' },
+ { x: 58, y: 82, w: 32, h: 4, label: '日期' },
+ ],
+ },
+ {
+ value: 'art-tianci',
+ label: '天赐良缘',
+ group: '艺术字',
+ artistic: true,
+ desc: '竖排书法 + 新人信息',
+ zones: [
+ { x: 16, y: 20, w: 14, h: 50, label: '天赐良缘', art: true, vertical: true },
+ { x: 38, y: 28, w: 10, h: 40, label: '婚礼', vertical: true },
+ { x: 55, y: 70, w: 36, h: 5, label: '姓名' },
+ { x: 55, y: 80, w: 36, h: 4, label: '日期' },
+ { x: 55, y: 88, w: 36, h: 4, label: '酒店' },
+ ],
+ },
+ {
+ value: 'art-tianzuo',
+ label: '天作之合',
+ group: '艺术字',
+ artistic: true,
+ desc: '四字方阵艺术字 + 欢迎语',
+ zones: [
+ { x: 18, y: 18, w: 28, h: 12, label: '天', art: true },
+ { x: 50, y: 18, w: 28, h: 12, label: '作', art: true },
+ { x: 18, y: 34, w: 28, h: 12, label: '之', art: true },
+ { x: 50, y: 34, w: 28, h: 12, label: '合', art: true },
+ { x: 22, y: 72, w: 56, h: 5, label: '欢迎参加' },
+ { x: 24, y: 82, w: 52, h: 5, label: '姓名' },
+ { x: 28, y: 92, w: 44, h: 4, label: '日期' },
+ ],
+ },
+ {
+ value: 'art-welcome-v',
+ label: '竖排欢迎',
+ group: '艺术字',
+ artistic: true,
+ desc: '左侧竖排书法欢迎全文',
+ zones: [
+ { x: 10, y: 18, w: 12, h: 58, label: '欢迎参加…', art: true, vertical: true },
+ { x: 30, y: 22, w: 8, h: 28, label: 'Welcome', vertical: true },
+ { x: 48, y: 78, w: 42, h: 5, label: '姓名' },
+ { x: 48, y: 88, w: 42, h: 4, label: '日期' },
+ ],
+ },
+ {
+ value: 'art-longest',
+ label: '最长的告白',
+ group: '艺术字',
+ artistic: true,
+ desc: '笔刷主句 + 英文手写叠字',
+ zones: [
+ { x: 12, y: 12, w: 76, h: 12, label: '最长的告白', art: true },
+ { x: 16, y: 24, w: 68, h: 6, label: 'Accompanying', art: true },
+ { x: 22, y: 78, w: 56, h: 5, label: '姓名' },
+ { x: 26, y: 88, w: 48, h: 4, label: '日期' },
+ ],
+ },
+ {
+ value: 'art-just-love',
+ label: '就爱这样的你',
+ group: '艺术字',
+ artistic: true,
+ desc: '现代笔刷主句 + 括号欢迎语',
+ zones: [
+ { x: 12, y: 14, w: 76, h: 14, label: '就爱这样的你', art: true },
+ { x: 18, y: 32, w: 64, h: 4, label: '【欢迎参加】' },
+ { x: 20, y: 40, w: 60, h: 5, label: '姓名' },
+ { x: 22, y: 88, w: 56, h: 4, label: '日期·酒店' },
+ ],
+ },
{
value: 'custom',
label: '自定义空白',
group: '自定义',
- desc: '无预设文字,自行添加并拖拽',
+ desc: '无预设,自行添加普通字 / 艺术字并拖拽',
zones: [],
},
]
-/** 旧模板 key → 新 key(兼容已保存数据) */
const LEGACY_TEMPLATE_MAP = {
'welcome-bottom': 'banner-bottom',
'welcome-top': 'banner-top',
'welcome-center': 'banner-center',
- 'welcome-left': 'banner-vertical-left',
- 'welcome-right': 'banner-vertical-right',
+ 'welcome-left': 'art-welcome-v',
+ 'welcome-right': 'banner-split-names',
+ 'banner-zh': 'art-xi-welcome',
+ 'banner-upper-third': 'banner-top',
+ 'banner-mid-band': 'banner-center',
+ 'banner-left-stack': 'banner-lower-third',
+ 'banner-right-stack': 'banner-lower-third',
+ 'banner-vertical-left': 'art-welcome-v',
+ 'banner-vertical-right': 'art-wujia',
+ 'banner-hero-name': 'banner-names',
+ 'banner-date-focus': 'banner-frame-bottom',
+ 'banner-welcome-en': 'banner-bottom',
+ 'banner-xi-corner': 'art-xi-welcome',
+ 'banner-top-bottom': 'banner-top',
}
export function resolveTemplate(value) {
@@ -286,6 +372,7 @@ function uid() {
}
export function createTextLayer(partial = {}) {
+ const fontKey = FONT_MAP[partial.fontFamily] ? partial.fontFamily : 'serif'
return {
id: partial.id || uid(),
content: partial.content ?? 'WEDDING',
@@ -293,12 +380,14 @@ export function createTextLayer(partial = {}) {
y: clampPct(partial.y ?? 70),
fontSize: Number(partial.fontSize) > 0 ? Number(partial.fontSize) : 28,
color: partial.color || '#ffffff',
- fontFamily: partial.fontFamily || 'serif',
+ fontFamily: fontKey,
fontWeight: partial.fontWeight || '600',
align: partial.align || 'center',
letterSpacing: Number.isFinite(Number(partial.letterSpacing)) ? Number(partial.letterSpacing) : 2,
shadow: partial.shadow !== false,
vertical: !!partial.vertical,
+ stroke: !!partial.stroke,
+ strokeColor: partial.strokeColor || 'rgba(255,255,255,0.35)',
}
}
@@ -308,143 +397,179 @@ export function clampPct(n) {
return Math.min(100, Math.max(0, v))
}
-/** 各模板预设:婚礼迎宾易拉宝文案位(百分比坐标,可再拖拽) */
+function L(partial) {
+ return createTextLayer(partial)
+}
+
+/** 各模板预设文案(含艺术字体) */
export function defaultTextsForTemplate(template) {
switch (resolveTemplate(template)) {
case 'banner-top':
return [
- createTextLayer({ content: 'Welcome to our Wedding', x: 50, y: 10, fontSize: 18, letterSpacing: 3, fontWeight: '400' }),
- createTextLayer({ content: '新郎 & 新娘', x: 50, y: 18, fontSize: 34, fontWeight: '700', letterSpacing: 4 }),
- createTextLayer({ content: '2026.10.01', x: 50, y: 26, fontSize: 16, letterSpacing: 4, fontWeight: '400' }),
+ L({ content: 'Welcome to our Wedding', x: 50, y: 10, fontSize: 18, letterSpacing: 3, fontWeight: '400', fontFamily: 'display' }),
+ L({ content: '新郎 & 新娘', x: 50, y: 18, fontSize: 34, fontWeight: '700', letterSpacing: 4, fontFamily: 'serif' }),
+ L({ content: '2026.10.01', x: 50, y: 26, fontSize: 16, letterSpacing: 4, fontWeight: '400', fontFamily: 'sans' }),
]
case 'banner-center':
return [
- createTextLayer({ content: 'WEDDING', x: 50, y: 42, fontSize: 42, letterSpacing: 12, fontWeight: '700' }),
- createTextLayer({ content: '新郎 & 新娘', x: 50, y: 54, fontSize: 28, letterSpacing: 6 }),
- createTextLayer({ content: 'Welcome to our Wedding', x: 50, y: 62, fontSize: 14, letterSpacing: 2, fontWeight: '400' }),
+ L({ content: 'WEDDING', x: 50, y: 42, fontSize: 42, letterSpacing: 12, fontWeight: '700', fontFamily: 'cinzel' }),
+ L({ content: '新郎 & 新娘', x: 50, y: 54, fontSize: 28, letterSpacing: 6, fontFamily: 'serif' }),
+ L({ content: 'Welcome to our Wedding', x: 50, y: 62, fontSize: 14, letterSpacing: 2, fontWeight: '400', fontFamily: 'display' }),
]
case 'banner-names':
return [
- createTextLayer({ content: 'OUR WEDDING', x: 50, y: 58, fontSize: 14, letterSpacing: 8, fontWeight: '400' }),
- createTextLayer({ content: '新郎', x: 50, y: 68, fontSize: 36, fontWeight: '700', letterSpacing: 10 }),
- createTextLayer({ content: '&', x: 50, y: 76, fontSize: 22, fontWeight: '400' }),
- createTextLayer({ content: '新娘', x: 50, y: 84, fontSize: 36, fontWeight: '700', letterSpacing: 10 }),
- createTextLayer({ content: '2026.10.01 · 婚礼酒店', x: 50, y: 93, fontSize: 14, letterSpacing: 3, fontWeight: '400' }),
- ]
- case 'banner-zh':
- return [
- createTextLayer({ content: '囍', x: 50, y: 12, fontSize: 36, color: '#c45c5c', letterSpacing: 0, shadow: false }),
- createTextLayer({ content: '欢迎光临我们的婚礼', x: 50, y: 72, fontSize: 22, letterSpacing: 6 }),
- createTextLayer({ content: '新郎 & 新娘', x: 50, y: 82, fontSize: 32, fontWeight: '700', letterSpacing: 4 }),
- createTextLayer({ content: '谨定于 2026年10月1日', x: 50, y: 91, fontSize: 14, letterSpacing: 2, fontWeight: '400' }),
+ L({ content: 'OUR WEDDING', x: 50, y: 58, fontSize: 14, letterSpacing: 8, fontWeight: '400', fontFamily: 'cinzel' }),
+ L({ content: '新郎', x: 50, y: 68, fontSize: 36, fontWeight: '700', letterSpacing: 10, fontFamily: 'serif' }),
+ L({ content: '&', x: 50, y: 76, fontSize: 22, fontWeight: '400', fontFamily: 'script' }),
+ L({ content: '新娘', x: 50, y: 84, fontSize: 36, fontWeight: '700', letterSpacing: 10, fontFamily: 'serif' }),
+ L({ content: '2026.10.01 · 婚礼酒店', x: 50, y: 93, fontSize: 14, letterSpacing: 3, fontWeight: '400', fontFamily: 'sans' }),
]
case 'banner-lower-third':
return [
- createTextLayer({ content: 'Welcome to our Wedding', x: 50, y: 72, fontSize: 16, letterSpacing: 2, fontWeight: '400' }),
- createTextLayer({ content: '新郎 & 新娘', x: 50, y: 81, fontSize: 32, fontWeight: '700', letterSpacing: 5 }),
- createTextLayer({ content: '2026.10.01', x: 50, y: 91, fontSize: 15, letterSpacing: 4, fontWeight: '400' }),
- ]
- case 'banner-upper-third':
- return [
- createTextLayer({ content: 'WEDDING', x: 50, y: 10, fontSize: 38, letterSpacing: 12, fontWeight: '700' }),
- createTextLayer({ content: '新郎 & 新娘', x: 50, y: 22, fontSize: 26, letterSpacing: 5 }),
- createTextLayer({ content: '2026.10.01', x: 50, y: 32, fontSize: 15, letterSpacing: 4, fontWeight: '400' }),
- ]
- case 'banner-mid-band':
- return [
- createTextLayer({ content: 'WEDDING', x: 50, y: 46, fontSize: 28, letterSpacing: 14, fontWeight: '700' }),
- createTextLayer({ content: '新郎 & 新娘', x: 50, y: 55, fontSize: 26, letterSpacing: 6 }),
- createTextLayer({ content: '2026.10.01', x: 50, y: 63, fontSize: 14, letterSpacing: 4, fontWeight: '400' }),
- ]
- case 'banner-left-stack':
- return [
- createTextLayer({ content: 'WEDDING', x: 12, y: 70, fontSize: 18, letterSpacing: 6, align: 'left', fontWeight: '700' }),
- createTextLayer({ content: '新郎 & 新娘', x: 12, y: 78, fontSize: 26, letterSpacing: 3, align: 'left', fontWeight: '700' }),
- createTextLayer({ content: '2026.10.01', x: 12, y: 87, fontSize: 14, letterSpacing: 2, align: 'left', fontWeight: '400' }),
- createTextLayer({ content: '婚礼酒店', x: 12, y: 93, fontSize: 13, letterSpacing: 2, align: 'left', fontWeight: '400' }),
- ]
- case 'banner-right-stack':
- return [
- createTextLayer({ content: 'WEDDING', x: 88, y: 70, fontSize: 18, letterSpacing: 6, align: 'right', fontWeight: '700' }),
- createTextLayer({ content: '新郎 & 新娘', x: 88, y: 78, fontSize: 26, letterSpacing: 3, align: 'right', fontWeight: '700' }),
- createTextLayer({ content: '2026.10.01', x: 88, y: 87, fontSize: 14, letterSpacing: 2, align: 'right', fontWeight: '400' }),
- createTextLayer({ content: '婚礼酒店', x: 88, y: 93, fontSize: 13, letterSpacing: 2, align: 'right', fontWeight: '400' }),
+ L({ content: 'Welcome to our Wedding', x: 50, y: 72, fontSize: 16, letterSpacing: 2, fontWeight: '400', fontFamily: 'display' }),
+ L({ content: '新郎 & 新娘', x: 50, y: 81, fontSize: 32, fontWeight: '700', letterSpacing: 5, fontFamily: 'serif' }),
+ L({ content: '2026.10.01', x: 50, y: 91, fontSize: 15, letterSpacing: 4, fontWeight: '400', fontFamily: 'sans' }),
]
case 'banner-split-names':
return [
- createTextLayer({ content: '新郎', x: 28, y: 74, fontSize: 30, fontWeight: '700', letterSpacing: 8 }),
- createTextLayer({ content: '&', x: 50, y: 75, fontSize: 20, fontWeight: '400' }),
- createTextLayer({ content: '新娘', x: 72, y: 74, fontSize: 30, fontWeight: '700', letterSpacing: 8 }),
- createTextLayer({ content: '2026.10.01', x: 50, y: 87, fontSize: 14, letterSpacing: 4, fontWeight: '400' }),
- createTextLayer({ content: 'Welcome to our Wedding', x: 50, y: 93, fontSize: 12, letterSpacing: 2, fontWeight: '400' }),
- ]
- case 'banner-vertical-left':
- return [
- createTextLayer({ content: '欢迎光临', x: 10, y: 42, fontSize: 18, vertical: true, letterSpacing: 10 }),
- createTextLayer({ content: '新郎新娘', x: 22, y: 45, fontSize: 28, vertical: true, fontWeight: '700', letterSpacing: 8 }),
- createTextLayer({ content: '2026.10.01', x: 34, y: 48, fontSize: 14, vertical: true, letterSpacing: 4, fontWeight: '400' }),
- ]
- case 'banner-vertical-right':
- return [
- createTextLayer({ content: '欢迎光临', x: 90, y: 42, fontSize: 18, vertical: true, letterSpacing: 10 }),
- createTextLayer({ content: '新郎新娘', x: 78, y: 45, fontSize: 28, vertical: true, fontWeight: '700', letterSpacing: 8 }),
- createTextLayer({ content: '2026.10.01', x: 66, y: 48, fontSize: 14, vertical: true, letterSpacing: 4, fontWeight: '400' }),
- ]
- case 'banner-hero-name':
- return [
- createTextLayer({ content: '新郎 & 新娘', x: 50, y: 68, fontSize: 40, fontWeight: '700', letterSpacing: 6 }),
- createTextLayer({ content: 'WEDDING', x: 50, y: 80, fontSize: 16, letterSpacing: 10, fontWeight: '400' }),
- createTextLayer({ content: '2026.10.01', x: 50, y: 88, fontSize: 15, letterSpacing: 4, fontWeight: '400' }),
- ]
- case 'banner-date-focus':
- return [
- createTextLayer({ content: 'OUR WEDDING', x: 50, y: 60, fontSize: 14, letterSpacing: 8, fontWeight: '400' }),
- createTextLayer({ content: '2026.10.01', x: 50, y: 72, fontSize: 40, fontWeight: '700', letterSpacing: 6 }),
- createTextLayer({ content: '新郎 & 新娘', x: 50, y: 84, fontSize: 24, letterSpacing: 4 }),
- createTextLayer({ content: '婚礼酒店', x: 50, y: 93, fontSize: 13, letterSpacing: 3, fontWeight: '400' }),
- ]
- case 'banner-welcome-en':
- return [
- createTextLayer({ content: 'Welcome to', x: 50, y: 66, fontSize: 20, letterSpacing: 4, fontWeight: '400' }),
- createTextLayer({ content: 'our Wedding', x: 50, y: 76, fontSize: 34, letterSpacing: 3, fontWeight: '700' }),
- createTextLayer({ content: '新郎 & 新娘', x: 50, y: 87, fontSize: 22, letterSpacing: 4 }),
- createTextLayer({ content: '2026.10.01', x: 50, y: 94, fontSize: 13, letterSpacing: 3, fontWeight: '400' }),
- ]
- case 'banner-minimal':
- return [
- createTextLayer({ content: '新郎 & 新娘', x: 50, y: 84, fontSize: 26, letterSpacing: 5, fontWeight: '700' }),
- createTextLayer({ content: '2026.10.01', x: 50, y: 93, fontSize: 14, letterSpacing: 4, fontWeight: '400' }),
- ]
- case 'banner-xi-corner':
- return [
- createTextLayer({ content: '囍', x: 12, y: 10, fontSize: 32, color: '#c45c5c', letterSpacing: 0, shadow: false, align: 'left' }),
- createTextLayer({ content: 'WEDDING', x: 50, y: 74, fontSize: 28, letterSpacing: 12, fontWeight: '700' }),
- createTextLayer({ content: '新郎 & 新娘', x: 50, y: 84, fontSize: 26, letterSpacing: 5 }),
- createTextLayer({ content: '2026.10.01', x: 50, y: 93, fontSize: 14, letterSpacing: 4, fontWeight: '400' }),
- ]
- case 'banner-top-bottom':
- return [
- createTextLayer({ content: 'WEDDING', x: 50, y: 10, fontSize: 30, letterSpacing: 12, fontWeight: '700' }),
- createTextLayer({ content: 'Welcome to our Wedding', x: 50, y: 18, fontSize: 13, letterSpacing: 2, fontWeight: '400' }),
- createTextLayer({ content: '新郎 & 新娘', x: 50, y: 82, fontSize: 30, letterSpacing: 5, fontWeight: '700' }),
- createTextLayer({ content: '2026.10.01', x: 50, y: 92, fontSize: 14, letterSpacing: 4, fontWeight: '400' }),
+ L({ content: '新郎', x: 28, y: 74, fontSize: 30, fontWeight: '700', letterSpacing: 8, fontFamily: 'serif' }),
+ L({ content: '&', x: 50, y: 75, fontSize: 20, fontWeight: '400', fontFamily: 'script' }),
+ L({ content: '新娘', x: 72, y: 74, fontSize: 30, fontWeight: '700', letterSpacing: 8, fontFamily: 'serif' }),
+ L({ content: '2026.10.01', x: 50, y: 87, fontSize: 14, letterSpacing: 4, fontWeight: '400', fontFamily: 'sans' }),
+ L({ content: 'Welcome to our Wedding', x: 50, y: 93, fontSize: 12, letterSpacing: 2, fontWeight: '400', fontFamily: 'display' }),
]
case 'banner-frame-bottom':
return [
- createTextLayer({ content: 'OUR WEDDING DAY', x: 50, y: 70, fontSize: 13, letterSpacing: 6, fontWeight: '400' }),
- createTextLayer({ content: '新郎 & 新娘', x: 50, y: 79, fontSize: 30, letterSpacing: 5, fontWeight: '700' }),
- createTextLayer({ content: '2026.10.01', x: 50, y: 88, fontSize: 14, letterSpacing: 4, fontWeight: '400' }),
- createTextLayer({ content: '婚礼酒店', x: 50, y: 94, fontSize: 13, letterSpacing: 3, fontWeight: '400' }),
+ L({ content: 'OUR WEDDING DAY', x: 50, y: 70, fontSize: 13, letterSpacing: 6, fontWeight: '400', fontFamily: 'cinzel' }),
+ L({ content: '新郎 & 新娘', x: 50, y: 79, fontSize: 30, letterSpacing: 5, fontWeight: '700', fontFamily: 'serif' }),
+ L({ content: '2026.10.01', x: 50, y: 88, fontSize: 14, letterSpacing: 4, fontWeight: '400', fontFamily: 'sans' }),
+ L({ content: '婚礼酒店', x: 50, y: 94, fontSize: 13, letterSpacing: 3, fontWeight: '400', fontFamily: 'kai' }),
]
+ case 'banner-minimal':
+ return [
+ L({ content: '新郎 & 新娘', x: 50, y: 84, fontSize: 26, letterSpacing: 5, fontWeight: '700', fontFamily: 'serif' }),
+ L({ content: '2026.10.01', x: 50, y: 93, fontSize: 14, letterSpacing: 4, fontWeight: '400', fontFamily: 'sans' }),
+ ]
+
+ case 'art-welcome-brush':
+ return [
+ L({ content: '欢迎来我们的婚礼', x: 50, y: 16, fontSize: 48, letterSpacing: 4, fontWeight: '400', fontFamily: 'brush', shadow: true }),
+ L({ content: 'Mr. 新郎 & Miss. 新娘', x: 50, y: 80, fontSize: 18, letterSpacing: 2, fontFamily: 'display', fontWeight: '400' }),
+ L({ content: 'WELCOME TO OUR WEDDING', x: 50, y: 88, fontSize: 12, letterSpacing: 4, fontFamily: 'cinzel', fontWeight: '400' }),
+ L({ content: '2026.10.01', x: 50, y: 94, fontSize: 13, letterSpacing: 3, fontFamily: 'sans', fontWeight: '400' }),
+ ]
+ case 'art-love-life':
+ return [
+ L({ content: '以爱之名 度一生', x: 50, y: 18, fontSize: 46, letterSpacing: 6, fontWeight: '400', fontFamily: 'liujian', shadow: true }),
+ L({ content: '新郎 & 新娘', x: 50, y: 80, fontSize: 20, letterSpacing: 4, fontFamily: 'serif' }),
+ L({ content: 'WELCOME TO OUR WEDDING', x: 50, y: 88, fontSize: 11, letterSpacing: 4, fontFamily: 'cinzel', fontWeight: '400' }),
+ L({ content: '2026.10.01 · 婚礼酒店', x: 50, y: 94, fontSize: 12, letterSpacing: 2, fontFamily: 'sans', fontWeight: '400' }),
+ ]
+ case 'art-gaobai':
+ return [
+ L({ content: 'Wedding Day', x: 38, y: 42, fontSize: 28, letterSpacing: 2, fontWeight: '400', fontFamily: 'script', color: '#e8c87a' }),
+ L({ content: '告白', x: 40, y: 56, fontSize: 64, letterSpacing: 8, fontWeight: '400', fontFamily: 'brush', shadow: true }),
+ L({ content: '新郎 & 新娘', x: 50, y: 86, fontSize: 18, letterSpacing: 4, fontFamily: 'serif' }),
+ L({ content: '2026.10.01', x: 50, y: 93, fontSize: 13, letterSpacing: 3, fontFamily: 'sans', fontWeight: '400' }),
+ ]
+ case 'art-married':
+ return [
+ L({ content: 'WEDDING', x: 50, y: 18, fontSize: 52, letterSpacing: 10, fontWeight: '700', fontFamily: 'cinzel', color: 'rgba(255,255,255,0.35)', shadow: false, stroke: true }),
+ L({ content: '我们结婚啦', x: 50, y: 24, fontSize: 44, letterSpacing: 4, fontWeight: '400', fontFamily: 'brush', color: '#ff6b3d', shadow: true }),
+ L({ content: '【欢迎参加我们的婚礼】', x: 50, y: 38, fontSize: 14, letterSpacing: 2, fontFamily: 'kai', fontWeight: '400' }),
+ L({ content: '新郎:XXX & 新娘:XXX', x: 50, y: 46, fontSize: 16, letterSpacing: 2, fontFamily: 'serif', fontWeight: '400' }),
+ L({ content: '10月01日 12:00', x: 50, y: 88, fontSize: 14, letterSpacing: 2, fontFamily: 'sans', fontWeight: '400' }),
+ L({ content: '婚礼酒店', x: 50, y: 94, fontSize: 13, letterSpacing: 2, fontFamily: 'kai', fontWeight: '400' }),
+ ]
+ case 'art-hand-love':
+ return [
+ L({ content: '携手热爱,奔赴山海', x: 50, y: 18, fontSize: 40, letterSpacing: 4, fontWeight: '400', fontFamily: 'liujian', shadow: true }),
+ L({ content: '【欢迎参加我们的婚礼】', x: 50, y: 34, fontSize: 14, letterSpacing: 2, fontFamily: 'kai', fontWeight: '400' }),
+ L({ content: '新郎:XXX & 新娘:XXX', x: 50, y: 42, fontSize: 16, letterSpacing: 2, fontFamily: 'serif', fontWeight: '400' }),
+ L({ content: '10月01日 12:00', x: 50, y: 88, fontSize: 14, letterSpacing: 2, fontFamily: 'sans', fontWeight: '400' }),
+ L({ content: '婚礼酒店', x: 50, y: 94, fontSize: 13, letterSpacing: 2, fontFamily: 'kai', fontWeight: '400' }),
+ ]
+ case 'art-like-you':
+ return [
+ L({ content: '就是喜欢你', x: 50, y: 20, fontSize: 48, letterSpacing: 6, fontWeight: '400', fontFamily: 'longcang', color: '#f0d48a', shadow: true }),
+ L({ content: '【欢迎参加我们的婚礼】', x: 50, y: 36, fontSize: 14, letterSpacing: 2, fontFamily: 'kai', fontWeight: '400' }),
+ L({ content: '新郎:XXX & 新娘:XXX', x: 50, y: 44, fontSize: 16, letterSpacing: 2, fontFamily: 'serif', fontWeight: '400' }),
+ L({ content: '10月01日 12:00', x: 50, y: 88, fontSize: 14, letterSpacing: 2, fontFamily: 'sans', fontWeight: '400' }),
+ L({ content: '婚礼酒店', x: 50, y: 94, fontSize: 13, letterSpacing: 2, fontFamily: 'kai', fontWeight: '400' }),
+ ]
+ case 'art-give-home':
+ return [
+ L({ content: 'WELCOME TO OUR WEDDING', x: 50, y: 14, fontSize: 16, letterSpacing: 5, fontWeight: '700', fontFamily: 'cinzel', stroke: true, shadow: false }),
+ L({ content: '给她一个家', x: 50, y: 26, fontSize: 42, letterSpacing: 8, fontWeight: '400', fontFamily: 'mashan', shadow: true }),
+ L({ content: '【欢迎参加我们的婚礼】', x: 50, y: 40, fontSize: 14, letterSpacing: 2, fontFamily: 'kai', fontWeight: '400' }),
+ L({ content: '新郎:XXX & 新娘:XXX', x: 50, y: 48, fontSize: 16, letterSpacing: 2, fontFamily: 'serif', fontWeight: '400' }),
+ L({ content: '10月01日 12:00', x: 50, y: 88, fontSize: 14, letterSpacing: 2, fontFamily: 'sans', fontWeight: '400' }),
+ L({ content: '婚礼酒店', x: 50, y: 94, fontSize: 13, letterSpacing: 2, fontFamily: 'kai', fontWeight: '400' }),
+ ]
+ case 'art-xi-welcome':
+ return [
+ L({ content: '囍', x: 50, y: 12, fontSize: 56, color: '#e8c87a', letterSpacing: 0, shadow: false, fontFamily: 'mashan', fontWeight: '400' }),
+ L({ content: '欢迎光临我们的婚礼', x: 50, y: 72, fontSize: 30, letterSpacing: 4, fontFamily: 'brush', fontWeight: '400' }),
+ L({ content: '新郎 & 新娘', x: 50, y: 84, fontSize: 24, letterSpacing: 4, fontFamily: 'serif' }),
+ L({ content: '谨定于 2026年10月1日', x: 50, y: 93, fontSize: 13, letterSpacing: 2, fontFamily: 'kai', fontWeight: '400' }),
+ ]
+ case 'art-wujia':
+ return [
+ L({ content: '吾家有喜', x: 22, y: 42, fontSize: 42, letterSpacing: 14, fontFamily: 'longcang', color: '#e8c87a', vertical: true, fontWeight: '400' }),
+ L({ content: '欢迎参加', x: 38, y: 40, fontSize: 18, letterSpacing: 10, fontFamily: 'kai', vertical: true, fontWeight: '400' }),
+ L({ content: '新郎 & 新娘', x: 72, y: 74, fontSize: 18, letterSpacing: 2, fontFamily: 'serif', align: 'left' }),
+ L({ content: '2026.10.01', x: 72, y: 84, fontSize: 14, letterSpacing: 2, fontFamily: 'sans', fontWeight: '400', align: 'left' }),
+ ]
+ case 'art-tianci':
+ return [
+ L({ content: '天赐良缘', x: 20, y: 42, fontSize: 40, letterSpacing: 14, fontFamily: 'longcang', color: '#e8c87a', vertical: true, fontWeight: '400' }),
+ L({ content: '吾家有喜', x: 36, y: 40, fontSize: 18, letterSpacing: 10, fontFamily: 'kai', vertical: true, fontWeight: '400' }),
+ L({ content: '新郎 & 新娘', x: 72, y: 72, fontSize: 18, letterSpacing: 2, fontFamily: 'serif', align: 'left' }),
+ L({ content: '2026年10月1日', x: 72, y: 82, fontSize: 13, letterSpacing: 1, fontFamily: 'sans', fontWeight: '400', align: 'left' }),
+ L({ content: '婚礼酒店', x: 72, y: 90, fontSize: 13, letterSpacing: 2, fontFamily: 'kai', fontWeight: '400', align: 'left' }),
+ ]
+ case 'art-tianzuo':
+ return [
+ L({ content: '天', x: 32, y: 22, fontSize: 48, fontFamily: 'longcang', color: '#e8c87a', fontWeight: '400', letterSpacing: 0 }),
+ L({ content: '作', x: 68, y: 22, fontSize: 48, fontFamily: 'longcang', color: '#e8c87a', fontWeight: '400', letterSpacing: 0 }),
+ L({ content: '之', x: 32, y: 40, fontSize: 48, fontFamily: 'longcang', color: '#e8c87a', fontWeight: '400', letterSpacing: 0 }),
+ L({ content: '合', x: 68, y: 40, fontSize: 48, fontFamily: 'longcang', color: '#e8c87a', fontWeight: '400', letterSpacing: 0 }),
+ L({ content: '欢迎参加我们的婚礼', x: 50, y: 72, fontSize: 16, letterSpacing: 4, fontFamily: 'kai', fontWeight: '400' }),
+ L({ content: '新郎 & 新娘', x: 50, y: 82, fontSize: 20, letterSpacing: 4, fontFamily: 'serif' }),
+ L({ content: '2026.10.01', x: 50, y: 92, fontSize: 13, letterSpacing: 3, fontFamily: 'sans', fontWeight: '400' }),
+ ]
+ case 'art-welcome-v':
+ return [
+ L({ content: '欢迎参加我们的婚礼', x: 14, y: 45, fontSize: 28, letterSpacing: 12, fontFamily: 'brush', vertical: true, fontWeight: '400' }),
+ L({ content: 'Welcome', x: 28, y: 36, fontSize: 16, letterSpacing: 6, fontFamily: 'script', vertical: true, fontWeight: '400', color: '#e8c87a' }),
+ L({ content: '新郎 & 新娘', x: 70, y: 80, fontSize: 18, letterSpacing: 2, fontFamily: 'serif', align: 'left' }),
+ L({ content: '2026.10.01', x: 70, y: 90, fontSize: 13, letterSpacing: 2, fontFamily: 'sans', fontWeight: '400', align: 'left' }),
+ ]
+ case 'art-longest':
+ return [
+ L({ content: '最长的告白', x: 50, y: 16, fontSize: 44, letterSpacing: 6, fontFamily: 'brush', fontWeight: '400', shadow: true }),
+ L({ content: 'Accompanying You', x: 50, y: 28, fontSize: 22, letterSpacing: 2, fontFamily: 'script', color: '#e07a7a', fontWeight: '400' }),
+ L({ content: '新郎 & 新娘', x: 50, y: 80, fontSize: 20, letterSpacing: 4, fontFamily: 'serif' }),
+ L({ content: '2026.10.01 · 婚礼酒店', x: 50, y: 90, fontSize: 13, letterSpacing: 2, fontFamily: 'sans', fontWeight: '400' }),
+ ]
+ case 'art-just-love':
+ return [
+ L({ content: '就爱这样的你', x: 50, y: 18, fontSize: 42, letterSpacing: 4, fontFamily: 'liujian', color: '#7eb6e8', fontWeight: '400', shadow: true }),
+ L({ content: '【欢迎参加我们的婚礼】', x: 50, y: 34, fontSize: 14, letterSpacing: 2, fontFamily: 'kai', fontWeight: '400' }),
+ L({ content: '新郎:XXX & 新娘:XXX', x: 50, y: 42, fontSize: 16, letterSpacing: 2, fontFamily: 'serif', fontWeight: '400' }),
+ L({ content: '10月01日 12:00', x: 50, y: 88, fontSize: 14, letterSpacing: 2, fontFamily: 'sans', fontWeight: '400' }),
+ L({ content: '婚礼酒店', x: 50, y: 94, fontSize: 13, letterSpacing: 2, fontFamily: 'kai', fontWeight: '400' }),
+ ]
+
case 'custom':
return []
case 'banner-bottom':
default:
return [
- createTextLayer({ content: 'WEDDING', x: 50, y: 68, fontSize: 36, letterSpacing: 14, fontWeight: '700' }),
- createTextLayer({ content: '新郎 & 新娘', x: 50, y: 78, fontSize: 26, letterSpacing: 6 }),
- createTextLayer({ content: 'Welcome to our Wedding', x: 50, y: 86, fontSize: 13, letterSpacing: 2, fontWeight: '400' }),
- createTextLayer({ content: '2026.10.01', x: 50, y: 93, fontSize: 14, letterSpacing: 4, fontWeight: '400' }),
+ L({ content: 'WEDDING', x: 50, y: 68, fontSize: 36, letterSpacing: 14, fontWeight: '700', fontFamily: 'cinzel' }),
+ L({ content: '新郎 & 新娘', x: 50, y: 78, fontSize: 26, letterSpacing: 6, fontFamily: 'serif' }),
+ L({ content: 'Welcome to our Wedding', x: 50, y: 86, fontSize: 13, letterSpacing: 2, fontWeight: '400', fontFamily: 'display' }),
+ L({ content: '2026.10.01', x: 50, y: 93, fontSize: 14, letterSpacing: 4, fontWeight: '400', fontFamily: 'sans' }),
]
}
}
diff --git a/vite-tailwindcss/src/style.css b/vite-tailwindcss/src/style.css
index a98a242..bd8202a 100644
--- a/vite-tailwindcss/src/style.css
+++ b/vite-tailwindcss/src/style.css
@@ -1,14 +1,26 @@
@import "tailwindcss";
@import "@fontsource/great-vibes/400.css";
@import "@fontsource/ma-shan-zheng/400.css";
+@import "@fontsource/zhi-mang-xing/400.css";
+@import "@fontsource/long-cang/400.css";
+@import "@fontsource/liu-jian-mao-cao/400.css";
+@import "@fontsource/playfair-display/400.css";
+@import "@fontsource/playfair-display/700.css";
+@import "@fontsource/pinyon-script/400.css";
+@import "@fontsource/cinzel/400.css";
+@import "@fontsource/cinzel/700.css";
:root {
--font-sans: "Avenir Next", "Helvetica Neue", "PingFang SC", "Microsoft YaHei", sans-serif;
--font-serif: "Noto Serif SC", "Source Han Serif SC", "Songti SC", "STSong", "SimSun", serif;
- --font-display: "Didot", "Bodoni 72", "Cormorant Garamond", "Times New Roman", serif;
+ --font-display: "Playfair Display", "Didot", "Bodoni 72", "Cormorant Garamond", "Times New Roman", serif;
--font-kai: "Kaiti SC", "STKaiti", "KaiTi", "FangSong", serif;
- --font-brush: "HanziPen SC", "STXingkai", "华文行楷", "FZKai-Z03S", "Kaiti SC", "STKaiti", "KaiTi", "FangSong", serif;
- --font-calligraphy: "Great Vibes", "Ma Shan Zheng", cursive, serif;
+ --font-brush: "Zhi Mang Xing", "Liu Jian Mao Cao", "HanziPen SC", "STXingkai", "华文行楷", "Kaiti SC", serif;
+ --font-calligraphy: "Great Vibes", "Pinyon Script", "Ma Shan Zheng", cursive, serif;
+ --font-mashan: "Ma Shan Zheng", "Zhi Mang Xing", cursive, serif;
+ --font-longcang: "Long Cang", "Ma Shan Zheng", cursive, serif;
+ --font-liujian: "Liu Jian Mao Cao", "Zhi Mang Xing", cursive, serif;
+ --font-cinzel: "Cinzel", "Playfair Display", serif;
--font-number: "Cochin", "Georgia", "Times New Roman", serif;
}
diff --git a/vite-tailwindcss/src/views/admin/HotelWelcomePosterAdmin.vue b/vite-tailwindcss/src/views/admin/HotelWelcomePosterAdmin.vue
index 8d19627..9fe0bf7 100644
--- a/vite-tailwindcss/src/views/admin/HotelWelcomePosterAdmin.vue
+++ b/vite-tailwindcss/src/views/admin/HotelWelcomePosterAdmin.vue
@@ -170,9 +170,15 @@