foliko 1.1.8 → 1.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (306) hide show
  1. package/.agent/agents/code-assistant.json +17 -0
  2. package/.agent/agents/email-assistant.json +14 -0
  3. package/.agent/agents/file-assistant.json +18 -0
  4. package/.agent/agents/orchestrator-demo.md +53 -0
  5. package/.agent/agents/orchestrator.json +7 -0
  6. package/.agent/agents/poster-expert.md +228 -0
  7. package/.agent/agents/system-assistant.json +15 -0
  8. package/.agent/agents/web-assistant.json +12 -0
  9. package/.agent/data/default.json +5 -404
  10. package/.agent/data/email/processed-emails.json +1 -0
  11. package/.agent/data/plugins-state.json +173 -172
  12. package/.agent/data/scheduler/tasks.json +1 -0
  13. package/.agent/data/web/web-config.json +5 -0
  14. package/.agent/mcp_config.json +0 -14
  15. package/.agent/package.json +8 -0
  16. package/.agent/plugins/__pycache__/file_writer.cpython-312.pyc +0 -0
  17. package/.agent/plugins/daytona/README.md +89 -0
  18. package/.agent/plugins/daytona/index.js +377 -0
  19. package/.agent/plugins/daytona/package.json +12 -0
  20. package/.agent/plugins/marknative/README.md +134 -0
  21. package/.agent/plugins/marknative/fonts.zip +0 -0
  22. package/.agent/plugins/marknative/index.js +256 -0
  23. package/.agent/plugins/marknative/package.json +12 -0
  24. package/.agent/plugins/system-info/index.js +387 -0
  25. package/.agent/plugins/system-info/package.json +4 -0
  26. package/.agent/plugins/system-info/test.js +40 -0
  27. package/.agent/plugins/test-plugin.py +123 -0
  28. package/.agent/plugins/test_nested_plugin.py +85 -0
  29. package/.agent/plugins.json +11 -5
  30. package/.agent/python-scripts/test_sample.py +24 -0
  31. package/.agent/sessions/cli_default.json +96 -249
  32. package/.agent/sessions/weixin_o9cq80zgZqKPA2-s59PN43GdDy1w@im.wechat.json +189 -0
  33. package/.agent/skills/agent-browser/SKILL.md +311 -0
  34. package/.agent/skills/agent-browser/TEST_PLAN.md +200 -0
  35. package/.agent/skills/sysinfo/SKILL.md +38 -0
  36. package/.agent/skills/sysinfo/system-info.sh +130 -0
  37. package/.agent/skills/workflow/SKILL.md +324 -0
  38. package/.agent/test-agent.js +35 -0
  39. package/.agent/weixin.json +6 -0
  40. package/.agent/workflows/email-digest.json +50 -0
  41. package/.agent/workflows/file-backup.json +21 -0
  42. package/.agent/workflows/get-ip-notify.json +32 -0
  43. package/.agent/workflows/news-aggregator.json +93 -0
  44. package/.agent/workflows/news-dashboard-v2.json +94 -0
  45. package/.agent/workflows/notification-batch.json +32 -0
  46. package/.claude/settings.local.json +9 -1
  47. package/.env.example +56 -56
  48. package/README.md +441 -441
  49. package/cli/src/ui/chat-ui.js +32 -21
  50. package/foliko_poster.png +0 -0
  51. package/output/business_poster_final.png +0 -0
  52. package/output/emoji_test_v2.png +0 -0
  53. package/output/foliko-ai-launch-poster.png +0 -0
  54. package/output/foliko-poster.png +0 -0
  55. package/output/muji_style_poster.png +0 -0
  56. package/output/new_product_launch.png +0 -0
  57. package/output/news_poster_625yi_subsidy.png +0 -0
  58. package/output/tech_future_2026.png +0 -0
  59. package/output/tech_future_poster.png +0 -0
  60. package/package.json +1 -2
  61. package/plugins/default-plugins.js +58 -6
  62. package/plugins/extension-executor-plugin.js +8 -21
  63. package/plugins/python-plugin-loader.js +461 -40
  64. package/plugins/python-plugin-loader.js.bak +856 -0
  65. package/plugins/subagent-plugin.js +0 -121
  66. package/plugins/weixin-plugin.js +38 -29
  67. package/poster.png +0 -0
  68. package/skills/find-skills/AGENTS.md +162 -162
  69. package/skills/find-skills/SKILL.md +133 -133
  70. package/skills/foliko-dev/SKILL.md +6 -0
  71. package/skills/python-plugin-dev/SKILL.md +124 -2
  72. package/src/core/agent-chat.js +220 -281
  73. package/src/core/agent.js +10 -0
  74. package/src/utils/plugin-helpers.js +22 -4
  75. package/system.md +1678 -1574
  76. package/test-scan.js +18 -0
  77. package/.agent/.shared/ui-ux-pro-max/data/charts.csv +0 -26
  78. package/.agent/.shared/ui-ux-pro-max/data/colors.csv +0 -97
  79. package/.agent/.shared/ui-ux-pro-max/data/icons.csv +0 -101
  80. package/.agent/.shared/ui-ux-pro-max/data/landing.csv +0 -31
  81. package/.agent/.shared/ui-ux-pro-max/data/products.csv +0 -97
  82. package/.agent/.shared/ui-ux-pro-max/data/prompts.csv +0 -24
  83. package/.agent/.shared/ui-ux-pro-max/data/react-performance.csv +0 -45
  84. package/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +0 -53
  85. package/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +0 -56
  86. package/.agent/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +0 -53
  87. package/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +0 -53
  88. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +0 -51
  89. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +0 -59
  90. package/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +0 -52
  91. package/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +0 -54
  92. package/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +0 -61
  93. package/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +0 -54
  94. package/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +0 -51
  95. package/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +0 -50
  96. package/.agent/.shared/ui-ux-pro-max/data/styles.csv +0 -59
  97. package/.agent/.shared/ui-ux-pro-max/data/typography.csv +0 -58
  98. package/.agent/.shared/ui-ux-pro-max/data/ui-reasoning.csv +0 -101
  99. package/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +0 -100
  100. package/.agent/.shared/ui-ux-pro-max/data/web-interface.csv +0 -31
  101. package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/core.cpython-313.pyc +0 -0
  102. package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-313.pyc +0 -0
  103. package/.agent/.shared/ui-ux-pro-max/scripts/core.py +0 -258
  104. package/.agent/.shared/ui-ux-pro-max/scripts/design_system.py +0 -1067
  105. package/.agent/.shared/ui-ux-pro-max/scripts/search.py +0 -106
  106. package/.agent/ARCHITECTURE.md +0 -288
  107. package/.agent/agents/ambient-agent.md +0 -57
  108. package/.agent/agents/debugger.md +0 -55
  109. package/.agent/agents/email-assistant.md +0 -49
  110. package/.agent/agents/file-manager.md +0 -42
  111. package/.agent/agents/python-developer.md +0 -60
  112. package/.agent/agents/scheduler.md +0 -59
  113. package/.agent/agents/web-developer.md +0 -45
  114. package/.agent/data/puppeteer-sessions/undefined.json +0 -6
  115. package/.agent/data/weixin-media/2026-04-08/img_1775618677512.jpg +0 -0
  116. package/.agent/data/weixin-media/2026-04-08/img_1775619073340.jpg +0 -0
  117. package/.agent/data/weixin-media/2026-04-08/img_1775619097536.jpg +0 -0
  118. package/.agent/data/weixin-media/2026-04-08/img_1775619209388.jpg +0 -0
  119. package/.agent/memory/feedback/mnrdvj5i-ca3dkd.md +0 -9
  120. package/.agent/memory/feedback/mnre365e-7s4zax.md +0 -9
  121. package/.agent/memory/feedback/mnre36jn-nkfgmp.md +0 -9
  122. package/.agent/memory/feedback/mnre3805-kjiq6h.md +0 -9
  123. package/.agent/memory/feedback/mnsf66kp-b10rcd.md +0 -9
  124. package/.agent/memory/feedback/mnsi3sz8-p5g2cw.md +0 -9
  125. package/.agent/memory/feedback/mnsibe47-sv2ni1.md +0 -9
  126. package/.agent/memory/feedback/mnsic89w-nn228o.md +0 -9
  127. package/.agent/memory/feedback/mnsj1xe9-x83ba0.md +0 -9
  128. package/.agent/memory/feedback/mnsj21iv-wnwelx.md +0 -9
  129. package/.agent/memory/feedback/mnsj2g4a-cog7a2.md +0 -9
  130. package/.agent/memory/feedback/mnsj4js7-lktjp6.md +0 -9
  131. package/.agent/memory/feedback/mnsj5d4y-uglwvp.md +0 -9
  132. package/.agent/memory/feedback/mnslkuo9-uous66.md +0 -24
  133. package/.agent/memory/feedback/mnsm3vq0-megoil.md +0 -9
  134. package/.agent/memory/feedback/mnsnn5x2-sxcihd.md +0 -9
  135. package/.agent/memory/feedback/mnsnq17s-nabrn9.md +0 -9
  136. package/.agent/memory/feedback/mnsnybet-wz7rn3.md +0 -9
  137. package/.agent/memory/feedback/mnsrw0s7-7s9e30.md +0 -9
  138. package/.agent/memory/feedback/mnu5hpnd-tlm16q.md +0 -9
  139. package/.agent/memory/feedback/mnu60uqe-xuoxp4.md +0 -9
  140. package/.agent/memory/project/mnqx54u5-loqtoe.md +0 -9
  141. package/.agent/memory/project/mnqx84cv-mx6dmd.md +0 -9
  142. package/.agent/memory/project/mnsacuyr-hgtk5n.md +0 -20
  143. package/.agent/memory/project/mnu5hy2x-bjsg7u.md +0 -9
  144. package/.agent/memory/reference/mnre3cww-penbo1.md +0 -9
  145. package/.agent/memory/reference/mns9wn48-luerua.md +0 -14
  146. package/.agent/memory/reference/mns9yz5c-thc2s0.md +0 -16
  147. package/.agent/memory/reference/mnsfy4um-910f1o.md +0 -23
  148. package/.agent/memory/reference/mnsg37dp-lmfj18.md +0 -32
  149. package/.agent/memory/reference/mnsll60q-0j911u.md +0 -36
  150. package/.agent/memory/reference/mnsmlb5y-nej31u.md +0 -16
  151. package/.agent/memory/reference/mnssle72-yrot96.md +0 -9
  152. package/.agent/memory/user/mnsfuon6-l416q1.md +0 -21
  153. package/.agent/memory/user/mnsg9kut-95m7rf.md +0 -20
  154. package/.agent/memory/user/mnu2eo1v-yy6fhe.md +0 -9
  155. package/.agent/memory/user/mnu2etuo-8u8jk8.md +0 -9
  156. package/.agent/plugins/poster-plugin/README.md +0 -304
  157. package/.agent/plugins/poster-plugin/fonts/NotoColorEmoji-Regular.ttf +0 -0
  158. package/.agent/plugins/poster-plugin/fonts/PatuaOne-Regular.ttf +0 -0
  159. package/.agent/plugins/poster-plugin/fonts/Symbola_hint.ttf +0 -0
  160. package/.agent/plugins/poster-plugin/fonts//345/276/256/350/275/257/351/233/205/351/273/221.ttf +0 -0
  161. package/.agent/plugins/poster-plugin/fonts//345/276/256/350/275/257/351/233/205/351/273/221/347/262/227/344/275/223.ttf +0 -0
  162. package/.agent/plugins/poster-plugin/index.js +0 -13
  163. package/.agent/plugins/poster-plugin/package.json +0 -29
  164. package/.agent/plugins/poster-plugin/src/canvas.js +0 -232
  165. package/.agent/plugins/poster-plugin/src/components/arrow.js +0 -84
  166. package/.agent/plugins/poster-plugin/src/components/avatar.js +0 -71
  167. package/.agent/plugins/poster-plugin/src/components/badge.js +0 -85
  168. package/.agent/plugins/poster-plugin/src/components/barcode.js +0 -123
  169. package/.agent/plugins/poster-plugin/src/components/bubble.js +0 -154
  170. package/.agent/plugins/poster-plugin/src/components/button.js +0 -168
  171. package/.agent/plugins/poster-plugin/src/components/card.js +0 -88
  172. package/.agent/plugins/poster-plugin/src/components/chart.js +0 -127
  173. package/.agent/plugins/poster-plugin/src/components/chip.js +0 -88
  174. package/.agent/plugins/poster-plugin/src/components/columns.js +0 -121
  175. package/.agent/plugins/poster-plugin/src/components/cta.js +0 -87
  176. package/.agent/plugins/poster-plugin/src/components/divider.js +0 -55
  177. package/.agent/plugins/poster-plugin/src/components/feature.js +0 -85
  178. package/.agent/plugins/poster-plugin/src/components/featureGrid.js +0 -117
  179. package/.agent/plugins/poster-plugin/src/components/frame.js +0 -230
  180. package/.agent/plugins/poster-plugin/src/components/grid.js +0 -130
  181. package/.agent/plugins/poster-plugin/src/components/highlightText.js +0 -145
  182. package/.agent/plugins/poster-plugin/src/components/icon.js +0 -94
  183. package/.agent/plugins/poster-plugin/src/components/imageFrame.js +0 -205
  184. package/.agent/plugins/poster-plugin/src/components/index.js +0 -81
  185. package/.agent/plugins/poster-plugin/src/components/listItem.js +0 -147
  186. package/.agent/plugins/poster-plugin/src/components/notification.js +0 -123
  187. package/.agent/plugins/poster-plugin/src/components/progress.js +0 -79
  188. package/.agent/plugins/poster-plugin/src/components/progressCircle.js +0 -117
  189. package/.agent/plugins/poster-plugin/src/components/qrcode.js +0 -74
  190. package/.agent/plugins/poster-plugin/src/components/quote.js +0 -169
  191. package/.agent/plugins/poster-plugin/src/components/rating.js +0 -85
  192. package/.agent/plugins/poster-plugin/src/components/ribbon.js +0 -197
  193. package/.agent/plugins/poster-plugin/src/components/seal.js +0 -148
  194. package/.agent/plugins/poster-plugin/src/components/star.js +0 -70
  195. package/.agent/plugins/poster-plugin/src/components/statCard.js +0 -105
  196. package/.agent/plugins/poster-plugin/src/components/stepper.js +0 -118
  197. package/.agent/plugins/poster-plugin/src/components/table.js +0 -167
  198. package/.agent/plugins/poster-plugin/src/components/tagCloud.js +0 -85
  199. package/.agent/plugins/poster-plugin/src/components/timeline.js +0 -117
  200. package/.agent/plugins/poster-plugin/src/components/watermark.js +0 -54
  201. package/.agent/plugins/poster-plugin/src/composer.js +0 -2314
  202. package/.agent/plugins/poster-plugin/src/elements/artText.js +0 -69
  203. package/.agent/plugins/poster-plugin/src/elements/background.js +0 -99
  204. package/.agent/plugins/poster-plugin/src/elements/circle.js +0 -31
  205. package/.agent/plugins/poster-plugin/src/elements/image.js +0 -28
  206. package/.agent/plugins/poster-plugin/src/elements/index.js +0 -28
  207. package/.agent/plugins/poster-plugin/src/elements/line.js +0 -23
  208. package/.agent/plugins/poster-plugin/src/elements/polygon.js +0 -63
  209. package/.agent/plugins/poster-plugin/src/elements/rectangle.js +0 -32
  210. package/.agent/plugins/poster-plugin/src/elements/richText.js +0 -283
  211. package/.agent/plugins/poster-plugin/src/elements/svg.js +0 -108
  212. package/.agent/plugins/poster-plugin/src/elements/text.js +0 -112
  213. package/.agent/plugins/poster-plugin/src/fonts.js +0 -674
  214. package/.agent/plugins/poster-plugin/src/index.js +0 -2126
  215. package/.agent/plugins/poster-plugin/src/presets.js +0 -36
  216. package/.agent/plugins/poster-plugin/src/templates/business.js +0 -60
  217. package/.agent/plugins/poster-plugin/src/templates/gradient.js +0 -64
  218. package/.agent/plugins/poster-plugin/src/templates/index.js +0 -43
  219. package/.agent/plugins/poster-plugin/src/templates/modern.js +0 -69
  220. package/.agent/plugins/poster-plugin/src/templates/simple.js +0 -58
  221. package/.agent/plugins/poster-plugin/src/templates/social.js +0 -62
  222. package/.agent/plugins/poster-plugin/src/templates/tech.js +0 -84
  223. package/.agent/plugins/poster-plugin/src/utils/imageLoader.js +0 -84
  224. package/.agent/plugins/poster-plugin/yarn.lock +0 -837
  225. package/.agent/plugins/puppeteer-plugin/README.md +0 -147
  226. package/.agent/plugins/puppeteer-plugin/index.js +0 -1422
  227. package/.agent/plugins/puppeteer-plugin/package.json +0 -9
  228. package/.agent/rules/GEMINI.md +0 -273
  229. package/.agent/rules/allow-rule.md +0 -77
  230. package/.agent/rules/log-rule.md +0 -83
  231. package/.agent/rules/security-rule.md +0 -93
  232. package/.agent/scripts/auto_preview.py +0 -148
  233. package/.agent/scripts/checklist.py +0 -217
  234. package/.agent/scripts/session_manager.py +0 -120
  235. package/.agent/scripts/verify_all.py +0 -327
  236. package/.agent/skills/api-patterns/SKILL.md +0 -81
  237. package/.agent/skills/api-patterns/api-style.md +0 -42
  238. package/.agent/skills/api-patterns/auth.md +0 -24
  239. package/.agent/skills/api-patterns/documentation.md +0 -26
  240. package/.agent/skills/api-patterns/graphql.md +0 -41
  241. package/.agent/skills/api-patterns/rate-limiting.md +0 -31
  242. package/.agent/skills/api-patterns/response.md +0 -37
  243. package/.agent/skills/api-patterns/rest.md +0 -40
  244. package/.agent/skills/api-patterns/scripts/api_validator.py +0 -211
  245. package/.agent/skills/api-patterns/security-testing.md +0 -122
  246. package/.agent/skills/api-patterns/trpc.md +0 -41
  247. package/.agent/skills/api-patterns/versioning.md +0 -22
  248. package/.agent/skills/app-builder/SKILL.md +0 -75
  249. package/.agent/skills/app-builder/agent-coordination.md +0 -71
  250. package/.agent/skills/app-builder/feature-building.md +0 -53
  251. package/.agent/skills/app-builder/project-detection.md +0 -34
  252. package/.agent/skills/app-builder/scaffolding.md +0 -118
  253. package/.agent/skills/app-builder/tech-stack.md +0 -40
  254. package/.agent/skills/app-builder/templates/SKILL.md +0 -39
  255. package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +0 -76
  256. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +0 -92
  257. package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +0 -88
  258. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +0 -88
  259. package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +0 -83
  260. package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +0 -90
  261. package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +0 -90
  262. package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +0 -122
  263. package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +0 -122
  264. package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +0 -169
  265. package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +0 -134
  266. package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +0 -83
  267. package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +0 -119
  268. package/.agent/skills/architecture/SKILL.md +0 -55
  269. package/.agent/skills/architecture/context-discovery.md +0 -43
  270. package/.agent/skills/architecture/examples.md +0 -94
  271. package/.agent/skills/architecture/pattern-selection.md +0 -68
  272. package/.agent/skills/architecture/patterns-reference.md +0 -50
  273. package/.agent/skills/architecture/trade-off-analysis.md +0 -77
  274. package/.agent/skills/clean-code/SKILL.md +0 -201
  275. package/.agent/skills/doc.md +0 -177
  276. package/.agent/skills/frontend-design/SKILL.md +0 -418
  277. package/.agent/skills/frontend-design/animation-guide.md +0 -331
  278. package/.agent/skills/frontend-design/color-system.md +0 -311
  279. package/.agent/skills/frontend-design/decision-trees.md +0 -418
  280. package/.agent/skills/frontend-design/motion-graphics.md +0 -306
  281. package/.agent/skills/frontend-design/scripts/accessibility_checker.py +0 -183
  282. package/.agent/skills/frontend-design/scripts/ux_audit.py +0 -722
  283. package/.agent/skills/frontend-design/typography-system.md +0 -345
  284. package/.agent/skills/frontend-design/ux-psychology.md +0 -1116
  285. package/.agent/skills/frontend-design/visual-effects.md +0 -383
  286. package/.agent/skills/i18n-localization/SKILL.md +0 -154
  287. package/.agent/skills/i18n-localization/scripts/i18n_checker.py +0 -241
  288. package/.agent/skills/mcp-builder/SKILL.md +0 -176
  289. package/.agent/skills/poster-design/SKILL.md +0 -385
  290. package/.agent/skills/web-design-guidelines/SKILL.md +0 -57
  291. package/.agent/workflows/brainstorm.md +0 -113
  292. package/.agent/workflows/create.md +0 -59
  293. package/.agent/workflows/debug.md +0 -103
  294. package/.agent/workflows/deploy.md +0 -176
  295. package/.agent/workflows/enhance.md +0 -63
  296. package/.agent/workflows/orchestrate.md +0 -237
  297. package/.agent/workflows/plan.md +0 -89
  298. package/.agent/workflows/preview.md +0 -81
  299. package/.agent/workflows/simple-test.md +0 -42
  300. package/.agent/workflows/status.md +0 -86
  301. package/.agent/workflows/structured-orchestrate.md +0 -180
  302. package/.agent/workflows/test.md +0 -144
  303. package/.agent/workflows/ui-ux-pro-max.md +0 -296
  304. package/outputs/emoji-font-showcase.png +0 -0
  305. package/outputs/foliko-muji-style.png +0 -0
  306. /package/.agent/plugins/{poster-plugin → marknative}/fonts/SegoeUI Emoji.ttf +0 -0
