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,71 +0,0 @@
1
- /**
2
- * 头像组件
3
- */
4
-
5
- const paper = require('paper')
6
-
7
- /**
8
- * 创建头像
9
- *
10
- * @param {Object} project - Paper.js 项目
11
- * @param {Object} canvas - 画布对象
12
- * @param {Object} args - 组件参数
13
- * @param {number} args.x - 圆心X坐标
14
- * @param {number} args.y - 圆心Y坐标
15
- * @param {number} args.size - 头像大小
16
- * @param {string} args.src - 图片路径(可选,不提供则显示首字母)
17
- * @param {string} args.initials - 首字母(无图片时显示)
18
- * @param {string} args.background - 背景色
19
- * @param {string} args.border - 边框颜色
20
- * @param {number} args.borderWidth - 边框宽度
21
- * @param {string} args.color - 文字颜色
22
- */
23
- function createAvatar(project, canvas, args) {
24
- const {
25
- x, y,
26
- size = 80,
27
- src,
28
- initials,
29
- background = '#6366f1',
30
- border,
31
- borderWidth = 0,
32
- color = '#ffffff',
33
- } = args
34
-
35
- const elements = []
36
- const radius = size / 2
37
-
38
- // 绘制圆形背景
39
- const circle = new paper.Path.Circle({
40
- center: [x, y],
41
- radius: radius,
42
- })
43
- circle.fillColor = new paper.Color(background)
44
-
45
- if (border) {
46
- circle.strokeColor = new paper.Color(border)
47
- circle.strokeWidth = borderWidth
48
- }
49
-
50
- elements.push({ type: 'circle', id: circle.id })
51
-
52
- // 如果没有图片,显示首字母
53
- if (!src && initials) {
54
- const text = new paper.PointText({
55
- point: [x, y + size / 6],
56
- content: initials.charAt(0).toUpperCase(),
57
- fontSize: size * 0.4,
58
- fillColor: new paper.Color(color),
59
- justification: 'center',
60
- })
61
- elements.push({ type: 'text', id: text.id })
62
- }
63
-
64
- return {
65
- success: true,
66
- elements,
67
- size,
68
- }
69
- }
70
-
71
- module.exports = createAvatar
@@ -1,85 +0,0 @@
1
- /**
2
- * 徽章/标签组件
3
- */
4
-
5
- const paper = require('paper')
6
-
7
- /**
8
- * 创建徽章组件
9
- *
10
- * @param {Object} project - Paper.js 项目
11
- * @param {Object} canvas - 画布对象
12
- * @param {Object} args - 组件参数
13
- * @param {number} args.x - X坐标(居中时使用)
14
- * @param {number} args.y - Y坐标
15
- * @param {string} args.text - 徽章文字
16
- * @param {string} args.background - 背景色
17
- * @param {string} args.color - 文字颜色
18
- * @param {string} args.border - 边框颜色
19
- * @param {number} args.fontSize - 字体大小
20
- * @param {string} args.align - 对齐方式: left, center, right
21
- * @param {number} args.padding - 内边距
22
- * @param {number} args.radius - 圆角半径
23
- */
24
- function createBadge(project, canvas, args) {
25
- const {
26
- x, y,
27
- text,
28
- background = '#007bff',
29
- color = '#ffffff',
30
- border,
31
- fontSize = 18,
32
- align = 'center',
33
- padding = 15,
34
- radius = 4,
35
- } = args
36
-
37
- const elements = []
38
-
39
- // 计算文字宽度(估算)
40
- const textWidth = text.length * fontSize * 0.6
41
- const badgeWidth = textWidth + padding * 2
42
- const badgeHeight = fontSize + padding * 2
43
-
44
- // 计算X位置
45
- let badgeX = x
46
- if (align === 'center') {
47
- badgeX = x - badgeWidth / 2
48
- } else if (align === 'right') {
49
- badgeX = x - badgeWidth
50
- }
51
-
52
- // 绘制徽章背景
53
- const badge = new paper.Path.Rectangle({
54
- point: [badgeX, y],
55
- size: [badgeWidth, badgeHeight],
56
- radius: radius,
57
- })
58
- badge.fillColor = new paper.Color(background)
59
-
60
- if (border) {
61
- badge.strokeColor = new paper.Color(border)
62
- badge.strokeWidth = 1
63
- }
64
-
65
- elements.push({ type: 'rectangle', id: badge.id })
66
-
67
- // 绘制文字
68
- const badgeText = new paper.PointText({
69
- point: [badgeX + badgeWidth / 2, y + badgeHeight / 2 + fontSize / 3],
70
- content: text,
71
- fontSize: fontSize,
72
- fillColor: new paper.Color(color),
73
- justification: 'center',
74
- })
75
- elements.push({ type: 'text', id: badgeText.id })
76
-
77
- return {
78
- success: true,
79
- elements,
80
- width: badgeWidth,
81
- height: badgeHeight,
82
- }
83
- }
84
-
85
- module.exports = createBadge
@@ -1,123 +0,0 @@
1
- /**
2
- * 条形码组件 - 静态图片
3
- */
4
-
5
- const paper = require('paper')
6
- const { loadImageAsRaster, downloadImage } = require('../utils/imageLoader')
7
- const { getFontFallbackChain, validateFont } = require('../fonts')
8
-
9
- /**
10
- * 创建条形码
11
- */
12
- async function createBarcode(project, args) {
13
- const {
14
- x = 0,
15
- y = 0,
16
- width = 300,
17
- height = 100,
18
- content = '1234567890',
19
- showText = true,
20
- textColor = '#000000',
21
- fontSize = 16,
22
- opacity = 1,
23
- } = args
24
-
25
- // 内容太短或像URL,回退到简单条形码
26
- if (content.length < 8 || content.startsWith('http')) {
27
- return createSimpleBarcode(project, { x, y, width, height, content, showText, textColor, fontSize, opacity })
28
- }
29
-
30
- try {
31
- const barcodeUrl = `https://api.qrserver.com/v1/create-qr-code/?size=${width}x${height}&data=${encodeURIComponent(content)}&format=png`
32
- const { raster } = await loadImageAsRaster(project, barcodeUrl, { x, y, width, height }, opacity)
33
- const items = [raster]
34
-
35
- // 文字
36
- if (showText) {
37
- const barcodeFont = getFontFallbackChain('monospace', content).join(', ')
38
- const textItem = new paper.PointText({
39
- point: [x + width / 2, y + height + fontSize + 5],
40
- content: content,
41
- fontSize,
42
- fontFamily: barcodeFont,
43
- fillColor: new paper.Color(textColor),
44
- justification: 'center',
45
- })
46
- if (opacity !== 1) textItem.opacity = opacity
47
- items.push(textItem)
48
- }
49
-
50
- return {
51
- success: true,
52
- type: 'barcode',
53
- items: items.map(i => i.id),
54
- }
55
- } catch (err) {
56
- // 回退到简单条形码
57
- return createSimpleBarcode(project, { x, y, width, height, content, showText, textColor, fontSize, opacity })
58
- }
59
- }
60
-
61
- /**
62
- * 创建简单的条形码(使用线条绘制)
63
- */
64
- function createSimpleBarcode(project, args) {
65
- const {
66
- x = 0,
67
- y = 0,
68
- width = 300,
69
- height = 80,
70
- content = '123456',
71
- color = '#000000',
72
- showText = true,
73
- textColor = '#000000',
74
- fontSize = 14,
75
- opacity = 1,
76
- } = args
77
-
78
- const items = []
79
- const barHeight = showText ? height - 25 : height
80
- const barWidth = width / (content.length * 15)
81
-
82
- // 生成简单的条形图案
83
- for (let i = 0; i < content.length; i++) {
84
- const charCode = content.charCodeAt(i)
85
- const density = (charCode % 3) + 1
86
-
87
- for (let d = 0; d < density; d++) {
88
- const isWide = (charCode + d) % 2 === 0
89
- const barW = isWide ? barWidth * 2 : barWidth
90
-
91
- const bar = new paper.Path.Rectangle({
92
- point: [x + (i * density + d) * barWidth, y],
93
- size: [barW * 0.8, barHeight],
94
- fillColor: new paper.Color(color),
95
- })
96
- if (opacity !== 1) bar.opacity = opacity
97
- items.push(bar)
98
- }
99
- }
100
-
101
- // 文字
102
- if (showText) {
103
- const simpleBarcodeFont = getFontFallbackChain('monospace', content).join(', ')
104
- const textItem = new paper.PointText({
105
- point: [x + width / 2, y + barHeight + fontSize + 3],
106
- content: content,
107
- fontSize,
108
- fontFamily: simpleBarcodeFont,
109
- fillColor: new paper.Color(textColor),
110
- justification: 'center',
111
- })
112
- if (opacity !== 1) textItem.opacity = opacity
113
- items.push(textItem)
114
- }
115
-
116
- return {
117
- success: true,
118
- type: 'barcode',
119
- items: items.map(i => i.id),
120
- }
121
- }
122
-
123
- module.exports = createBarcode
@@ -1,154 +0,0 @@
1
- /**
2
- * 对话气泡组件
3
- */
4
-
5
- const paper = require('paper')
6
- const { getFontFallbackChain, validateFont } = require('../fonts')
7
-
8
- /**
9
- * 创建对话气泡
10
- */
11
- function createBubble(project, args) {
12
- const {
13
- x = 0,
14
- y = 0,
15
- width = 300,
16
- height = 100,
17
- text = '',
18
- fontSize = 24,
19
- fontFamily,
20
- color = '#000000',
21
- backgroundColor = '#ffffff',
22
- borderColor,
23
- borderWidth = 1,
24
- radius = 20,
25
- tailDirection = 'bottom', // bottom, top, left, right
26
- tailPosition = 'left', // left, center, right
27
- shadow,
28
- opacity = 1,
29
- } = args
30
-
31
- const items = []
32
-
33
- // 气泡主体
34
- const bubbleX = tailDirection === 'left' ? x + 15 : x
35
- const bubbleY = tailDirection === 'top' ? y + 15 : y
36
- const bubbleWidth = tailDirection === 'left' ? width - 15 : width
37
- const bubbleHeight = tailDirection === 'top' ? height - 15 : height
38
-
39
- const bgOpts = {
40
- point: [bubbleX, bubbleY],
41
- size: [bubbleWidth, bubbleHeight],
42
- radius: radius,
43
- }
44
-
45
- if (borderColor) {
46
- bgOpts.strokeColor = new paper.Color(borderColor)
47
- bgOpts.strokeWidth = borderWidth
48
- }
49
-
50
- const bg = new paper.Path.Rectangle(bgOpts)
51
- bg.fillColor = new paper.Color(backgroundColor)
52
-
53
- if (shadow) {
54
- bg.shadowColor = new paper.Color(shadow.color || '#000000')
55
- bg.shadowBlur = shadow.blur || 10
56
- bg.shadowOffset = new paper.Point(shadow.offsetX || 3, shadow.offsetY || 3)
57
- }
58
-
59
- if (opacity !== 1) bg.opacity = opacity
60
- items.push(bg)
61
-
62
- // 气泡尾巴
63
- const tailSize = 20
64
- let tailX, tailY, tailRotation
65
-
66
- // 计算尾巴位置
67
- switch (tailDirection) {
68
- case 'bottom':
69
- tailY = bubbleY + bubbleHeight - 5
70
- if (tailPosition === 'left') tailX = bubbleX + 30
71
- else if (tailPosition === 'right') tailX = bubbleX + bubbleWidth - 30
72
- else tailX = bubbleX + bubbleWidth / 2
73
- tailRotation = 0
74
- break
75
- case 'top':
76
- tailY = bubbleY + 5
77
- if (tailPosition === 'left') tailX = bubbleX + 30
78
- else if (tailPosition === 'right') tailX = bubbleX + bubbleWidth - 30
79
- else tailX = bubbleX + bubbleWidth / 2
80
- tailRotation = 180
81
- break
82
- case 'left':
83
- tailX = bubbleX + 5
84
- if (tailPosition === 'left') tailY = bubbleY + 30
85
- else if (tailPosition === 'right') tailY = bubbleY + bubbleHeight - 30
86
- else tailY = bubbleY + bubbleHeight / 2
87
- tailRotation = 90
88
- break
89
- case 'right':
90
- tailX = bubbleX + bubbleWidth - 5
91
- if (tailPosition === 'left') tailY = bubbleY + 30
92
- else if (tailPosition === 'right') tailY = bubbleY + bubbleHeight - 30
93
- else tailY = bubbleY + bubbleHeight / 2
94
- tailRotation = 270
95
- break
96
- }
97
-
98
- const tail = new paper.Path()
99
- tail.add(new paper.Point(tailX - tailSize, tailY))
100
- tail.add(new paper.Point(tailX, tailY + tailSize * 0.7))
101
- tail.add(new paper.Point(tailX, tailY - tailSize * 0.7))
102
- tail.closed = true
103
- tail.fillColor = new paper.Color(backgroundColor)
104
- if (borderColor) {
105
- tail.strokeColor = new paper.Color(borderColor)
106
- tail.strokeWidth = borderWidth
107
- }
108
- tail.rotate(tailRotation, new paper.Point(tailX, tailY))
109
-
110
- if (opacity !== 1) tail.opacity = opacity
111
- items.push(tail)
112
-
113
- // 文字
114
- const padding = 25
115
- const textItem = new paper.PointText({
116
- point: [bubbleX + padding, bubbleY + bubbleHeight / 2 + fontSize / 3],
117
- content: text,
118
- fontSize,
119
- fontFamily: getFontFallbackChain(fontFamily, text).join(', '),
120
- fillColor: new paper.Color(color),
121
- justification: tailPosition === 'left' ? 'left' : tailPosition === 'right' ? 'right' : 'center',
122
- })
123
-
124
- // 限制文字宽度
125
- const maxTextWidth = bubbleWidth - padding * 2
126
- if (textItem.bounds.width > maxTextWidth) {
127
- textItem.justification = 'left'
128
- const charsPerLine = Math.floor((text.length * maxTextWidth) / textItem.bounds.width)
129
- // 简单换行处理
130
- let lines = []
131
- let currentLine = ''
132
- for (const char of text) {
133
- currentLine += char
134
- const testText = new paper.PointText({ content: currentLine, fontSize, fontFamily: getFontFallbackChain(fontFamily, currentLine).join(', ') })
135
- if (testText.bounds.width > maxTextWidth) {
136
- lines.push(currentLine.slice(0, -1))
137
- currentLine = char
138
- }
139
- }
140
- if (currentLine) lines.push(currentLine)
141
- textItem.content = lines.join('\n')
142
- }
143
-
144
- if (opacity !== 1) textItem.opacity = opacity
145
- items.push(textItem)
146
-
147
- return {
148
- success: true,
149
- type: 'bubble',
150
- items: items.map(i => i.id),
151
- }
152
- }
153
-
154
- module.exports = createBubble
@@ -1,168 +0,0 @@
1
- /**
2
- * 按钮组件
3
- */
4
-
5
- const paper = require('paper')
6
- const { loadImageAsRaster } = require('../utils/imageLoader')
7
- const { getFontFallbackChain, validateFont } = require('../fonts')
8
-
9
- /**
10
- * 创建按钮
11
- */
12
- async function createButton(project, args) {
13
- const {
14
- x = 0,
15
- y = 0,
16
- width: customWidth, // 重命名为 customWidth
17
- height = 60,
18
- text = '按钮',
19
- fontSize = 24,
20
- fontFamily,
21
- color = '#ffffff',
22
- backgroundColor = '#3b82f6',
23
- borderColor,
24
- borderWidth = 0,
25
- radius = 8,
26
- shadow,
27
- gradient,
28
- icon,
29
- iconPosition = 'left',
30
- opacity = 1,
31
- padding = 30, // 内边距
32
- } = args
33
-
34
- // 使用字符数估算文本宽度(参考 CTA 组件的方式)
35
- const textStr = String(text || '')
36
- const chineseChars = (textStr.match(/[\u4e00-\u9fa5]/g) || []).length
37
- const otherChars = textStr.length - chineseChars
38
- // 中文约1.0倍,英文/数字约0.5倍字体大小
39
- const textWidth = chineseChars * fontSize * 1.0 + otherChars * fontSize * 0.5
40
-
41
- // 图标宽度
42
- const iconWidth = icon ? Math.min(height * 0.5, fontSize) + 8 : 0
43
-
44
- // 计算最终宽度:如果没有指定宽度,则根据内容计算
45
- const finalWidth = customWidth || (textWidth + padding * 2 + iconWidth)
46
-
47
- // 创建按钮背景
48
- const bg = new paper.Path.Rectangle({
49
- point: [x, y],
50
- size: [finalWidth, height],
51
- radius: radius,
52
- })
53
-
54
- // 边框
55
- if (borderColor) {
56
- bg.strokeColor = new paper.Color(borderColor)
57
- bg.strokeWidth = borderWidth
58
- }
59
-
60
- // 渐变或纯色填充
61
- if (gradient && gradient.colors && gradient.colors.length > 1) {
62
- const colors = gradient.colors.map(c => new paper.Color(c))
63
- bg.fillColor = new paper.Color({
64
- gradient: { stops: colors },
65
- origin: bg.bounds.topLeft,
66
- destination: bg.bounds.bottomLeft,
67
- })
68
- } else {
69
- bg.fillColor = new paper.Color(backgroundColor)
70
- }
71
-
72
- // 阴影
73
- if (shadow && typeof shadow === 'object') {
74
- try {
75
- if (shadow.color) bg.shadowColor = new paper.Color(shadow.color)
76
- bg.shadowBlur = shadow.blur || 10
77
- bg.shadowOffset = new paper.Point(shadow.offsetX || 0, shadow.offsetY || 4)
78
- } catch (e) {
79
- // 忽略阴影错误
80
- }
81
- }
82
-
83
- if (opacity !== 1) {
84
- bg.opacity = opacity
85
- }
86
-
87
- if (project && project.activeLayer) {
88
- project.activeLayer.addChild(bg)
89
- }
90
-
91
- const elements = [{ type: 'rectangle', id: bg.id }]
92
-
93
- // 文字居中 x 坐标
94
- const textX = x + finalWidth / 2
95
-
96
- // 添加图标
97
- if (icon) {
98
- const iconSize = Math.min(height * 0.5, fontSize)
99
- const iconY = y + height / 2 + iconSize / 3
100
-
101
- if (icon.startsWith('http') || icon.startsWith('data:')) {
102
- // URL图片图标
103
- const iconX = iconPosition === 'left'
104
- ? x + padding
105
- : x + finalWidth - padding - iconSize
106
-
107
- const { raster } = await loadImageAsRaster(project, icon, {
108
- x: iconX,
109
- y: y + (height - iconSize) / 2,
110
- width: iconSize,
111
- height: iconSize
112
- }, opacity)
113
-
114
- if (project && project.activeLayer) {
115
- project.activeLayer.addChild(raster)
116
- }
117
- elements.push({ type: 'raster', id: raster.id })
118
- } else {
119
- // Emoji 或文本图标
120
- const iconX = iconPosition === 'left'
121
- ? x + padding + iconSize / 2
122
- : x + finalWidth - padding - iconSize / 2
123
-
124
- const iconText = new paper.PointText({
125
- point: [iconX, iconY],
126
- content: icon,
127
- fontSize: iconSize,
128
- justification: 'center',
129
- })
130
- if (opacity !== 1) iconText.opacity = opacity
131
-
132
- if (project && project.activeLayer) {
133
- project.activeLayer.addChild(iconText)
134
- }
135
- elements.push({ type: 'text', id: iconText.id })
136
- }
137
- }
138
-
139
- // 添加文字
140
- const textY = y + height / 2 + fontSize / 3
141
- const buttonText = new paper.PointText({
142
- point: [textX, textY],
143
- content: textStr,
144
- fontSize: fontSize,
145
- fontFamily: getFontFallbackChain(fontFamily, textStr).join(', '),
146
- fillColor: new paper.Color(color),
147
- justification: 'center',
148
- })
149
-
150
- if (opacity !== 1) {
151
- buttonText.opacity = opacity
152
- }
153
-
154
- if (project && project.activeLayer) {
155
- project.activeLayer.addChild(buttonText)
156
- }
157
- elements.push({ type: 'text', id: buttonText.id })
158
-
159
- return {
160
- success: true,
161
- type: 'button',
162
- elements,
163
- width: finalWidth,
164
- height: height,
165
- }
166
- }
167
-
168
- module.exports = createButton
@@ -1,88 +0,0 @@
1
- /**
2
- * 卡片组件
3
- */
4
-
5
- const paper = require('paper')
6
-
7
- /**
8
- * 创建卡片组件
9
- *
10
- * @param {Object} project - Paper.js 项目
11
- * @param {Object} canvas - 画布对象
12
- * @param {Object} args - 组件参数
13
- * @param {number} args.x - 卡片X坐标
14
- * @param {number} args.y - 卡片Y坐标
15
- * @param {number} args.width - 卡片宽度
16
- * @param {number} args.height - 卡片高度
17
- * @param {string} args.background - 背景色
18
- * @param {string} args.border - 边框颜色
19
- * @param {number} args.borderWidth - 边框宽度
20
- * @param {number} args.radius - 圆角半径
21
- * @param {string} args.title - 标题文字
22
- * @param {number} args.titleSize - 标题字体大小
23
- * @param {string} args.titleColor - 标题颜色
24
- * @param {string} args.subtitle - 副标题
25
- * @param {number} args.subtitleSize - 副标题字体大小
26
- * @param {string} args.subtitleColor - 副标题颜色
27
- * @param {number} args.padding - 内边距
28
- */
29
- function createCard(project, canvas, args) {
30
- const {
31
- x, y, width, height,
32
- background, border, borderWidth, radius,
33
- title, titleSize, titleColor,
34
- subtitle, subtitleSize, subtitleColor,
35
- padding = 20,
36
- } = args
37
-
38
- const elements = []
39
-
40
- // 绘制卡片背景
41
- const card = new paper.Path.Rectangle({
42
- point: [x, y],
43
- size: [width, height],
44
- radius: radius || 0,
45
- })
46
-
47
- if (background) {
48
- card.fillColor = new paper.Color(background)
49
- } else {
50
- card.fillColor = new paper.Color('#ffffff')
51
- }
52
-
53
- if (border) {
54
- card.strokeColor = new paper.Color(border)
55
- card.strokeWidth = borderWidth || 1
56
- }
57
-
58
- elements.push({ type: 'rectangle', id: card.id })
59
-
60
- // 绘制标题
61
- if (title) {
62
- const titleText = new paper.PointText({
63
- point: [x + padding, y + padding + (titleSize || 24)],
64
- content: title,
65
- fontSize: titleSize || 24,
66
- fillColor: new paper.Color(titleColor || '#000000'),
67
- justification: 'left',
68
- })
69
- elements.push({ type: 'text', id: titleText.id })
70
- }
71
-
72
- // 绘制副标题
73
- if (subtitle) {
74
- const titleHeight = title ? (titleSize || 24) + padding : padding
75
- const subtitleText = new paper.PointText({
76
- point: [x + padding, y + titleHeight + (subtitleSize || 16) + 10],
77
- content: subtitle,
78
- fontSize: subtitleSize || 16,
79
- fillColor: new paper.Color(subtitleColor || '#666666'),
80
- justification: 'left',
81
- })
82
- elements.push({ type: 'text', id: subtitleText.id })
83
- }
84
-
85
- return { success: true, elements }
86
- }
87
-
88
- module.exports = createCard