Merge pull request 'Codex/ecommerce hot video responsive' (#7) from codex/ecommerce-hot-video-responsive into main
Reviewed-on: #7
This commit was merged in pull request #7.
This commit is contained in:
@@ -367,310 +367,310 @@ const platformSpecOptions: Array<{
|
||||
}> = [
|
||||
{
|
||||
label: "淘宝/天猫",
|
||||
ratios: ["淘宝主图 / SKU 鍥?800脳800px", "详情页宽 750px", "详情页宽 790px"],
|
||||
defaultRatio: "淘宝主图 / SKU 鍥?800脳800px",
|
||||
ratios: ["淘宝主图 / SKU 图 800×800px", "详情页宽 750px", "详情页宽 790px"],
|
||||
defaultRatio: "淘宝主图 / SKU 图 800×800px",
|
||||
ratioGroups: {
|
||||
set: {
|
||||
ratios: ["1000脳1000px\u00a0\u00a0\u00a01锛?", "800脳800px\u00a0\u00a0\u00a01锛?"],
|
||||
defaultRatio: "1000脳1000px\u00a0\u00a0\u00a01锛?",
|
||||
ratios: ["1000×1000px\u00a0\u00a0\u00a01:1", "800×800px\u00a0\u00a0\u00a01:1"],
|
||||
defaultRatio: "1000×1000px\u00a0\u00a0\u00a01:1",
|
||||
},
|
||||
detail: {
|
||||
ratios: [
|
||||
"750脳1000px\u00a0\u00a0\u00a03锛?",
|
||||
"790脳1053px\u00a0\u00a0\u00a03锛?",
|
||||
"750脳1125px\u00a0\u00a0\u00a02锛?",
|
||||
"790脳1185px\u00a0\u00a0\u00a02锛?",
|
||||
"750×1000px\u00a0\u00a0\u00a03:4",
|
||||
"790×1053px\u00a0\u00a0\u00a03:4",
|
||||
"750×1125px\u00a0\u00a0\u00a02:3",
|
||||
"790×1185px\u00a0\u00a0\u00a02:3",
|
||||
],
|
||||
defaultRatio: "750脳1000px\u00a0\u00a0\u00a03锛?",
|
||||
defaultRatio: "750×1000px\u00a0\u00a0\u00a03:4",
|
||||
},
|
||||
model: {
|
||||
ratios: ["750脳1000px\u00a0\u00a0\u00a03锛?"],
|
||||
defaultRatio: "750脳1000px\u00a0\u00a0\u00a03锛?",
|
||||
ratios: ["750×1000px\u00a0\u00a0\u00a03:4"],
|
||||
defaultRatio: "750×1000px\u00a0\u00a0\u00a03:4",
|
||||
},
|
||||
video: {
|
||||
ratios: ["1080脳1920px\u00a0\u00a0\u00a09锛?6", "1080脳1440px\u00a0\u00a0\u00a03锛?", "1080脳1080px\u00a0\u00a0\u00a01锛?"],
|
||||
defaultRatio: "1080脳1920px\u00a0\u00a0\u00a09锛?6",
|
||||
ratios: ["1080×1920px\u00a0\u00a0\u00a09:16", "1080×1440px\u00a0\u00a0\u00a03:4", "1080×1080px\u00a0\u00a0\u00a01:1"],
|
||||
defaultRatio: "1080×1920px\u00a0\u00a0\u00a09:16",
|
||||
},
|
||||
hot: {
|
||||
ratios: ["800脳800px\u00a0\u00a0\u00a01锛?"],
|
||||
defaultRatio: "800脳800px\u00a0\u00a0\u00a01锛?",
|
||||
ratios: ["800×800px\u00a0\u00a0\u00a01:1"],
|
||||
defaultRatio: "800×800px\u00a0\u00a0\u00a01:1",
|
||||
},
|
||||
},
|
||||
specs: ["主图 / SKU 鍥?800脳800px锛屸墹3MB", "详情页宽 750px 或?790px锛屽崟寮犻珮鈮?546px"],
|
||||
tip: "建议主图 200-400KB JPG锛岃秴杩?500KB 浼氬奖鍝嶅姞杞介€熷害銆?",
|
||||
specs: ["主图 / SKU 图 800×800px,≤3MB", "详情页宽 750px 或 790px,单张高度≤1546px"],
|
||||
tip: "建议主图 200-400KB JPG,超过 500KB 会影响加载速度。",
|
||||
},
|
||||
{
|
||||
label: "京东",
|
||||
ratios: ["京东主图 / SKU 鍥?800脳800px", "详情页宽 750px", "首图主体占比 鈮?0%"],
|
||||
defaultRatio: "京东主图 / SKU 鍥?800脳800px",
|
||||
ratios: ["京东主图 / SKU 图 800×800px", "详情页宽 750px", "首图主体占比 ≥80%"],
|
||||
defaultRatio: "京东主图 / SKU 图 800×800px",
|
||||
ratioGroups: {
|
||||
set: {
|
||||
ratios: ["1000脳1000px\u00a0\u00a0\u00a01锛?"],
|
||||
defaultRatio: "1000脳1000px\u00a0\u00a0\u00a01锛?",
|
||||
ratios: ["1000×1000px\u00a0\u00a0\u00a01:1"],
|
||||
defaultRatio: "1000×1000px\u00a0\u00a0\u00a01:1",
|
||||
},
|
||||
detail: {
|
||||
ratios: [
|
||||
"750脳1000px\u00a0\u00a0\u00a03锛?",
|
||||
"990脳1320px\u00a0\u00a0\u00a03锛?",
|
||||
"750脳1125px\u00a0\u00a0\u00a02锛?",
|
||||
"990脳1485px\u00a0\u00a0\u00a02锛?",
|
||||
"750×1000px\u00a0\u00a0\u00a03:4",
|
||||
"990×1320px\u00a0\u00a0\u00a03:4",
|
||||
"750×1125px\u00a0\u00a0\u00a02:3",
|
||||
"990×1485px\u00a0\u00a0\u00a02:3",
|
||||
],
|
||||
defaultRatio: "750脳1000px\u00a0\u00a0\u00a03锛?",
|
||||
defaultRatio: "750×1000px\u00a0\u00a0\u00a03:4",
|
||||
},
|
||||
model: {
|
||||
ratios: ["750脳1125px\u00a0\u00a0\u00a02锛?", "990脳1485px\u00a0\u00a0\u00a02锛?"],
|
||||
defaultRatio: "750脳1125px\u00a0\u00a0\u00a02锛?",
|
||||
ratios: ["750×1125px\u00a0\u00a0\u00a02:3", "990×1485px\u00a0\u00a0\u00a02:3"],
|
||||
defaultRatio: "750×1125px\u00a0\u00a0\u00a02:3",
|
||||
},
|
||||
video: {
|
||||
ratios: ["1080脳1920px\u00a0\u00a0\u00a09锛?6", "1920脳1080px\u00a0\u00a0\u00a016锛?"],
|
||||
defaultRatio: "1080脳1920px\u00a0\u00a0\u00a09锛?6",
|
||||
ratios: ["1080×1920px\u00a0\u00a0\u00a09:16", "1920×1080px\u00a0\u00a0\u00a016:9"],
|
||||
defaultRatio: "1080×1920px\u00a0\u00a0\u00a09:16",
|
||||
},
|
||||
hot: {
|
||||
ratios: ["800脳800px\u00a0\u00a0\u00a01锛?"],
|
||||
defaultRatio: "800脳800px\u00a0\u00a0\u00a01锛?",
|
||||
ratios: ["800×800px\u00a0\u00a0\u00a01:1"],
|
||||
defaultRatio: "800×800px\u00a0\u00a0\u00a01:1",
|
||||
},
|
||||
},
|
||||
specs: ["主图 / SKU 鍥?800脳800px锛岀櫧搴曪紝鈮?MB", "详情页宽 750px锛岄鍥句富浣撳崰姣?鈮?0%"],
|
||||
specs: ["主图 / SKU 图 800×800px,白底,≤3MB", "详情页宽 750px,首图主体占比 ≥80%"],
|
||||
},
|
||||
{
|
||||
label: "拼多多",
|
||||
ratios: ["主图 750脳352px", "主图 800脳800px", "详情页宽 750px"],
|
||||
defaultRatio: "主图 750脳352px",
|
||||
ratios: ["主图 750×352px", "主图 800×800px", "详情页宽 750px"],
|
||||
defaultRatio: "主图 750×352px",
|
||||
ratioGroups: {
|
||||
set: {
|
||||
ratios: ["800脳800px\u00a0\u00a0\u00a01锛?", "750脳1000px\u00a0\u00a0\u00a03锛?"],
|
||||
defaultRatio: "800脳800px\u00a0\u00a0\u00a01锛?",
|
||||
ratios: ["800×800px\u00a0\u00a0\u00a01:1", "750×1000px\u00a0\u00a0\u00a03:4"],
|
||||
defaultRatio: "800×800px\u00a0\u00a0\u00a01:1",
|
||||
},
|
||||
detail: {
|
||||
ratios: ["750脳1000px\u00a0\u00a0\u00a03锛?", "750脳1125px\u00a0\u00a0\u00a02锛?"],
|
||||
defaultRatio: "750脳1000px\u00a0\u00a0\u00a03锛?",
|
||||
ratios: ["750×1000px\u00a0\u00a0\u00a03:4", "750×1125px\u00a0\u00a0\u00a02:3"],
|
||||
defaultRatio: "750×1000px\u00a0\u00a0\u00a03:4",
|
||||
},
|
||||
model: {
|
||||
ratios: ["750脳1000px\u00a0\u00a0\u00a03锛?"],
|
||||
defaultRatio: "750脳1000px\u00a0\u00a0\u00a03锛?",
|
||||
ratios: ["750×1000px\u00a0\u00a0\u00a03:4"],
|
||||
defaultRatio: "750×1000px\u00a0\u00a0\u00a03:4",
|
||||
},
|
||||
video: {
|
||||
ratios: ["1080脳1920px\u00a0\u00a0\u00a09锛?6"],
|
||||
defaultRatio: "1080脳1920px\u00a0\u00a0\u00a09锛?6",
|
||||
ratios: ["1080×1920px\u00a0\u00a0\u00a09:16"],
|
||||
defaultRatio: "1080×1920px\u00a0\u00a0\u00a09:16",
|
||||
},
|
||||
hot: {
|
||||
ratios: ["800脳800px\u00a0\u00a0\u00a01锛?"],
|
||||
defaultRatio: "800脳800px\u00a0\u00a0\u00a01锛?",
|
||||
ratios: ["800×800px\u00a0\u00a0\u00a01:1"],
|
||||
defaultRatio: "800×800px\u00a0\u00a0\u00a01:1",
|
||||
},
|
||||
},
|
||||
specs: ["主图 750脳352px 或?800脳800px锛屸墹1MB", "详情页宽 750px,要求纯白底、无水印、无拼接"],
|
||||
specs: ["主图 750×352px 或 800×800px,≤1MB", "详情页宽 750px,要求纯白底、无水印、无拼接"],
|
||||
},
|
||||
{
|
||||
label: "抖音电商",
|
||||
ratios: ["鐭棰?1080脳1920px"],
|
||||
defaultRatio: "鐭棰?1080脳1920px",
|
||||
ratios: ["短视频1080×1920px"],
|
||||
defaultRatio: "短视频1080×1920px",
|
||||
ratioGroups: {
|
||||
video: {
|
||||
ratios: ["1080脳1920px\u00a0\u00a0\u00a09锛?6"],
|
||||
defaultRatio: "1080脳1920px\u00a0\u00a0\u00a09锛?6",
|
||||
ratios: ["1080×1920px\u00a0\u00a0\u00a09:16"],
|
||||
defaultRatio: "1080×1920px\u00a0\u00a0\u00a09:16",
|
||||
},
|
||||
hot: {
|
||||
ratios: ["800脳800px\u00a0\u00a0\u00a01锛?"],
|
||||
defaultRatio: "800脳800px\u00a0\u00a0\u00a01锛?",
|
||||
ratios: ["800×800px\u00a0\u00a0\u00a01:1"],
|
||||
defaultRatio: "800×800px\u00a0\u00a0\u00a01:1",
|
||||
},
|
||||
},
|
||||
specs: ["鐭棰?1080脳1920px锛?:16", "30s 图呮渶浣?"],
|
||||
specs: ["短视频 1080×1920px,9:16", "30s 内最佳"],
|
||||
},
|
||||
{
|
||||
label: "亚马逊 Amazon",
|
||||
ratios: ["主图 鈮?600脳1600px", "建议 2000脳2000px+", "鏈€灏?500脳500px"],
|
||||
defaultRatio: "主图 鈮?600脳1600px",
|
||||
ratios: ["主图 ≥1600×1600px", "建议 2000×2000px+", "最小 500×500px"],
|
||||
defaultRatio: "主图 ≥1600×1600px",
|
||||
ratioGroups: {
|
||||
set: {
|
||||
ratios: ["1600脳1600px\u00a0\u00a0\u00a01锛?"],
|
||||
defaultRatio: "1600脳1600px\u00a0\u00a0\u00a01锛?",
|
||||
ratios: ["1600×1600px\u00a0\u00a0\u00a01:1"],
|
||||
defaultRatio: "1600×1600px\u00a0\u00a0\u00a01:1",
|
||||
},
|
||||
detail: {
|
||||
ratios: ["1600脳1600px\u00a0\u00a0\u00a01锛?", "1200脳1800px\u00a0\u00a0\u00a02锛?", "1200脳1600px\u00a0\u00a0\u00a03锛?"],
|
||||
defaultRatio: "1200脳1800px\u00a0\u00a0\u00a02锛?",
|
||||
ratios: ["1600×1600px\u00a0\u00a0\u00a01:1", "1200×1800px\u00a0\u00a0\u00a02:3", "1200×1600px\u00a0\u00a0\u00a03:4"],
|
||||
defaultRatio: "1200×1800px\u00a0\u00a0\u00a02:3",
|
||||
},
|
||||
model: {
|
||||
ratios: ["1200脳1800px\u00a0\u00a0\u00a02锛?"],
|
||||
defaultRatio: "1200脳1800px\u00a0\u00a0\u00a02锛?",
|
||||
ratios: ["1200×1800px\u00a0\u00a0\u00a02:3"],
|
||||
defaultRatio: "1200×1800px\u00a0\u00a0\u00a02:3",
|
||||
},
|
||||
video: {
|
||||
ratios: ["1920脳1080px\u00a0\u00a0\u00a016锛?"],
|
||||
defaultRatio: "1920脳1080px\u00a0\u00a0\u00a016锛?",
|
||||
ratios: ["1920×1080px\u00a0\u00a0\u00a016:9"],
|
||||
defaultRatio: "1920×1080px\u00a0\u00a0\u00a016:9",
|
||||
},
|
||||
hot: {
|
||||
ratios: ["1600脳1600px\u00a0\u00a0\u00a01锛?"],
|
||||
defaultRatio: "1600脳1600px\u00a0\u00a0\u00a01锛?",
|
||||
ratios: ["1600×1600px\u00a0\u00a0\u00a01:1"],
|
||||
defaultRatio: "1600×1600px\u00a0\u00a0\u00a01:1",
|
||||
},
|
||||
},
|
||||
specs: ["主图 1600脳1600px+,纯白底,≤10MB", "鏈€灏?500脳500px锛屽缓璁?2000px+ 浠ユ敮鎸佺缉鏀?"],
|
||||
aliases: ["浜氶┈閫?"],
|
||||
specs: ["主图 1600×1600px+,纯白底,≤10MB", "最小 500×500px,建议 2000px+ 以支持缩放"],
|
||||
aliases: ["亚马逊"],
|
||||
},
|
||||
{
|
||||
label: "Shopee",
|
||||
ratios: ["商品主图 1024脳1024px", "基础主图 800脳800px"],
|
||||
defaultRatio: "商品主图 1024脳1024px",
|
||||
ratios: ["商品主图 1024×1024px", "基础主图 800×800px"],
|
||||
defaultRatio: "商品主图 1024×1024px",
|
||||
ratioGroups: {
|
||||
set: {
|
||||
ratios: ["800脳800px\u00a0\u00a0\u00a01锛?"],
|
||||
defaultRatio: "800脳800px\u00a0\u00a0\u00a01锛?",
|
||||
ratios: ["800×800px\u00a0\u00a0\u00a01:1"],
|
||||
defaultRatio: "800×800px\u00a0\u00a0\u00a01:1",
|
||||
},
|
||||
detail: {
|
||||
ratios: ["750脳1000px\u00a0\u00a0\u00a03锛?", "750脳1125px\u00a0\u00a0\u00a02锛?"],
|
||||
defaultRatio: "750脳1000px\u00a0\u00a0\u00a03锛?",
|
||||
ratios: ["750×1000px\u00a0\u00a0\u00a03:4", "750×1125px\u00a0\u00a0\u00a02:3"],
|
||||
defaultRatio: "750×1000px\u00a0\u00a0\u00a03:4",
|
||||
},
|
||||
model: {
|
||||
ratios: ["750脳1000px\u00a0\u00a0\u00a03锛?"],
|
||||
defaultRatio: "750脳1000px\u00a0\u00a0\u00a03锛?",
|
||||
ratios: ["750×1000px\u00a0\u00a0\u00a03:4"],
|
||||
defaultRatio: "750×1000px\u00a0\u00a0\u00a03:4",
|
||||
},
|
||||
video: {
|
||||
ratios: ["1080脳1920px\u00a0\u00a0\u00a09锛?6"],
|
||||
defaultRatio: "1080脳1920px\u00a0\u00a0\u00a09锛?6",
|
||||
ratios: ["1080×1920px\u00a0\u00a0\u00a09:16"],
|
||||
defaultRatio: "1080×1920px\u00a0\u00a0\u00a09:16",
|
||||
},
|
||||
hot: {
|
||||
ratios: ["800脳800px\u00a0\u00a0\u00a01锛?"],
|
||||
defaultRatio: "800脳800px\u00a0\u00a0\u00a01锛?",
|
||||
ratios: ["800×800px\u00a0\u00a0\u00a01:1"],
|
||||
defaultRatio: "800×800px\u00a0\u00a0\u00a01:1",
|
||||
},
|
||||
},
|
||||
specs: ["商品主图推荐 1024脳1024px,基础 800脳800px", "鈮?MB锛岀櫧搴曟垨娴呰壊搴?"],
|
||||
specs: ["商品主图推荐 1024×1024px,基础 800×800px", "≤2MB,白底或浅色底"],
|
||||
aliases: ["虾皮 Shopee/Lazada", "虾皮"],
|
||||
},
|
||||
{
|
||||
label: "Lazada",
|
||||
ratios: ["商品主图 800脳800px"],
|
||||
defaultRatio: "商品主图 800脳800px",
|
||||
ratios: ["商品主图 800×800px"],
|
||||
defaultRatio: "商品主图 800×800px",
|
||||
ratioGroups: {
|
||||
set: {
|
||||
ratios: ["800脳800px\u00a0\u00a0\u00a01锛?"],
|
||||
defaultRatio: "800脳800px\u00a0\u00a0\u00a01锛?",
|
||||
ratios: ["800×800px\u00a0\u00a0\u00a01:1"],
|
||||
defaultRatio: "800×800px\u00a0\u00a0\u00a01:1",
|
||||
},
|
||||
detail: {
|
||||
ratios: ["750脳1000px\u00a0\u00a0\u00a03锛?", "750脳1125px\u00a0\u00a0\u00a02锛?"],
|
||||
defaultRatio: "750脳1000px\u00a0\u00a0\u00a03锛?",
|
||||
ratios: ["750×1000px\u00a0\u00a0\u00a03:4", "750×1125px\u00a0\u00a0\u00a02:3"],
|
||||
defaultRatio: "750×1000px\u00a0\u00a0\u00a03:4",
|
||||
},
|
||||
model: {
|
||||
ratios: ["750脳1000px\u00a0\u00a0\u00a03锛?"],
|
||||
defaultRatio: "750脳1000px\u00a0\u00a0\u00a03锛?",
|
||||
ratios: ["750×1000px\u00a0\u00a0\u00a03:4"],
|
||||
defaultRatio: "750×1000px\u00a0\u00a0\u00a03:4",
|
||||
},
|
||||
video: {
|
||||
ratios: ["1080脳1920px\u00a0\u00a0\u00a09锛?6"],
|
||||
defaultRatio: "1080脳1920px\u00a0\u00a0\u00a09锛?6",
|
||||
ratios: ["1080×1920px\u00a0\u00a0\u00a09:16"],
|
||||
defaultRatio: "1080×1920px\u00a0\u00a0\u00a09:16",
|
||||
},
|
||||
hot: {
|
||||
ratios: ["800脳800px\u00a0\u00a0\u00a01锛?"],
|
||||
defaultRatio: "800脳800px\u00a0\u00a0\u00a01锛?",
|
||||
ratios: ["800×800px\u00a0\u00a0\u00a01:1"],
|
||||
defaultRatio: "800×800px\u00a0\u00a0\u00a01:1",
|
||||
},
|
||||
},
|
||||
specs: ["商品主图 800脳800px锛?:1"],
|
||||
specs: ["商品主图 800×800px,1:1"],
|
||||
},
|
||||
{
|
||||
label: "Instagram",
|
||||
ratios: ["帖子 1080脳1350px", "帖子 1080脳1080px", "Stories / Reels 1080脳1920px", "头像 320脳320px"],
|
||||
defaultRatio: "帖子 1080脳1350px",
|
||||
ratios: ["帖子 1080×1350px", "帖子 1080×1080px", "Stories / Reels 1080×1920px", "头像 320×320px"],
|
||||
defaultRatio: "帖子 1080×1350px",
|
||||
ratioGroups: {
|
||||
set: {
|
||||
ratios: ["1080脳1080px\u00a0\u00a0\u00a01锛?", "1080脳1350px\u00a0\u00a0\u00a04锛?"],
|
||||
defaultRatio: "1080脳1080px\u00a0\u00a0\u00a01锛?",
|
||||
ratios: ["1080×1080px\u00a0\u00a0\u00a01:1", "1080×1350px\u00a0\u00a0\u00a04:5"],
|
||||
defaultRatio: "1080×1080px\u00a0\u00a0\u00a01:1",
|
||||
},
|
||||
detail: {
|
||||
ratios: ["1080脳1350px\u00a0\u00a0\u00a04锛?"],
|
||||
defaultRatio: "1080脳1350px\u00a0\u00a0\u00a04锛?",
|
||||
ratios: ["1080×1350px\u00a0\u00a0\u00a04:5"],
|
||||
defaultRatio: "1080×1350px\u00a0\u00a0\u00a04:5",
|
||||
},
|
||||
model: {
|
||||
ratios: ["1080脳1350px\u00a0\u00a0\u00a04锛?"],
|
||||
defaultRatio: "1080脳1350px\u00a0\u00a0\u00a04锛?",
|
||||
ratios: ["1080×1350px\u00a0\u00a0\u00a04:5"],
|
||||
defaultRatio: "1080×1350px\u00a0\u00a0\u00a04:5",
|
||||
},
|
||||
video: {
|
||||
ratios: ["1080脳1920px\u00a0\u00a0\u00a09锛?6", "1080脳1350px\u00a0\u00a0\u00a04锛?"],
|
||||
defaultRatio: "1080脳1920px\u00a0\u00a0\u00a09锛?6",
|
||||
ratios: ["1080×1920px\u00a0\u00a0\u00a09:16", "1080×1350px\u00a0\u00a0\u00a04:5"],
|
||||
defaultRatio: "1080×1920px\u00a0\u00a0\u00a09:16",
|
||||
},
|
||||
},
|
||||
specs: ["帖子 1080脳1350px 或?1080脳1080px", "Stories / Reels 封面 1080脳1920px锛屽ご鍍?320脳320px"],
|
||||
tip: "建议 鈮?MB JPG銆?",
|
||||
specs: ["帖子 1080×1350px 或 1080×1080px", "Stories / Reels 封面 1080×1920px,头像 320×320px"],
|
||||
tip: "建议 ≤8MB JPG。",
|
||||
aliases: ["Instagram Reels"],
|
||||
},
|
||||
{
|
||||
label: "速卖通",
|
||||
ratios: ["主图 800脳800px", "主图 1000脳1000px+"],
|
||||
defaultRatio: "主图 800脳800px",
|
||||
ratios: ["主图 800×800px", "主图 1000×1000px+"],
|
||||
defaultRatio: "主图 800×800px",
|
||||
ratioGroups: {
|
||||
set: {
|
||||
ratios: ["1000脳1000px\u00a0\u00a0\u00a01锛?"],
|
||||
defaultRatio: "1000脳1000px\u00a0\u00a0\u00a01锛?",
|
||||
ratios: ["1000×1000px\u00a0\u00a0\u00a01:1"],
|
||||
defaultRatio: "1000×1000px\u00a0\u00a0\u00a01:1",
|
||||
},
|
||||
detail: {
|
||||
ratios: ["750脳1125px\u00a0\u00a0\u00a02锛?", "750脳1000px\u00a0\u00a0\u00a03锛?"],
|
||||
defaultRatio: "750脳1125px\u00a0\u00a0\u00a02锛?",
|
||||
ratios: ["750×1125px\u00a0\u00a0\u00a02:3", "750×1000px\u00a0\u00a0\u00a03:4"],
|
||||
defaultRatio: "750×1125px\u00a0\u00a0\u00a02:3",
|
||||
},
|
||||
model: {
|
||||
ratios: ["750脳1125px\u00a0\u00a0\u00a02锛?"],
|
||||
defaultRatio: "750脳1125px\u00a0\u00a0\u00a02锛?",
|
||||
ratios: ["750×1125px\u00a0\u00a0\u00a02:3"],
|
||||
defaultRatio: "750×1125px\u00a0\u00a0\u00a02:3",
|
||||
},
|
||||
video: {
|
||||
ratios: ["1080脳1920px\u00a0\u00a0\u00a09锛?6", "1920脳1080px\u00a0\u00a0\u00a016锛?"],
|
||||
defaultRatio: "1080脳1920px\u00a0\u00a0\u00a09锛?6",
|
||||
ratios: ["1080×1920px\u00a0\u00a0\u00a09:16", "1920×1080px\u00a0\u00a0\u00a016:9"],
|
||||
defaultRatio: "1080×1920px\u00a0\u00a0\u00a09:16",
|
||||
},
|
||||
hot: {
|
||||
ratios: ["800脳800px\u00a0\u00a0\u00a01锛?"],
|
||||
defaultRatio: "800脳800px\u00a0\u00a0\u00a01锛?",
|
||||
ratios: ["800×800px\u00a0\u00a0\u00a01:1"],
|
||||
defaultRatio: "800×800px\u00a0\u00a0\u00a01:1",
|
||||
},
|
||||
},
|
||||
specs: ["主图建议 800脳800px 或更高,1:1", "适合跨境电商主图、SKU 鍥惧拰鍦烘櫙鍥?"],
|
||||
specs: ["主图建议 800×800px 或更高,1:1", "适合跨境电商主图、SKU 图和场景图"],
|
||||
},
|
||||
{
|
||||
label: "eBay",
|
||||
ratios: ["鍟嗗搧鍥?1:1", "白底多角度展示图 1:1"],
|
||||
defaultRatio: "鍟嗗搧鍥?1:1",
|
||||
ratios: ["商品图1:1", "白底多角度展示图 1:1"],
|
||||
defaultRatio: "商品图1:1",
|
||||
ratioGroups: {
|
||||
set: {
|
||||
ratios: ["1600脳1600px\u00a0\u00a0\u00a01锛?"],
|
||||
defaultRatio: "1600脳1600px\u00a0\u00a0\u00a01锛?",
|
||||
ratios: ["1600×1600px\u00a0\u00a0\u00a01:1"],
|
||||
defaultRatio: "1600×1600px\u00a0\u00a0\u00a01:1",
|
||||
},
|
||||
detail: {
|
||||
ratios: ["1000脳1500px\u00a0\u00a0\u00a02锛?", "1200脳1600px\u00a0\u00a0\u00a03锛?"],
|
||||
defaultRatio: "1000脳1500px\u00a0\u00a0\u00a02锛?",
|
||||
ratios: ["1000×1500px\u00a0\u00a0\u00a02:3", "1200×1600px\u00a0\u00a0\u00a03:4"],
|
||||
defaultRatio: "1000×1500px\u00a0\u00a0\u00a02:3",
|
||||
},
|
||||
model: {
|
||||
ratios: ["1000脳1500px\u00a0\u00a0\u00a02锛?"],
|
||||
defaultRatio: "1000脳1500px\u00a0\u00a0\u00a02锛?",
|
||||
ratios: ["1000×1500px\u00a0\u00a0\u00a02:3"],
|
||||
defaultRatio: "1000×1500px\u00a0\u00a0\u00a02:3",
|
||||
},
|
||||
video: {
|
||||
ratios: ["1920脳1080px\u00a0\u00a0\u00a016锛?", "1080脳1920px\u00a0\u00a0\u00a09锛?6"],
|
||||
defaultRatio: "1920脳1080px\u00a0\u00a0\u00a016锛?",
|
||||
ratios: ["1920×1080px\u00a0\u00a0\u00a016:9", "1080×1920px\u00a0\u00a0\u00a09:16"],
|
||||
defaultRatio: "1920×1080px\u00a0\u00a0\u00a016:9",
|
||||
},
|
||||
hot: {
|
||||
ratios: ["1600脳1600px\u00a0\u00a0\u00a01锛?"],
|
||||
defaultRatio: "1600脳1600px\u00a0\u00a0\u00a01锛?",
|
||||
ratios: ["1600×1600px\u00a0\u00a0\u00a01:1"],
|
||||
defaultRatio: "1600×1600px\u00a0\u00a0\u00a01:1",
|
||||
},
|
||||
},
|
||||
specs: ["鍟嗗搧鍥惧缓璁?1:1锛屼富浣撴竻鏅板眳涓?", "閫傚悎白底主图鍜屽瑙掑害灞曠ず鍥?"],
|
||||
specs: ["商品图建议 1:1,主体清晰居中", "适合白底主图和多角度展示图"],
|
||||
},
|
||||
{
|
||||
label: "TikTok Shop",
|
||||
ratios: ["商品主图 1:1", "鐭棰?/ 竖版封面 9:16"],
|
||||
ratios: ["商品主图 1:1", "短视频/ 竖版封面 9:16"],
|
||||
defaultRatio: "商品主图 1:1",
|
||||
ratioGroups: {
|
||||
set: {
|
||||
ratios: ["1280脳1280px\u00a0\u00a0\u00a01锛?"],
|
||||
defaultRatio: "1280脳1280px\u00a0\u00a0\u00a01锛?",
|
||||
ratios: ["1280×1280px\u00a0\u00a0\u00a01:1"],
|
||||
defaultRatio: "1280×1280px\u00a0\u00a0\u00a01:1",
|
||||
},
|
||||
detail: {
|
||||
ratios: ["1080脳1350px\u00a0\u00a0\u00a04锛?"],
|
||||
defaultRatio: "1080脳1350px\u00a0\u00a0\u00a04锛?",
|
||||
ratios: ["1080×1350px\u00a0\u00a0\u00a04:5"],
|
||||
defaultRatio: "1080×1350px\u00a0\u00a0\u00a04:5",
|
||||
},
|
||||
model: {
|
||||
ratios: ["1080脳1350px\u00a0\u00a0\u00a04锛?"],
|
||||
defaultRatio: "1080脳1350px\u00a0\u00a0\u00a04锛?",
|
||||
ratios: ["1080×1350px\u00a0\u00a0\u00a04:5"],
|
||||
defaultRatio: "1080×1350px\u00a0\u00a0\u00a04:5",
|
||||
},
|
||||
video: {
|
||||
ratios: ["1080脳1920px\u00a0\u00a0\u00a09锛?6"],
|
||||
defaultRatio: "1080脳1920px\u00a0\u00a0\u00a09锛?6",
|
||||
ratios: ["1080×1920px\u00a0\u00a0\u00a09:16"],
|
||||
defaultRatio: "1080×1920px\u00a0\u00a0\u00a09:16",
|
||||
},
|
||||
hot: {
|
||||
ratios: ["800脳800px\u00a0\u00a0\u00a01锛?"],
|
||||
defaultRatio: "800脳800px\u00a0\u00a0\u00a01锛?",
|
||||
ratios: ["800×800px\u00a0\u00a0\u00a01:1"],
|
||||
defaultRatio: "800×800px\u00a0\u00a0\u00a01:1",
|
||||
},
|
||||
},
|
||||
specs: ["商品主图建议 1:1", "鐭棰?竖版封面建议 9:16"],
|
||||
specs: ["商品主图建议 1:1", "短视频竖版封面建议 9:16"],
|
||||
},
|
||||
];
|
||||
const platformOptions = platformSpecOptions.map((option) => option.label);
|
||||
@@ -684,7 +684,7 @@ const getPlatformLogoSources = (value: string) => {
|
||||
if (normalized.includes("shopee")) return [shopeeLogo];
|
||||
if (normalized.includes("lazada")) return [lazadaLogo];
|
||||
if (normalized.includes("instagram")) return [instagramLogo];
|
||||
if (value.includes("速卖通") || value.includes("閫熷崠閫")) return [aliexpressLogo];
|
||||
if (value.includes("速卖通")) return [aliexpressLogo];
|
||||
if (normalized.includes("ebay")) return [ebayLogo];
|
||||
if (normalized.includes("tiktok")) return [tiktokShopLogo];
|
||||
return [];
|
||||
@@ -744,7 +744,7 @@ const languageAliases: Record<string, string> = {
|
||||
"西班牙语": "西班牙语",
|
||||
"葡文": "葡萄牙语",
|
||||
"葡萄牙语": "葡萄牙语",
|
||||
"鍗板凹璇?": "印度尼西亚语",
|
||||
"印尼语": "印度尼西亚语",
|
||||
"印度尼西亚语": "印度尼西亚语",
|
||||
"菲律宾语": "菲律宾语(他加禄语)",
|
||||
"菲律宾语(他加禄语)": "菲律宾语(他加禄语)",
|
||||
@@ -755,10 +755,10 @@ const getPlatformSpec = (value: string) =>
|
||||
const legacyPlatformAliases: Record<string, string> = {
|
||||
"淘宝/天猫": "淘宝/天猫",
|
||||
"京东": "京东",
|
||||
"鎷煎澶?": "拼多多",
|
||||
"拼多多": "拼多多",
|
||||
"抖音电商": "抖音电商",
|
||||
"浜氶┈閫?Amazon": "亚马逊 Amazon",
|
||||
"閫熷崠閫?": "速卖通",
|
||||
"亚马逊Amazon": "亚马逊 Amazon",
|
||||
"速卖通": "速卖通",
|
||||
};
|
||||
const normalizePlatform = (value: string) => getPlatformSpec(legacyPlatformAliases[value] ?? value).label;
|
||||
const domesticPlatformLabels = new Set(["淘宝/天猫", "京东", "拼多多", "抖音电商"]);
|
||||
@@ -811,13 +811,13 @@ const formatRatioDisplayValue = (value: string) => {
|
||||
return `${width}×${height}px\u00a0\u00a0\u00a0${formatAspectRatio(width, height)}`;
|
||||
}
|
||||
return normalizedValue
|
||||
.replace("淘宝主图 / SKU 鍥?", "淘宝主图 / SKU 图 ")
|
||||
.replace("京东主图 / SKU 鍥?", "京东主图 / SKU 图 ")
|
||||
.replace("淘宝主图 / SKU 图 ", "淘宝主图 / SKU 图 ")
|
||||
.replace("京东主图 / SKU 图 ", "京东主图 / SKU 图 ")
|
||||
.replace("详情页宽", "详情页宽")
|
||||
.replace("鐭棰?", "短视频")
|
||||
.replace("短视频", "短视频")
|
||||
.replace("主图", "主图")
|
||||
.replace("商品主图", "商品主图")
|
||||
.replace("鍟嗗搧鍥?", "商品图");
|
||||
.replace("商品图", "商品图");
|
||||
};
|
||||
/** Extract CSS aspect-ratio from a ratio string like "1000x1000px 1:1" -> "1 / 1" */
|
||||
const parseRatioToAspectCss = (ratioStr: string): string => {
|
||||
@@ -825,7 +825,7 @@ const parseRatioToAspectCss = (ratioStr: string): string => {
|
||||
if (!match) return "1 / 1";
|
||||
return `${match[1]} / ${match[2]}`;
|
||||
};
|
||||
/** Normalize ratio display string ("1000脳1000px 1锛?") to API format ("1:1") */
|
||||
/** Normalize ratio display string ("1000×1000px 1:1") to API format ("1:1") */
|
||||
const normalizeRatioForApi = (ratioStr: string): string => {
|
||||
const match = ratioStr.match(/(\d+)\D+(\d+)/u);
|
||||
if (!match) return "1:1";
|
||||
@@ -938,7 +938,7 @@ const productSetAssets = ossAssets.ecommerce.productSet;
|
||||
const productSetPreviewCards = [
|
||||
{ id: "main", label: "01 主图 (白底/合规)", src: productSetAssets.main },
|
||||
{ id: "scene", label: "02 场景展示", src: productSetAssets.scene },
|
||||
{ id: "model", label: "03 妯$壒鍦烘櫙鍥?", src: productSetAssets.model },
|
||||
{ id: "model", label: "03 模特场景图", src: productSetAssets.model },
|
||||
{ id: "detail", label: "04 细节说明", src: productSetAssets.detail },
|
||||
{ id: "selling", label: "05 卖点详解", src: productSetAssets.selling },
|
||||
];
|
||||
@@ -998,6 +998,22 @@ function getImageFileFormat(file: File) {
|
||||
return file.name.split(".").pop()?.toUpperCase() ?? "";
|
||||
}
|
||||
|
||||
function getRemoteImageFormat(mimeType: string, imageUrl: string) {
|
||||
const mimeFormat = mimeType.split("/")[1]?.replace("jpeg", "jpg").toUpperCase();
|
||||
if (mimeFormat) return mimeFormat;
|
||||
return imageUrl.split("?")[0].split(".").pop()?.toUpperCase() ?? "IMAGE";
|
||||
}
|
||||
|
||||
function getRemoteImageName(imageUrl: string, fallback: string) {
|
||||
try {
|
||||
const parsed = new URL(imageUrl);
|
||||
const filename = decodeURIComponent(parsed.pathname.split("/").filter(Boolean).pop() || "");
|
||||
return filename || fallback;
|
||||
} catch {
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
|
||||
function readImageDimensions(src: string): Promise<{ width: number; height: number }> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const image = new Image();
|
||||
@@ -1219,7 +1235,9 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
const cloneReferenceInputRef = useRef<HTMLInputElement>(null);
|
||||
const smartCutoutInputRef = useRef<HTMLInputElement>(null);
|
||||
const imageWorkbenchInputRef = useRef<HTMLInputElement>(null);
|
||||
const imageWorkbenchUrlInputRef = useRef<HTMLInputElement>(null);
|
||||
const watermarkInputRef = useRef<HTMLInputElement>(null);
|
||||
const watermarkUrlInputRef = useRef<HTMLInputElement>(null);
|
||||
const watermarkProcessTimeoutRef = useRef<number | null>(null);
|
||||
const smartCutoutTransitionTimeoutRef = useRef<number | null>(null);
|
||||
const smartCutoutPendingUrlsRef = useRef<string[]>([]);
|
||||
@@ -1698,7 +1716,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
});
|
||||
setProductSetStatus("ready");
|
||||
} catch (err) {
|
||||
toast.error(err instanceof Error ? err.message : "鍟嗗搧鍥句笂浼犲け璐?");
|
||||
toast.error(err instanceof Error ? err.message : "商品图上传失败");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1793,6 +1811,49 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
setIsCloneSettingsCollapsed(false);
|
||||
};
|
||||
|
||||
const loadRemoteImageFromInput = async (input: HTMLInputElement | null, fallbackName: string) => {
|
||||
const rawValue = input?.value.trim() ?? "";
|
||||
if (!rawValue) {
|
||||
toast.info("请先粘贴图片 URL");
|
||||
return null;
|
||||
}
|
||||
|
||||
let imageUrl: string;
|
||||
try {
|
||||
const parsed = new URL(rawValue, window.location.href);
|
||||
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
||||
throw new Error("仅支持 http 或 https 图片链接");
|
||||
}
|
||||
imageUrl = parsed.toString();
|
||||
} catch (error) {
|
||||
toast.error(error instanceof Error ? error.message : "图片 URL 不正确");
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(imageUrl);
|
||||
if (!response.ok) throw new Error(`图片读取失败(${response.status})`);
|
||||
const blob = await response.blob();
|
||||
if (!blob.type.startsWith("image/")) throw new Error("链接内容不是图片");
|
||||
const src = URL.createObjectURL(blob);
|
||||
try {
|
||||
await readImageDimensions(src);
|
||||
} catch {
|
||||
URL.revokeObjectURL(src);
|
||||
throw new Error("图片无法预览,请换一个链接");
|
||||
}
|
||||
if (input) input.value = "";
|
||||
return {
|
||||
src,
|
||||
name: getRemoteImageName(imageUrl, fallbackName),
|
||||
format: getRemoteImageFormat(blob.type, imageUrl),
|
||||
};
|
||||
} catch (error) {
|
||||
toast.error(error instanceof Error ? error.message : "图片导入失败");
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const closeWatermarkRemovalPage = () => {
|
||||
if (watermarkProcessTimeoutRef.current !== null) {
|
||||
window.clearTimeout(watermarkProcessTimeoutRef.current);
|
||||
@@ -1846,6 +1907,18 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
if (file) addWatermarkImage(file);
|
||||
};
|
||||
|
||||
const handleWatermarkUrlImport = async () => {
|
||||
const nextImage = await loadRemoteImageFromInput(watermarkUrlInputRef.current, "watermark-source");
|
||||
if (!nextImage) return;
|
||||
setWatermarkImage((current) => {
|
||||
if (current?.src) URL.revokeObjectURL(current.src);
|
||||
return nextImage;
|
||||
});
|
||||
setWatermarkStatus("idle");
|
||||
setActiveQuickTool("watermark");
|
||||
toast.success("图片已导入");
|
||||
};
|
||||
|
||||
const handleWatermarkGenerate = () => {
|
||||
if (!watermarkImage || watermarkStatus === "processing") return;
|
||||
if (watermarkProcessTimeoutRef.current !== null) window.clearTimeout(watermarkProcessTimeoutRef.current);
|
||||
@@ -1943,6 +2016,22 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
if (file) addImageWorkbenchImage(file);
|
||||
};
|
||||
|
||||
const handleImageWorkbenchUrlImport = async () => {
|
||||
const nextImage = await loadRemoteImageFromInput(imageWorkbenchUrlInputRef.current, "image-workbench-source");
|
||||
if (!nextImage) return;
|
||||
setImageWorkbenchImage((current) => {
|
||||
if (current?.src) URL.revokeObjectURL(current.src);
|
||||
return nextImage;
|
||||
});
|
||||
setImageWorkbenchStatus("idle");
|
||||
setImageWorkbenchMaskStrokes([]);
|
||||
setImageWorkbenchBrushCursor(null);
|
||||
clearImageWorkbenchMaskCanvas();
|
||||
imageWorkbenchActiveStrokeIdRef.current = null;
|
||||
setActiveQuickTool("image-edit");
|
||||
toast.success("图片已导入");
|
||||
};
|
||||
|
||||
const handleImageWorkbenchGenerate = () => {
|
||||
if (!imageWorkbenchImage) {
|
||||
toast.info("请先上传图片");
|
||||
@@ -2444,7 +2533,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
setStatus("ready");
|
||||
setResults([]);
|
||||
} catch (err) {
|
||||
toast.error(err instanceof Error ? err.message : "鍟嗗搧鍥句笂浼犲け璐?");
|
||||
toast.error(err instanceof Error ? err.message : "商品图上传失败");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2961,7 +3050,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
setGarmentImages((current) => [...current, ...nextImages].slice(0, 5));
|
||||
setTryOnStatus("ready");
|
||||
} catch (err) {
|
||||
toast.error(err instanceof Error ? err.message : "鏈嶉グ鍥句笂浼犲け璐?");
|
||||
toast.error(err instanceof Error ? err.message : "服饰图上传失败");
|
||||
}
|
||||
})();
|
||||
event.target.value = "";
|
||||
@@ -3011,7 +3100,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
setDetailStatus("ready");
|
||||
setDetailResultUrl(null);
|
||||
} catch (err) {
|
||||
toast.error(err instanceof Error ? err.message : "璇︽儏鍥句笂浼犲け璐?");
|
||||
toast.error(err instanceof Error ? err.message : "详情图上传失败");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3040,9 +3129,9 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
const IMAGE_MODEL = "gpt-image-2";
|
||||
|
||||
const setCountLabels: Record<CloneSetCountKey, { label: string; promptDesc: string }> = {
|
||||
selling: { label: "鍗栫偣鍥?", promptDesc: "selling-point infographic image highlighting core product advantages and detail close-ups" },
|
||||
white: { label: "白底鍥?", promptDesc: "clean white-background product photo showing the item from its best angle, studio lighting, no props" },
|
||||
scene: { label: "鍦烘櫙鍥?", promptDesc: "lifestyle scene image showing the product in a realistic usage environment with natural surroundings" },
|
||||
selling: { label: "卖点图", promptDesc: "selling-point infographic image highlighting core product advantages and detail close-ups" },
|
||||
white: { label: "白底图", promptDesc: "clean white-background product photo showing the item from its best angle, studio lighting, no props" },
|
||||
scene: { label: "场景图", promptDesc: "lifestyle scene image showing the product in a realistic usage environment with natural surroundings" },
|
||||
};
|
||||
|
||||
const buildDetailModulePrompt = (moduleIds: string[]): string => {
|
||||
@@ -3182,7 +3271,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
imageGen.updateTask(storeId, { status: "completed", progress: 100, resultUrl: persistedUrl });
|
||||
} else {
|
||||
generatedUrls.push("");
|
||||
imageGen.updateTask(storeId, { status: "failed", error: "生成鏈繑鍥炵粨鏋?" });
|
||||
imageGen.updateTask(storeId, { status: "failed", error: "生成未返回结果" });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3270,7 +3359,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
imageGen.updateTask(storeId, { status: "completed", progress: 100, resultUrl: persistedUrl });
|
||||
} else {
|
||||
statusFn?.("idle");
|
||||
imageGen.updateTask(storeId, { status: "failed", error: "生成鏈繑鍥炵粨鏋?" });
|
||||
imageGen.updateTask(storeId, { status: "failed", error: "生成未返回结果" });
|
||||
}
|
||||
} catch (err) {
|
||||
if (imageAbortRef.current.current) {
|
||||
@@ -3467,7 +3556,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
|
||||
const handleDetailAiWrite = () => {
|
||||
setDetailRequirement(
|
||||
"1.产品名称:无线降噪蓝牙耳机\n2.鏍稿績鍗栫偣锛氫富鍔ㄩ檷鍣€?4H续航、低延迟连接、舒适佩戴\n3.适用人群:通勤、办公、运动和旅行用户\n4.期望场景:地铁通勤、居家办公、户外运动\n5.鍏蜂綋参数锛氳摑鐗?.3銆両PX4闃叉按銆佸揩鍏?0分钟使用2小时",
|
||||
"1.产品名称:无线降噪蓝牙耳机\n2.核心卖点:主动降噪、24H续航、低延迟连接、舒适佩戴\n3.适用人群:通勤、办公、运动和旅行用户\n4.期望场景:地铁通勤、居家办公、户外运动\n5.具体参数:蓝牙5.3、IPX4防水、快充10分钟使用2小时",
|
||||
);
|
||||
};
|
||||
|
||||
@@ -3547,19 +3636,19 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
const isWatermarkTool = isCloneTool && activeQuickTool === "watermark";
|
||||
const isImageEditTool = isCloneTool && activeQuickTool === "image-edit";
|
||||
const isHotVideoTool = isCloneTool && activeQuickTool === "hot-video";
|
||||
const pageLabel = isSetTool ? "商品套图" : isDetail ? "A+/璇︽儏椤?" : isTryOn ? "AI服饰穿戴" : activeToolMeta?.label || "商品工具";
|
||||
const pageLabel = isSetTool ? "商品套图" : isDetail ? "A+/详情页" : isTryOn ? "AI服饰穿戴" : activeToolMeta?.label || "商品工具";
|
||||
const setPrimaryLabel =
|
||||
setImages.length === 0
|
||||
? "请先上传商品原图"
|
||||
: productSetStatus === "generating"
|
||||
? "生成涓?.."
|
||||
? "生成中..."
|
||||
: "生成" + selectedProductSetOutput.label;
|
||||
const tryOnPrimaryLabel =
|
||||
garmentImages.length === 0 ? "请先上传服装图片" : tryOnStatus === "generating" ? "生成涓?.." : "生成服饰穿戴鍥?";
|
||||
garmentImages.length === 0 ? "请先上传服装图片" : tryOnStatus === "generating" ? "生成中..." : "生成服饰穿戴图";
|
||||
const detailPrimaryLabel =
|
||||
detailProductImages.length === 0 ? "请上传产品图" : detailStatus === "generating" ? "生成涓?.." : "生成A+璇︽儏椤?";
|
||||
detailProductImages.length === 0 ? "请上传产品图" : detailStatus === "generating" ? "生成中..." : "生成A+详情页";
|
||||
const clonePrimaryLabel =
|
||||
productImages.length === 0 ? "请先上传商品原图" : status === "generating" ? "生成涓?.." : "生成" + selectedCloneOutput.label;
|
||||
productImages.length === 0 ? "请先上传商品原图" : status === "generating" ? "生成中..." : "生成" + selectedCloneOutput.label;
|
||||
const setPreviewCards: CloneResult[] = [];
|
||||
let setIndex = 0;
|
||||
for (const countKey of cloneSetCountKeys) {
|
||||
@@ -3693,7 +3782,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
if (historyRefreshLockRef.current) return;
|
||||
historyRefreshLockRef.current = true;
|
||||
setIsHistoryRefreshing(true);
|
||||
setHistoryRefreshMessage("鍒锋柊涓?..");
|
||||
setHistoryRefreshMessage("刷新中...");
|
||||
setHistoryRefreshStamp(Date.now());
|
||||
|
||||
window.setTimeout(() => {
|
||||
@@ -4023,7 +4112,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
value={productSetRequirement}
|
||||
onChange={(event) => setProductSetRequirement(event.target.value)}
|
||||
maxLength={500}
|
||||
placeholder="建议鍖呭惈浠ヤ笅淇℃伅锛氫骇鍝佸悕绉般€佹牳蹇冨崠鐐广€佹湡鏈涘満鏅€佸叿浣撳弬鏁?"
|
||||
placeholder="建议包含以下信息:产品名称、核心卖点、期望场景、具体参数"
|
||||
/>
|
||||
<button type="button" className="product-set-floating-submit" disabled={!canGenerateSet} onClick={handleSetGenerate}>
|
||||
{productSetStatus === "generating" ? <LoadingOutlined /> : null}
|
||||
@@ -4290,7 +4379,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
<span className="clone-ai-flow-node__label">附件原图</span>
|
||||
</div>
|
||||
|
||||
{/* Connector —鍒嗘敮杩炴帴绾?*/}
|
||||
{/* Connector - branch lines */}
|
||||
<div className="clone-ai-flow-connector" aria-hidden="true">
|
||||
<div className="clone-ai-flow-connector__trunk" />
|
||||
<div className="clone-ai-flow-connector__branches">
|
||||
@@ -4503,7 +4592,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
<strong>上传商品图</strong>
|
||||
</button>
|
||||
{productImages.length || videoOutfitVideoFile ? (
|
||||
<div className="ecom-command-asset-popover" aria-label="宸蹭笂浼犵礌鏉?">
|
||||
<div className="ecom-command-asset-popover" aria-label="已上传素材">
|
||||
{productImages.map((image) => (
|
||||
<figure key={image.id} className="ecom-command-asset-thumb">
|
||||
<img src={image.src} alt={image.name || "上传图片"} />
|
||||
@@ -4675,7 +4764,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
);
|
||||
|
||||
const smartCutoutPreview = (
|
||||
<main className={`ecom-smart-cutout-page${smartCutoutImage ? " is-editor" : " is-upload"}${isSmartCutoutTransitioning ? " is-transitioning" : ""}`} aria-label="智能抠图">
|
||||
<main key={`smart-cutout-${smartCutoutImage ? "editor" : "upload"}`} className={`ecom-smart-cutout-page ecom-tool-page-enter${smartCutoutImage ? " is-editor" : " is-upload"}${isSmartCutoutTransitioning ? " is-transitioning" : ""}`} aria-label="智能抠图">
|
||||
<input
|
||||
ref={smartCutoutInputRef}
|
||||
type="file"
|
||||
@@ -4950,7 +5039,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
);
|
||||
|
||||
const imageWorkbenchPreview = (
|
||||
<main className="ecom-image-workbench-page" aria-label="图片修改局部重绘">
|
||||
<main key="image-workbench" className="ecom-image-workbench-page ecom-tool-page-enter" aria-label="图片修改局部重绘">
|
||||
<input
|
||||
ref={imageWorkbenchInputRef}
|
||||
type="file"
|
||||
@@ -5021,8 +5110,15 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
)}
|
||||
</div>
|
||||
<div className="ecom-image-workbench-url-row">
|
||||
<input placeholder="粘贴图片 URL" aria-label="粘贴图片 URL" />
|
||||
<button type="button" onClick={() => toast.info("请先使用本地上传")}>添加</button>
|
||||
<input
|
||||
ref={imageWorkbenchUrlInputRef}
|
||||
placeholder="粘贴图片 URL"
|
||||
aria-label="粘贴图片 URL"
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === "Enter") void handleImageWorkbenchUrlImport();
|
||||
}}
|
||||
/>
|
||||
<button type="button" onClick={() => void handleImageWorkbenchUrlImport()}>添加</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -5155,7 +5251,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
);
|
||||
|
||||
const watermarkPreview = (
|
||||
<main className="ecom-watermark-page" aria-label="去水印">
|
||||
<main key="watermark" className="ecom-watermark-page ecom-tool-page-enter" aria-label="去水印">
|
||||
<input
|
||||
ref={watermarkInputRef}
|
||||
type="file"
|
||||
@@ -5165,7 +5261,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
/>
|
||||
<aside className="ecom-watermark-side">
|
||||
<header className="ecom-quick-set-panel-head ecom-watermark-panel-head">
|
||||
<strong className="ecom-quick-set-page-title">增/去水印</strong>
|
||||
<strong className="ecom-quick-set-page-title">去水印</strong>
|
||||
<button type="button" className="ecom-quick-set-back" onClick={closeWatermarkRemovalPage}>首页</button>
|
||||
<button type="button" className="ecom-quick-set-back" onClick={closeWatermarkRemovalPage}>上一页</button>
|
||||
</header>
|
||||
@@ -5225,8 +5321,15 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
)}
|
||||
</div>
|
||||
<div className="ecom-watermark-url-row">
|
||||
<input placeholder="粘贴图片 URL" aria-label="粘贴图片 URL" />
|
||||
<button type="button" onClick={() => toast.info("请先使用本地上传")}>导入</button>
|
||||
<input
|
||||
ref={watermarkUrlInputRef}
|
||||
placeholder="粘贴图片 URL"
|
||||
aria-label="粘贴图片 URL"
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === "Enter") void handleWatermarkUrlImport();
|
||||
}}
|
||||
/>
|
||||
<button type="button" onClick={() => void handleWatermarkUrlImport()}>导入</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -5350,7 +5453,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
);
|
||||
|
||||
const hotVideoPreview = (
|
||||
<main className="ecom-quick-set-page ecom-hot-video-page" aria-label="广告视频">
|
||||
<main key="hot-video" className="ecom-quick-set-page ecom-hot-video-page ecom-tool-page-enter" aria-label="广告视频">
|
||||
<div className="ecom-quick-set-body">
|
||||
<aside className="ecom-quick-set-panel" aria-label="广告视频设置">
|
||||
<header className="ecom-quick-set-panel-head">
|
||||
@@ -5475,7 +5578,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
);
|
||||
|
||||
const quickProductSetPreview = (
|
||||
<main className={`ecom-quick-set-page${isQuickPanelCollapsed ? " is-panel-collapsed" : ""}`} aria-label="AI商品套图">
|
||||
<main key="quick-set" className={`ecom-quick-set-page ecom-tool-page-enter${isQuickPanelCollapsed ? " is-panel-collapsed" : ""}`} aria-label="AI商品套图">
|
||||
<div className="ecom-quick-set-body">
|
||||
<aside className="ecom-quick-set-panel" aria-label="商品套图设置" onWheel={handleQuickPanelWheel}>
|
||||
<header className="ecom-quick-set-panel-head">
|
||||
@@ -5621,14 +5724,6 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="ecom-quick-set-collapse"
|
||||
aria-label={isQuickPanelCollapsed ? "展开设置" : "收起设置"}
|
||||
onClick={() => setIsQuickPanelCollapsed((value) => !value)}
|
||||
>
|
||||
{isQuickPanelCollapsed ? "›" : "‹"}
|
||||
</button>
|
||||
<button type="button" className="ecom-quick-set-help" aria-label="帮助" onClick={() => toast.info("上传商品原图后,可选择平台、语言、比例并开始生成。")}>?</button>
|
||||
</main>
|
||||
);
|
||||
@@ -5636,7 +5731,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
const quickDetailVisibleSelect = quickDetailBasicSelects.find((item) => item.key === visibleQuickSetSelect) ?? null;
|
||||
|
||||
const quickDetailPreview = (
|
||||
<main className={`ecom-quick-set-page ecom-quick-detail-page${isQuickPanelCollapsed ? " is-panel-collapsed" : ""}`} aria-label="A+详情页生成">
|
||||
<main key="quick-detail" className={`ecom-quick-set-page ecom-quick-detail-page ecom-tool-page-enter${isQuickPanelCollapsed ? " is-panel-collapsed" : ""}`} aria-label="A+详情页生成">
|
||||
<div className="ecom-quick-set-body">
|
||||
<aside className="ecom-quick-set-panel" aria-label="A+详情页设置" onWheel={handleQuickPanelWheel}>
|
||||
<header className="ecom-quick-set-panel-head">
|
||||
@@ -5794,14 +5889,6 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="ecom-quick-set-collapse"
|
||||
aria-label={isQuickPanelCollapsed ? "展开设置" : "收起设置"}
|
||||
onClick={() => setIsQuickPanelCollapsed((value) => !value)}
|
||||
>
|
||||
{isQuickPanelCollapsed ? "›" : "‹"}
|
||||
</button>
|
||||
<button type="button" className="ecom-quick-set-help" aria-label="帮助" onClick={() => toast.info("上传商品图后,选择平台和详情模块即可生成 A+ 详情页。")}>?</button>
|
||||
</main>
|
||||
);
|
||||
@@ -5930,7 +6017,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
? smartCutoutPreview
|
||||
: isQuickSetTool || isQuickDetailTool || isHotVideoTool
|
||||
? (
|
||||
<div className="ecom-quick-page-wrap">
|
||||
<div key={`quick-${activeQuickTool}`} className="ecom-quick-page-wrap ecom-tool-page-enter">
|
||||
{quickPageSidebar}
|
||||
{isQuickSetTool ? quickProductSetPreview : isQuickDetailTool ? quickDetailPreview : hotVideoPreview}
|
||||
</div>
|
||||
@@ -5948,7 +6035,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
|
||||
return (
|
||||
<section
|
||||
className={`product-clone-page page-motion${isCloneTool && isCloneSettingsCollapsed ? " is-settings-collapsed" : ""}${isCloneTool && isCommandHistoryCollapsed ? " is-history-collapsed" : ""}${isSmartCutoutTool ? " is-smart-cutout-page" : ""}${isQuickSetTool || isQuickDetailTool ? " is-quick-set-page" : ""}${isWatermarkTool ? " is-watermark-page" : ""}${isImageEditTool ? " is-image-workbench-page" : ""}${isHotVideoTool ? " is-hot-video-page" : ""}`}
|
||||
className={`product-clone-page page-motion${isCloneTool && isCloneSettingsCollapsed ? " is-settings-collapsed" : ""}${isCloneTool && isCommandHistoryCollapsed ? " is-history-collapsed" : ""}${isSmartCutoutTool ? " is-smart-cutout-page" : ""}${isQuickSetTool || isQuickDetailTool || isHotVideoTool ? " is-quick-set-page" : ""}${isWatermarkTool ? " is-watermark-page" : ""}${isImageEditTool ? " is-image-workbench-page" : ""}${isHotVideoTool ? " is-hot-video-page" : ""}`}
|
||||
data-tool={activeTool}
|
||||
aria-label={pageLabel}
|
||||
>
|
||||
@@ -5994,7 +6081,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
productImageFiles={ecommerceVideoImageFiles}
|
||||
requirement={requirement}
|
||||
platform={platform}
|
||||
aspectRatio={ratio.includes("9锛?6") || ratio.includes("9:16") ? "9:16" : ratio.includes("16锛?") || ratio.includes("16:9") ? "16:9" : ratio.includes("3锛?") || ratio.includes("3:4") ? "3:4" : "9:16"}
|
||||
aspectRatio={ratio.includes("9:16") || ratio.includes("9:16") ? "9:16" : ratio.includes("16:9") || ratio.includes("16:9") ? "16:9" : ratio.includes("3:4") || ratio.includes("3:4") ? "3:4" : "9:16"}
|
||||
durationSeconds={cloneVideoDuration}
|
||||
resolution={cloneVideoQuality === "standard" ? "720P" : "1080P"}
|
||||
onRequestLogin={() => (isAuthenticated ? undefined : requestLogin())}
|
||||
|
||||
@@ -622,7 +622,6 @@ export default function EcommerceVideoWorkspace({
|
||||
const imagedScenes = scenes.filter((s) => s.imageUrl);
|
||||
const primaryVideo = completedScenes[0]?.resultUrl;
|
||||
const sourceImage = sourceImageUrls[0] || planResult?.imageUrls[0] || productImageDataUrls[0] || "";
|
||||
const flowHasStarted = stage !== "idle" || completedSteps.length > 0;
|
||||
const flowMeta = `${platform} / ${aspectRatio} / ${durationSeconds}s / ${resolution}`;
|
||||
const hasImaging = stage === "imaging" || stage === "imaged" || stage === "rendering" || stage === "completed" || stage === "partial_failed";
|
||||
const hasRendering = stage === "rendering" || stage === "completed" || stage === "partial_failed";
|
||||
@@ -630,11 +629,16 @@ export default function EcommerceVideoWorkspace({
|
||||
|
||||
return (
|
||||
<div className="ecom-video-workspace" data-stage={stage}>
|
||||
{/* ── Flow bar ──────────────────────────────────── */}
|
||||
<header className="ecom-video-flowbar">
|
||||
<div className="ecom-video-flowbar__title" aria-label={`短视频分镜流,${flowMeta}`} title={flowMeta}>
|
||||
<span className={`ecom-video-flowbar__pulse${flowHasStarted ? " is-active" : ""}`} aria-hidden="true" />
|
||||
<span className="ecom-video-flowbar__wave" aria-hidden="true"><i /><i /><i /></span>
|
||||
{/* ── Preview header ─────────────────────────────── */}
|
||||
<header className="ecom-video-flowbar ecom-video-preview-head" title={flowMeta}>
|
||||
<div className="ecom-video-preview-copy">
|
||||
<h1>预览</h1>
|
||||
<p>上传商品图,AI 即刻生成 <span>符合多电商平台规范</span> 的高转化率短视频素材。</p>
|
||||
<div className="ecom-video-flowbar__zoom">
|
||||
<button type="button" onClick={() => setFlowZoom((z) => Math.max(0.25, z - 0.1))} disabled={flowZoom <= 0.25} aria-label="缩小">−</button>
|
||||
<span>{Math.round(flowZoom * 100)}%</span>
|
||||
<button type="button" onClick={() => setFlowZoom((z) => Math.min(2, z + 0.1))} disabled={flowZoom >= 2} aria-label="放大">+</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="ecom-video-step-dots" aria-label="策划进度">
|
||||
@@ -645,12 +649,6 @@ export default function EcommerceVideoWorkspace({
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div className="ecom-video-flowbar__zoom">
|
||||
<button type="button" onClick={() => setFlowZoom((z) => Math.max(0.25, z - 0.1))} disabled={flowZoom <= 0.25} aria-label="缩小">−</button>
|
||||
<span>{Math.round(flowZoom * 100)}%</span>
|
||||
<button type="button" onClick={() => setFlowZoom((z) => Math.min(2, z + 0.1))} disabled={flowZoom >= 2} aria-label="放大">+</button>
|
||||
</div>
|
||||
|
||||
<div className="ecom-video-flowbar__actions">
|
||||
{onOpenHistory ? (
|
||||
<button type="button" className="ecom-video-flow-action ecom-video-flow-action--ghost" onClick={onOpenHistory} title="生成记录">
|
||||
|
||||
@@ -2394,7 +2394,21 @@
|
||||
.ecommerce-standalone .ecommerce-auth-modal__scrim,
|
||||
.ecommerce-standalone .ecommerce-profile-popover__backdrop,
|
||||
.ecommerce-standalone .product-set-preview-backdrop,
|
||||
.ecommerce-standalone .ecom-command-asset-popover {
|
||||
.ecommerce-standalone .ecom-command-asset-popover,
|
||||
.ecommerce-standalone .ecom-tool-page-enter,
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-quick-page-sidebar,
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-quick-set-panel,
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-watermark-side,
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-image-workbench-side,
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-smart-cutout-nav,
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-quick-set-stage,
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-watermark-workspace,
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-image-workbench-stage,
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-smart-cutout-upload,
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-smart-editor,
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-quick-set-panel > section,
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-watermark-panel,
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-image-workbench-panel {
|
||||
animation: none !important;
|
||||
}
|
||||
|
||||
@@ -4028,6 +4042,10 @@
|
||||
/* Smart cutout quick tool: standalone upload and editor flow. */
|
||||
.ecommerce-standalone .product-clone-page[data-tool="clone"].is-smart-cutout-page {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
min-width: 100% !important;
|
||||
height: 100% !important;
|
||||
min-height: calc(100vh - 58px) !important;
|
||||
overflow: hidden !important;
|
||||
background: #feffff !important;
|
||||
}
|
||||
@@ -4035,7 +4053,9 @@
|
||||
.ecommerce-standalone .product-clone-page[data-tool="clone"].is-smart-cutout-page .product-clone-shell {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
min-width: 100% !important;
|
||||
height: 100% !important;
|
||||
min-height: calc(100vh - 58px) !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
@@ -4797,6 +4817,63 @@
|
||||
font-weight: 750 !important;
|
||||
}
|
||||
|
||||
.ecommerce-standalone .ecom-hot-video-page .ecom-video-preview-head {
|
||||
display: grid !important;
|
||||
grid-template-columns: minmax(0, 1fr) auto !important;
|
||||
align-items: start !important;
|
||||
gap: 16px !important;
|
||||
min-height: 0 !important;
|
||||
padding: 0 0 18px !important;
|
||||
border: 0 !important;
|
||||
border-bottom: 1px solid rgba(16, 115, 204, 0.08) !important;
|
||||
background: transparent !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.ecommerce-standalone .ecom-hot-video-page .ecom-video-preview-copy {
|
||||
display: grid !important;
|
||||
gap: 8px !important;
|
||||
justify-items: start !important;
|
||||
min-width: 0 !important;
|
||||
}
|
||||
|
||||
.ecommerce-standalone .ecom-hot-video-page .ecom-video-preview-copy h1 {
|
||||
margin: 0 !important;
|
||||
color: #172636 !important;
|
||||
font-size: 21px !important;
|
||||
font-weight: 950 !important;
|
||||
line-height: 1.25 !important;
|
||||
letter-spacing: 0 !important;
|
||||
}
|
||||
|
||||
.ecommerce-standalone .ecom-hot-video-page .ecom-video-preview-copy p {
|
||||
margin: 0 !important;
|
||||
color: #657686 !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 750 !important;
|
||||
line-height: 1.55 !important;
|
||||
}
|
||||
|
||||
.ecommerce-standalone .ecom-hot-video-page .ecom-video-preview-copy p span {
|
||||
color: #1073cc !important;
|
||||
font-weight: 950 !important;
|
||||
}
|
||||
|
||||
.ecommerce-standalone .ecom-hot-video-page .ecom-video-preview-head .ecom-video-flowbar__zoom {
|
||||
display: inline-flex !important;
|
||||
align-items: center !important;
|
||||
gap: 8px !important;
|
||||
}
|
||||
|
||||
.ecommerce-standalone .ecom-hot-video-page .ecom-video-preview-head .ecom-video-step-dots {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.ecommerce-standalone .ecom-hot-video-page .ecom-video-preview-head .ecom-video-flowbar__actions {
|
||||
align-self: start !important;
|
||||
min-height: 24px !important;
|
||||
}
|
||||
|
||||
/* ── Step dots — light theme ──────────────────────── */
|
||||
.ecommerce-standalone .ecom-hot-video-page .ecom-video-step-dot {
|
||||
background: #cfd8dc !important;
|
||||
@@ -7649,33 +7726,7 @@
|
||||
}
|
||||
|
||||
.ecommerce-standalone .ecom-quick-set-collapse {
|
||||
position: absolute !important;
|
||||
left: 428px !important;
|
||||
top: 50% !important;
|
||||
z-index: 30 !important;
|
||||
display: inline-flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
width: 42px !important;
|
||||
height: 42px !important;
|
||||
min-height: 42px !important;
|
||||
border: 1px solid rgba(30, 189, 219, 0.22) !important;
|
||||
border-radius: 15px !important;
|
||||
color: #1073cc !important;
|
||||
background: #feffff !important;
|
||||
box-shadow: 0 16px 34px rgba(16, 115, 204, 0.14) !important;
|
||||
font-size: 25px !important;
|
||||
font-weight: 800 !important;
|
||||
line-height: 1 !important;
|
||||
cursor: pointer !important;
|
||||
transform: translateY(-50%) !important;
|
||||
transition:
|
||||
left 680ms cubic-bezier(0.22, 1, 0.36, 1),
|
||||
transform 220ms ease,
|
||||
border-color 260ms ease,
|
||||
background 260ms ease,
|
||||
color 260ms ease,
|
||||
box-shadow 460ms ease !important;
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.ecommerce-standalone .ecom-quick-set-collapse:hover {
|
||||
@@ -7692,7 +7743,9 @@
|
||||
.ecommerce-standalone .ecom-smart-cutout-page {
|
||||
position: relative !important;
|
||||
width: 100% !important;
|
||||
min-width: 100% !important;
|
||||
height: 100% !important;
|
||||
min-height: calc(100vh - 58px) !important;
|
||||
overflow: auto !important;
|
||||
color: #111820 !important;
|
||||
background: #feffff !important;
|
||||
@@ -8837,6 +8890,96 @@
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ecom-tool-page-enter {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(14px) scale(0.992);
|
||||
filter: saturate(0.96);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
filter: saturate(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ecom-tool-panel-enter {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(16px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ecom-tool-side-enter {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateX(-14px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ecom-tool-stage-enter {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateX(16px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
.ecommerce-standalone .ecom-tool-page-enter {
|
||||
animation: ecom-tool-page-enter 460ms cubic-bezier(0.16, 1, 0.3, 1) both !important;
|
||||
will-change: opacity, transform;
|
||||
}
|
||||
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-quick-page-sidebar,
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-quick-set-panel,
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-watermark-side,
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-image-workbench-side,
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-smart-cutout-nav {
|
||||
animation: ecom-tool-side-enter 430ms cubic-bezier(0.16, 1, 0.3, 1) 40ms both !important;
|
||||
}
|
||||
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-quick-set-stage,
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-watermark-workspace,
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-image-workbench-stage,
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-smart-cutout-upload,
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-smart-editor {
|
||||
animation: ecom-tool-stage-enter 500ms cubic-bezier(0.16, 1, 0.3, 1) 90ms both !important;
|
||||
}
|
||||
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-quick-set-panel > section,
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-watermark-panel,
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-image-workbench-panel {
|
||||
animation: ecom-tool-panel-enter 420ms cubic-bezier(0.16, 1, 0.3, 1) both !important;
|
||||
}
|
||||
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-quick-set-panel > section:nth-of-type(1),
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-watermark-panel:nth-of-type(1),
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-image-workbench-panel:nth-of-type(1) {
|
||||
animation-delay: 80ms !important;
|
||||
}
|
||||
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-quick-set-panel > section:nth-of-type(2),
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-watermark-panel:nth-of-type(2),
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-image-workbench-panel:nth-of-type(2) {
|
||||
animation-delay: 130ms !important;
|
||||
}
|
||||
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-quick-set-panel > section:nth-of-type(3),
|
||||
.ecommerce-standalone .ecom-tool-page-enter .ecom-image-workbench-panel:nth-of-type(3) {
|
||||
animation-delay: 180ms !important;
|
||||
}
|
||||
|
||||
@keyframes ecom-smart-upload-enter {
|
||||
from {
|
||||
opacity: 0;
|
||||
|
||||
Reference in New Issue
Block a user