@@ -1,69 +0,0 @@
1
- /**
2
- * 艺术文字元素 - 使用 @napi-rs/canvas 原生字体 API
3
- */
4
-
5
- const paper = require('paper')
6
- const {
7
- validateFont,
8
- getDefaultFontFamily,
9
- getFontFallbackChain
10
- } = require('../fonts')
11
-
12
- /**
13
- * 添加艺术文字
14
- */
15
- function addArtText(project, args) {
16
- const {
17
- text,
18
- x, y,
19
- fontSize,
20
- fontFamily,
21
- gradient,
22
- strokeColor,
23
- strokeWidth,
24
- shadow,
25
- } = args
26
-
27
- // 获取字体
28
- const baseFont = validateFont(fontFamily) || getDefaultFontFamily()
29
- const chain = getFontFallbackChain(fontFamily || baseFont, text)
30
- const font = chain.length === 1 ? chain[0] : chain.join(', ')
31
-
32
- const textItem = new paper.PointText({
33
- point: [x, y],
34
- content: text,
35
- fontSize: fontSize || 120,
36
- fontFamily: font,
37
- fillColor: gradient
38
- ? new paper.Color(gradient.colors[0])
39
- : new paper.Color('#ffffff'),
40
- justification: 'center',
41
- })
42
-
43
- // 渐变填充
44
- if (gradient && gradient.colors.length > 0) {
45
- const colors = gradient.colors.map(c => new paper.Color(c))
46
- textItem.fillColor = new paper.Color({
47
- gradient: { stops: colors },
48
- origin: textItem.bounds.topLeft,
49
- destination: textItem.bounds.topRight,
50
- })
51
- }
52
-
53
- // 描边
54
- if (strokeColor) {
55
- textItem.strokeColor = new paper.Color(strokeColor)
56
- textItem.strokeWidth = strokeWidth || 2
57
- }
58
-
59
- // 阴影
60
- if (shadow) {
61
- textItem.shadowColor = new paper.Color(shadow.color || '#000000')
62
- textItem.shadowBlur = shadow.blur || 10
63
- textItem.shadowOffset = new paper.Point(shadow.offsetX || 3, shadow.offsetY || 3)
64
- }
65
-
66
- return { success: true, id: textItem.id, type: 'artText' }
67
- }
68
-
69
- module.exports = addArtText
@@ -1,99 +0,0 @@
1
- /**
2
- * 背景元素
3
- */
4
-
5
- const paper = require('paper')
6
- const { loadImageAsRaster } = require('../utils/imageLoader')
7
-
8
- /**
9
- * 添加背景(支持纯色、渐变或图片)
10
- */
11
- async function addBackground(project, canvas, args) {
12
- const { color, gradient, image } = args
13
-
14
- if (image) {
15
- const { raster } = await loadImageAsRaster(project, image, { x: 0, y: 0 })
16
-
17
- raster.onLoad = () => {
18
- // 计算缩放比例,使图片覆盖整个画布(cover 模式)
19
- const canvasRatio = canvas.width / canvas.height
20
- const imageRatio = raster.width / raster.height
21
-
22
- let scaledWidth, scaledHeight, offsetX, offsetY
23
-
24
- if (imageRatio > canvasRatio) {
25
- // 图片更宽,以高度为基准缩放
26
- scaledHeight = canvas.height
27
- scaledWidth = raster.width * (canvas.height / raster.height)
28
- offsetX = (canvas.width - scaledWidth) / 2
29
- offsetY = 0
30
- } else {
31
- // 图片更高,以宽度为基准缩放
32
- scaledWidth = canvas.width
33
- scaledHeight = raster.height * (canvas.width / raster.width)
34
- offsetX = 0
35
- offsetY = (canvas.height - scaledHeight) / 2
36
- }
37
-
38
- raster.bounds = new paper.Rectangle(offsetX, offsetY, scaledWidth, scaledHeight)
39
- raster.sendToBack()
40
- }
41
-
42
- return { success: true, message: 'Background image added' }
43
- }
44
-
45
- if (gradient) {
46
- const { type, colors, direction } = gradient
47
- const paperColors = colors.map(c => new paper.Color(c))
48
-
49
- let gradientConfig
50
- if (type === 'linear') {
51
- const angle = (direction || 45) * Math.PI / 180
52
- const diagonal = Math.sqrt(canvas.width ** 2 + canvas.height ** 2)
53
- const start = new paper.Point(
54
- canvas.width / 2 - Math.cos(angle) * diagonal / 2,
55
- canvas.height / 2 - Math.sin(angle) * diagonal / 2
56
- )
57
- const stop = new paper.Point(
58
- canvas.width / 2 + Math.cos(angle) * diagonal / 2,
59
- canvas.height / 2 + Math.sin(angle) * diagonal / 2
60
- )
61
- gradientConfig = {
62
- gradient: { stops: paperColors },
63
- origin: start,
64
- destination: stop,
65
- }
66
- } else {
67
- // radial
68
- const center = new paper.Point(canvas.width / 2, canvas.height / 2)
69
- const radius = Math.max(canvas.width, canvas.height) / 2
70
- gradientConfig = {
71
- gradient: { stops: paperColors },
72
- origin: center,
73
- destination: center.add(new paper.Point(radius, 0)),
74
- }
75
- }
76
-
77
- // 创建矩形背景元素(确保导出时能正确渲染渐变)
78
- const bg = new paper.Path.Rectangle({
79
- point: [0, 0],
80
- size: [canvas.width, canvas.height],
81
- fillColor: new paper.Color(gradientConfig),
82
- })
83
- bg.sendToBack()
84
- } else if (color) {
85
- // 创建矩形背景元素(确保导出时能正确渲染)
86
- const bg = new paper.Path.Rectangle({
87
- point: [0, 0],
88
- size: [canvas.width, canvas.height],
89
- fillColor: new paper.Color(color),
90
- })
91
- bg.sendToBack()
92
- } else {
93
- throw new Error('Must provide color, gradient, or image')
94
- }
95
-
96
- return { success: true, message: 'Background added' }
97
- }
98
-
99
- module.exports = addBackground
@@ -1,31 +0,0 @@
1
- /**
2
- * 圆形/椭圆元素
3
- */
4
-
5
- const paper = require('paper')
6
-
7
- /**
8
- * 添加圆形或椭圆
9
- */
10
- function addCircle(project, args) {
11
- const {
12
- cx, cy, rx, ry,
13
- fill, stroke, strokeWidth, opacity,
14
- } = args
15
-
16
- const circle = new paper.Path.Ellipse({
17
- center: [cx, cy],
18
- radius: [rx, ry || rx],
19
- })
20
-
21
- if (fill) circle.fillColor = new paper.Color(fill)
22
- if (stroke) {
23
- circle.strokeColor = new paper.Color(stroke)
24
- circle.strokeWidth = strokeWidth || 1
25
- }
26
- if (opacity !== undefined) circle.opacity = opacity
27
-
28
- return { success: true, id: circle.id, type: 'circle' }
29
- }
30
-
31
- module.exports = addCircle
@@ -1,28 +0,0 @@
1
- /**
2
- * 图片元素
3
- */
4
-
5
- const paper = require('paper')
6
- const { loadImageAsRaster } = require('../utils/imageLoader')
7
-
8
- /**
9
- * 添加图片(支持本地路径、URL、Base64)
10
- */
11
- async function addImage(project, args) {
12
- const { src, x, y, width, height, opacity } = args
13
-
14
- try {
15
- const { raster } = await loadImageAsRaster(project, src, { x, y, width, height }, opacity)
16
-
17
- return {
18
- success: true,
19
- id: raster.id,
20
- type: 'image',
21
- path: src,
22
- }
23
- } catch (err) {
24
- return { success: false, error: `Failed to load image: ${err.message}` }
25
- }
26
- }
27
-
28
- module.exports = addImage
@@ -1,28 +0,0 @@
1
- /**
2
- * 基础元素模块导出
3
- */
4
-
5
- const addRectangle = require('./rectangle')
6
- const addCircle = require('./circle')
7
- const addLine = require('./line')
8
- const addPolygon = require('./polygon')
9
- const addImage = require('./image')
10
- const addText = require('./text')
11
- const addArtText = require('./artText')
12
- const addRichText = require('./richText')
13
- const addBackground = require('./background')
14
- const { addSVG, exportSVG } = require('./svg')
15
-
16
- module.exports = {
17
- addRectangle,
18
- addCircle,
19
- addLine,
20
- addPolygon,
21
- addImage,
22
- addText,
23
- addArtText,
24
- addRichText,
25
- addBackground,
26
- addSVG,
27
- exportSVG,
28
- }
@@ -1,23 +0,0 @@
1
- /**
2
- * 线条元素
3
- */
4
-
5
- const paper = require('paper')
6
-
7
- /**
8
- * 添加线条
9
- */
10
- function addLine(project, args) {
11
- const { x1, y1, x2, y2, stroke, strokeWidth } = args
12
-
13
- const line = new paper.Path.Line({
14
- from: [x1, y1],
15
- to: [x2, y2],
16
- strokeColor: new paper.Color(stroke || '#ffffff'),
17
- strokeWidth: strokeWidth || 2,
18
- })
19
-
20
- return { success: true, id: line.id, type: 'line' }
21
- }
22
-
23
- module.exports = addLine
@@ -1,63 +0,0 @@
1
- /**
2
- * 多边形元素
3
- */
4
-
5
- const paper = require('paper')
6
-
7
- /**
8
- * 添加多边形
9
- * 支持两种模式:
10
- * 1. 规则多边形: cx, cy, radius, sides
11
- * 2. 自定义多边形: points 数组 [[x1,y1], [x2,y2], ...]
12
- */
13
- function addPolygon(project, args) {
14
- const {
15
- cx, cy, radius, sides,
16
- points,
17
- fill, stroke, strokeWidth, opacity,
18
- x = 0, y = 0,
19
- } = args
20
-
21
- let polygon
22
-
23
- if (points && Array.isArray(points)) {
24
- // 使用自定义点创建多边形
25
- // 每个点应该是 [relativeX, relativeY],相对于 x, y 偏移
26
- const pathData = points.map((pt, i) => {
27
- const px = (Array.isArray(pt) ? pt[0] : pt) + x
28
- const py = (Array.isArray(pt) ? pt[1] : 0) + y
29
- return i === 0 ? [px, py] : [px, py]
30
- })
31
-
32
- polygon = new paper.Path({
33
- segments: pathData,
34
- closed: true,
35
- })
36
- } else if (cx !== undefined && cy !== undefined) {
37
- // 使用中心点和半径创建规则多边形
38
- polygon = new paper.Path.RegularPolygon({
39
- center: [cx, cy],
40
- radius: radius || 100,
41
- sides: sides || 6,
42
- })
43
- } else {
44
- throw new Error('Polygon requires either points array or cx/cy coordinates')
45
- }
46
-
47
- if (fill) {
48
- polygon.fillColor = new paper.Color(fill)
49
- } else {
50
- polygon.fillColor = null
51
- }
52
-
53
- if (stroke) {
54
- polygon.strokeColor = new paper.Color(stroke)
55
- polygon.strokeWidth = strokeWidth || 1
56
- }
57
-
58
- if (opacity !== undefined) polygon.opacity = opacity
59
-
60
- return { success: true, id: polygon.id, type: 'polygon' }
61
- }
62
-
63
- module.exports = addPolygon
@@ -1,32 +0,0 @@
1
- /**
2
- * 矩形元素
3
- */
4
-
5
- const paper = require('paper')
6
-
7
- /**
8
- * 添加矩形
9
- */
10
- function addRectangle(project, args) {
11
- const {
12
- x, y, width, height,
13
- fill, stroke, strokeWidth, radius, opacity,
14
- } = args
15
-
16
- const rect = new paper.Path.Rectangle({
17
- point: [x, y],
18
- size: [width, height],
19
- radius: radius || 0,
20
- })
21
-
22
- if (fill) rect.fillColor = new paper.Color(fill)
23
- if (stroke) {
24
- rect.strokeColor = new paper.Color(stroke)
25
- rect.strokeWidth = strokeWidth || 1
26
- }
27
- if (opacity !== undefined) rect.opacity = opacity
28
-
29
- return { success: true, id: rect.id, type: 'rectangle' }
30
- }
31
-
32
- module.exports = addRectangle
@@ -1,283 +0,0 @@
1
- /**
2
- * 富文本组件 - 使用 @napi-rs/canvas 原生字体 API
3
- * 支持自动换行
4
- */
5
-
6
- const paper = require('paper')
7
- const {
8
- validateFont,
9
- getDefaultFontFamily,
10
- getFontFallbackChain,
11
- isEmojiFont
12
- } = require('../fonts')
13
-
14
- /**
15
- * 检测文本是否包含 emoji
16
- */
17
- function containsEmoji(text) {
18
- if (!text || typeof text !== 'string') return false
19
- const emojiRanges = [
20
- /\u{1F600}-\u{1F64F}/u,
21
- /\u{1F300}-\u{1F5FF}/u,
22
- /\u{1F680}-\u{1F6FF}/u,
23
- /\u{1F700}-\u{1F77F}/u,
24
- /\u{1F780}-\u{1F7FF}/u,
25
- /\u{1F800}-\u{1F8FF}/u,
26
- /\u{1F900}-\u{1F9FF}/u,
27
- /\u{1FA00}-\u{1FA6F}/u,
28
- /\u{1FA70}-\u{1FAFF}/u,
29
- /\u2600-\u26FF/u,
30
- /\u2700-\u27BF/u,
31
- ]
32
- for (const range of emojiRanges) {
33
- if (range.test(text)) return true
34
- }
35
- return false
36
- }
37
-
38
- /**
39
- * 检测文本是否包含中文
40
- */
41
- function containsChinese(text) {
42
- if (!text || typeof text !== 'string') return false
43
- return /[\u4e00-\u9fff]/.test(text)
44
- }
45
-
46
- /**
47
- * 获取适合的字体
48
- */
49
- function getFontForText(requestedFont, text) {
50
- const baseFont = validateFont(requestedFont) || getDefaultFontFamily()
51
- const chain = getFontFallbackChain(requestedFont || baseFont, text)
52
-
53
- if (chain.length === 1) {
54
- return chain[0]
55
- }
56
-
57
- return chain.join(', ')
58
- }
59
-
60
- /**
61
- * 手动实现文本自动换行
62
- */
63
- function wrapText(text, maxWidth, fontSize, font) {
64
- if (!maxWidth || maxWidth <= 0) return [text]
65
-
66
- const tempText = new paper.PointText({
67
- fontSize,
68
- fontFamily: font,
69
- })
70
-
71
- const lines = []
72
- const paragraphs = text.split('\n')
73
-
74
- for (const paragraph of paragraphs) {
75
- let currentLine = ''
76
-
77
- // 简单字符分割
78
- const chars = [...paragraph]
79
-
80
- for (const char of chars) {
81
- const testLine = currentLine + char
82
- tempText.content = testLine
83
- const testWidth = tempText.bounds.width
84
-
85
- if (testWidth > maxWidth && currentLine.length > 0) {
86
- lines.push(currentLine)
87
- currentLine = char
88
- } else {
89
- currentLine = testLine
90
- }
91
- }
92
-
93
- if (currentLine.length > 0) {
94
- lines.push(currentLine)
95
- }
96
- }
97
-
98
- tempText.remove()
99
- return lines
100
- }
101
-
102
- /**
103
- * 添加富文本
104
- */
105
- function addRichText(project, args) {
106
- const {
107
- x = 0,
108
- y = 0,
109
- width,
110
-
111
- text = '',
112
-
113
- fontSize = 48,
114
- fontFamily,
115
- fontWeight,
116
- fontStyle,
117
- italic = false,
118
- bold = false,
119
-
120
- underline = false,
121
- strikethrough = false,
122
-
123
- color = '#ffffff',
124
- backgroundColor,
125
- gradient,
126
-
127
- strokeColor,
128
- strokeWidth = 1,
129
-
130
- shadow,
131
-
132
- letterSpacing = 0,
133
- lineSpacing = 0,
134
- lineHeight,
135
-
136
- align = 'left',
137
-
138
- rotation = 0,
139
- scale,
140
-
141
- opacity = 1,
142
-
143
- wrap = true,
144
- } = args
145
-
146
- const font = getFontForText(fontFamily, text)
147
- const effectiveFontWeight = bold ? 'bold' : (fontWeight || 'normal')
148
- const effectiveFontStyle = italic ? 'italic' : (fontStyle || 'normal')
149
-
150
- const actualLineHeight = lineHeight || (fontSize + lineSpacing)
151
-
152
- // 文本换行
153
- let textLines = [text]
154
- if (wrap && width && width > 0) {
155
- textLines = wrapText(text, width - 10, fontSize, font)
156
- }
157
-
158
- // 创建组
159
- const group = new paper.Group()
160
-
161
- // 逐行创建文本
162
- textLines.forEach((lineText, index) => {
163
- const lineY = y + fontSize + index * actualLineHeight
164
-
165
- const textItem = new paper.PointText({
166
- point: [x, lineY],
167
- content: lineText,
168
- fontSize,
169
- fontFamily: font,
170
- fontWeight: effectiveFontWeight,
171
- fontStyle: effectiveFontStyle,
172
- fillColor: new paper.Color(color),
173
- justification: align,
174
- })
175
-
176
- if (letterSpacing !== 0) {
177
- textItem.letterSpacing = letterSpacing
178
- }
179
-
180
- if (underline || strikethrough) {
181
- textItem.decorations = []
182
- if (underline) textItem.decorations.push('underline')
183
- if (strikethrough) textItem.decorations.push('strikethrough')
184
- }
185
-
186
- if (strokeColor) {
187
- textItem.strokeColor = new paper.Color(strokeColor)
188
- textItem.strokeWidth = strokeWidth
189
- }
190
-
191
- if (shadow) {
192
- textItem.shadowColor = new paper.Color(shadow.color || '#000000')
193
- textItem.shadowBlur = shadow.blur || 5
194
- textItem.shadowOffset = new paper.Point(shadow.offsetX || 2, shadow.offsetY || 2)
195
- }
196
-
197
- if (opacity !== 1) {
198
- textItem.opacity = opacity
199
- }
200
-
201
- group.addChild(textItem)
202
- })
203
-
204
- // 渐变填充
205
- if (gradient && gradient.colors && gradient.colors.length > 0) {
206
- const colors = gradient.colors.map(c => new paper.Color(c))
207
- const bounds = group.bounds
208
-
209
- if (gradient.direction !== undefined) {
210
- const angle = gradient.direction * Math.PI / 180
211
- const diagonal = Math.sqrt(bounds.width ** 2 + bounds.height ** 2)
212
- group.fillColor = new paper.Color({
213
- gradient: { stops: colors },
214
- origin: new paper.Point(
215
- bounds.center.x - Math.cos(angle) * diagonal / 2,
216
- bounds.center.y - Math.sin(angle) * diagonal / 2
217
- ),
218
- destination: new paper.Point(
219
- bounds.center.x + Math.cos(angle) * diagonal / 2,
220
- bounds.center.y + Math.sin(angle) * diagonal / 2
221
- ),
222
- })
223
- } else {
224
- group.fillColor = new paper.Color({
225
- gradient: { stops: colors },
226
- origin: bounds.topLeft,
227
- destination: bounds.topRight,
228
- })
229
- }
230
-
231
- group.children.forEach(child => {
232
- if (child.fillColor) {
233
- child.fillColor = null
234
- }
235
- })
236
- }
237
-
238
- // 背景色
239
- let bgRect = null
240
- if (backgroundColor) {
241
- const padding = 10
242
- bgRect = new paper.Path.Rectangle({
243
- point: [group.bounds.left - padding, group.bounds.top - padding],
244
- size: [group.bounds.width + padding * 2, group.bounds.height + padding * 2],
245
- fillColor: new paper.Color(backgroundColor),
246
- radius: 4,
247
- })
248
- bgRect.sendToBack()
249
- }
250
-
251
- // 旋转
252
- if (rotation !== 0) {
253
- group.rotate(rotation, new paper.Point(x, y + fontSize))
254
- if (bgRect) bgRect.rotate(rotation, bgRect.bounds.center)
255
- }
256
-
257
- // 缩放
258
- if (scale !== undefined) {
259
- if (typeof scale === 'number') {
260
- group.scale(scale, scale, new paper.Point(x, y + fontSize))
261
- if (bgRect) bgRect.scale(scale, scale, bgRect.bounds.center)
262
- } else if (typeof scale === 'object') {
263
- const sx = scale.x || 1
264
- const sy = scale.y || sx
265
- group.scale(sx, sy, new paper.Point(x, y + fontSize))
266
- if (bgRect) bgRect.scale(sx, sy, bgRect.bounds.center)
267
- }
268
- }
269
-
270
- return {
271
- success: true,
272
- id: group.id,
273
- type: 'richText',
274
- bounds: {
275
- x: group.bounds.x,
276
- y: group.bounds.y,
277
- width: group.bounds.width,
278
- height: group.bounds.height,
279
- }
280
- }
281
- }
282
-
283
- module.exports = addRichText