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,117 +0,0 @@
1
- /**
2
- * 环形进度条组件
3
- */
4
-
5
- const paper = require('paper')
6
-
7
- /**
8
- * 创建环形进度条组件
9
- */
10
- function createProgressCircle(project, canvas, params) {
11
- const {
12
- cx,
13
- cy,
14
- radius,
15
- value,
16
- strokeWidth = 10,
17
- trackColor = '#e5e7eb',
18
- fillColor = '#3b82f6',
19
- backgroundColor,
20
- showLabel = true,
21
- labelColor,
22
- startAngle = -90
23
- } = params
24
-
25
- const elements = []
26
-
27
- // 绘制背景圆(可选)
28
- if (backgroundColor) {
29
- const bgCircle = new paper.Path.Circle({
30
- center: [cx, cy],
31
- radius: radius + strokeWidth / 2
32
- })
33
- bgCircle.fillColor = new paper.Color(backgroundColor)
34
- if (project && project.activeLayer) {
35
- project.activeLayer.addChild(bgCircle)
36
- }
37
- elements.push({ type: 'path', id: bgCircle.id })
38
- }
39
-
40
- // 绘制轨道(背景环)
41
- const trackCircle = new paper.Path.Circle({
42
- center: [cx, cy],
43
- radius: radius
44
- })
45
- trackCircle.fillColor = null
46
- trackCircle.strokeColor = new paper.Color(trackColor)
47
- trackCircle.strokeWidth = strokeWidth
48
- if (project && project.activeLayer) {
49
- project.activeLayer.addChild(trackCircle)
50
- }
51
- elements.push({ type: 'path', id: trackCircle.id })
52
-
53
- // 绘制进度弧线
54
- if (value > 0 && value <= 100) {
55
- const percentage = value / 100
56
- const arcAngle = percentage * 360
57
-
58
- // 转换为弧度
59
- const startRad = startAngle * Math.PI / 180
60
- const endRad = (startAngle + arcAngle) * Math.PI / 180
61
-
62
- // 创建进度弧线路径
63
- const progressArc = new paper.Path()
64
-
65
- // 添加起点
66
- progressArc.moveTo(
67
- cx + radius * Math.cos(startRad),
68
- cy + radius * Math.sin(startRad)
69
- )
70
-
71
- // 添加弧线上的点(用多个点模拟圆弧)
72
- const segments = 36
73
- const angleStep = (endRad - startRad) / segments
74
- for (let i = 1; i <= segments; i++) {
75
- const angle = startRad + angleStep * i
76
- progressArc.lineTo(
77
- cx + radius * Math.cos(angle),
78
- cy + radius * Math.sin(angle)
79
- )
80
- }
81
-
82
- progressArc.strokeColor = new paper.Color(fillColor)
83
- progressArc.strokeWidth = strokeWidth
84
- progressArc.strokeCap = 'round'
85
-
86
- if (project && project.activeLayer) {
87
- project.activeLayer.addChild(progressArc)
88
- }
89
- elements.push({ type: 'path', id: progressArc.id })
90
- }
91
-
92
- // 绘制标签文字
93
- if (showLabel) {
94
- const textColor = labelColor || fillColor
95
- const fontSize = Math.min(Math.max(Math.round(radius * 0.35), 12), 48)
96
- const label = new paper.PointText({
97
- point: [cx, cy + fontSize * 0.35],
98
- content: `${Math.round(value)}%`,
99
- fontSize: fontSize,
100
- fillColor: new paper.Color(textColor),
101
- justification: 'center',
102
- fontWeight: 'bold'
103
- })
104
- if (project && project.activeLayer) {
105
- project.activeLayer.addChild(label)
106
- }
107
- elements.push({ type: 'text', id: label.id })
108
- }
109
-
110
- return {
111
- success: true,
112
- elements,
113
- type: 'progressCircle'
114
- }
115
- }
116
-
117
- module.exports = createProgressCircle
@@ -1,74 +0,0 @@
1
- /**
2
- * 二维码组件 - 本地生成
3
- */
4
-
5
- const paper = require('paper')
6
- const QRCode = require('qrcode')
7
-
8
- /**
9
- * 创建二维码
10
- */
11
- async function createQRCode(project, args) {
12
- const {
13
- x = 0,
14
- y = 0,
15
- size = 200,
16
- content = '',
17
- color = '#000000',
18
- backgroundColor = '#ffffff',
19
- logo,
20
- logoSize,
21
- opacity = 1,
22
- } = args
23
-
24
- try {
25
- // 生成 QR 码图片
26
- const qrDataUrl = await QRCode.toDataURL(content, {
27
- width: size,
28
- margin: 2,
29
- color: {
30
- dark: color,
31
- light: backgroundColor,
32
- },
33
- })
34
-
35
- // 使用 imageLoader 加载
36
- const { loadImageAsRaster } = require('../utils/imageLoader')
37
- const { raster } = await loadImageAsRaster(project, qrDataUrl, { x, y, width: size, height: size }, opacity)
38
- const items = [raster]
39
-
40
- // 添加logo
41
- if (logo) {
42
- const ls = logoSize || size * 0.2
43
- const { raster: logoRaster } = await loadImageAsRaster(project, logo, {
44
- x: x + (size - ls) / 2,
45
- y: y + (size - ls) / 2,
46
- width: ls,
47
- height: ls
48
- }, opacity)
49
-
50
- // 添加白色背景
51
- const logoBg = new paper.Path.Rectangle({
52
- point: [x + (size - ls) / 2 - 5, y + (size - ls) / 2 - 5],
53
- size: [ls + 10, ls + 10],
54
- fillColor: new paper.Color(backgroundColor),
55
- radius: 4,
56
- })
57
- logoBg.sendToBack()
58
- items.push(logoRaster)
59
- }
60
-
61
- return {
62
- success: true,
63
- type: 'qrcode',
64
- items: items.map(i => i.id),
65
- }
66
- } catch (err) {
67
- return {
68
- success: false,
69
- error: `Failed to generate QR code: ${err.message}`,
70
- }
71
- }
72
- }
73
-
74
- module.exports = createQRCode
@@ -1,169 +0,0 @@
1
- /**
2
- * 引用块组件 - 支持自动换行
3
- */
4
-
5
- const paper = require('paper')
6
- const { getFontFallbackChain } = require('../fonts')
7
-
8
- /**
9
- * 手动实现文本自动换行
10
- */
11
- function wrapText(text, maxWidth, fontSize, font) {
12
- if (!maxWidth || maxWidth <= 0) return [text]
13
-
14
- const tempText = new paper.PointText({
15
- fontSize,
16
- fontFamily: font,
17
- })
18
-
19
- const lines = []
20
- const paragraphs = text.split('\n')
21
-
22
- for (let p = 0; p < paragraphs.length; p++) {
23
- let currentLine = ''
24
- const paragraph = paragraphs[p]
25
- let i = 0
26
-
27
- while (i < paragraph.length) {
28
- // 尝试获取下一个字符
29
- let char = paragraph[i]
30
- let testLine = currentLine + char
31
-
32
- tempText.content = testLine
33
- let testWidth = tempText.bounds.width
34
-
35
- // 如果加上下一个字符超过宽度
36
- if (testWidth > maxWidth && currentLine.length > 0) {
37
- lines.push(currentLine)
38
- currentLine = char
39
- } else {
40
- currentLine = testLine
41
- }
42
- i++
43
- }
44
-
45
- if (currentLine.length > 0) {
46
- lines.push(currentLine)
47
- }
48
- }
49
-
50
- tempText.remove()
51
- return lines
52
- }
53
-
54
- /**
55
- * 创建引用块
56
- *
57
- * @param {Object} project - Paper.js 项目
58
- * @param {Object} canvas - 画布对象
59
- * @param {Object} args - 组件参数
60
- * @param {number} args.x - X坐标
61
- * @param {number} args.y - Y坐标
62
- * @param {number} args.width - 宽度
63
- * @param {string} args.text - 引用文字
64
- * @param {string} args.author - 作者
65
- * @param {string} args.background - 背景色
66
- * @param {string} args.borderColor - 左边框颜色
67
- * @param {number} args.borderWidth - 左边框宽度
68
- * @param {number} args.padding - 内边距
69
- * @param {number} args.radius - 圆角半径
70
- * @param {string} args.textColor - 文字颜色
71
- * @param {string} args.authorColor - 作者颜色
72
- * @param {number} args.fontSize - 字体大小
73
- */
74
- function createQuote(project, canvas, args) {
75
- const {
76
- x, y,
77
- width = 400,
78
- text,
79
- author,
80
- background = '#f8fafc',
81
- borderColor = '#6366f1',
82
- borderWidth = 4,
83
- padding = 20,
84
- radius = 8,
85
- textColor = '#1e293b',
86
- authorColor = '#64748b',
87
- fontSize = 18,
88
- fontFamily,
89
- } = args
90
-
91
- // 获取字体回退链
92
- const quoteFont = getFontFallbackChain(fontFamily, text || '').join(', ')
93
-
94
- const elements = []
95
-
96
- // 计算文本换行
97
- const textPadding = padding + 30 // 左边距 + 引号宽度
98
- const maxTextWidth = width - textPadding - padding
99
- const textLines = wrapText(text, maxTextWidth, fontSize, quoteFont)
100
- const lineHeight = fontSize * 1.5
101
- const textBlockHeight = textLines.length * lineHeight
102
-
103
- // 计算背景高度
104
- const authorHeight = author ? fontSize * 1.5 : 0
105
- const totalHeight = padding * 2 + textBlockHeight + authorHeight
106
- const minHeight = 80
107
- const finalHeight = Math.max(totalHeight, minHeight)
108
-
109
- // 绘制背景
110
- const bg = new paper.Path.Rectangle({
111
- point: [x, y],
112
- size: [width, finalHeight],
113
- radius: radius,
114
- })
115
- bg.fillColor = new paper.Color(background)
116
- elements.push({ type: 'rectangle', id: bg.id })
117
-
118
- // 绘制左边框
119
- const border = new paper.Path.Rectangle({
120
- point: [x, y],
121
- size: [borderWidth, finalHeight],
122
- })
123
- border.fillColor = new paper.Color(borderColor)
124
- elements.push({ type: 'rectangle', id: border.id })
125
-
126
- // 绘制引用符号
127
- const quoteMark = new paper.PointText({
128
- point: [x + padding + 10, y + padding + fontSize],
129
- content: '"',
130
- fontSize: fontSize * 2,
131
- fontFamily: quoteFont,
132
- fillColor: new paper.Color(borderColor),
133
- justification: 'left',
134
- })
135
- elements.push({ type: 'text', id: quoteMark.id })
136
-
137
- // 绘制引用文字(多行)
138
- textLines.forEach((line, index) => {
139
- const lineY = y + padding + fontSize + index * lineHeight
140
- const quoteText = new paper.PointText({
141
- point: [x + padding + 30, lineY],
142
- content: line,
143
- fontSize: fontSize,
144
- fontFamily: quoteFont,
145
- fillColor: new paper.Color(textColor),
146
- justification: 'left',
147
- })
148
- elements.push({ type: 'text', id: quoteText.id })
149
- })
150
-
151
- // 绘制作者
152
- if (author) {
153
- const authorY = y + padding + textBlockHeight + fontSize * 1.3
154
- const authorFont = getFontFallbackChain(fontFamily, author).join(', ')
155
- const authorText = new paper.PointText({
156
- point: [x + padding, authorY],
157
- content: `— ${author}`,
158
- fontSize: fontSize * 0.85,
159
- fontFamily: authorFont,
160
- fillColor: new paper.Color(authorColor),
161
- justification: 'left',
162
- })
163
- elements.push({ type: 'text', id: authorText.id })
164
- }
165
-
166
- return { success: true, elements }
167
- }
168
-
169
- module.exports = createQuote
@@ -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 {number} args.value - 评分值 0-5
16
- * @param {number} args.max - 最大值,默认5
17
- * @param {number} args.size - 星星大小
18
- * @param {string} args.filledColor - 填充颜色
19
- * @param {string} args.emptyColor - 空心颜色
20
- * @param {number} args.gap - 星星间距
21
- */
22
- function createRating(project, canvas, args) {
23
- const {
24
- x, y,
25
- value = 4,
26
- max = 5,
27
- size = 24,
28
- filledColor = '#fbbf24',
29
- emptyColor = '#e5e7eb',
30
- gap = 4,
31
- } = args
32
-
33
- const elements = []
34
-
35
- for (let i = 0; i < max; i++) {
36
- const starX = x + i * (size + gap)
37
- const filled = i < Math.floor(value)
38
- const partial = !filled && i < value
39
-
40
- // 绘制星星(使用多边形)
41
- const star = createStar(project, starX + size / 2, y + size / 2, size / 2, size / 4, 5)
42
- star.fillColor = new paper.Color(partial ? filledColor : emptyColor)
43
- star.opacity = partial ? value - Math.floor(value) : 1
44
- elements.push({ type: 'polygon', id: star.id })
45
-
46
- if (partial) {
47
- // 半星效果用填充色覆盖一半
48
- const halfStar = createStar(project, starX + size / 2, y + size / 2, size / 2, size / 4, 5)
49
- const clipPath = new paper.Path.Rectangle({
50
- point: [starX, y],
51
- size: [size / 2, size],
52
- })
53
- halfStar.fillColor = new paper.Color(filledColor)
54
- halfStar.opacity = 1
55
- elements.push({ type: 'polygon', id: halfStar.id })
56
- }
57
- }
58
-
59
- return {
60
- success: true,
61
- elements,
62
- value,
63
- }
64
- }
65
-
66
- /**
67
- * 创建星星形状
68
- */
69
- function createStar(project, cx, cy, outerRadius, innerRadius, points) {
70
- const star = new paper.Path()
71
- const step = Math.PI / points
72
-
73
- for (let i = 0; i < 2 * points; i++) {
74
- const radius = i % 2 === 0 ? outerRadius : innerRadius
75
- const angle = i * step - Math.PI / 2
76
- const x = cx + Math.cos(angle) * radius
77
- const y = cy + Math.sin(angle) * radius
78
- star.add(new paper.Point(x, y))
79
- }
80
-
81
- star.closed = true
82
- return star
83
- }
84
-
85
- module.exports = createRating
@@ -1,197 +0,0 @@
1
- /**
2
- * 丝带/飘带组件
3
- */
4
-
5
- const paper = require('paper')
6
- const { getFontFallbackChain, validateFont } = require('../fonts')
7
-
8
- /**
9
- * 创建丝带
10
- */
11
- function createRibbon(project, args) {
12
- const {
13
- x = 0,
14
- y = 0,
15
- width = 300,
16
- text = '',
17
- fontSize = 28,
18
- fontFamily,
19
- color = '#ffffff',
20
- backgroundColor = '#e74c3c',
21
- borderColor,
22
- borderWidth = 2,
23
- shadow,
24
- position = 'top', // top, bottom, left, right
25
- style = 'fold', // fold, diagonal, corner
26
- opacity = 1,
27
- } = args
28
-
29
- const items = []
30
-
31
- // 获取字体回退链
32
- const ribbonFont = getFontFallbackChain(fontFamily, text).join(', ')
33
-
34
- if (style === 'diagonal') {
35
- // 对角丝带
36
- const diagonalLength = Math.sqrt(width ** 2 + 60 ** 2)
37
- const angle = Math.atan2(60, width) * 180 / Math.PI
38
-
39
- const ribbon = new paper.Path.Rectangle({
40
- point: [x, y],
41
- size: [diagonalLength, 60],
42
- radius: 4,
43
- fillColor: new paper.Color(backgroundColor),
44
- })
45
- ribbon.rotate(angle, new paper.Point(x, y))
46
-
47
- if (borderColor) {
48
- ribbon.strokeColor = new paper.Color(borderColor)
49
- ribbon.strokeWidth = borderWidth
50
- }
51
-
52
- if (shadow) {
53
- ribbon.shadowColor = new paper.Color(shadow.color || '#000000')
54
- ribbon.shadowBlur = shadow.blur || 8
55
- ribbon.shadowOffset = new paper.Point(shadow.offsetX || 3, shadow.offsetY || 3)
56
- }
57
-
58
- if (opacity !== 1) ribbon.opacity = opacity
59
- items.push(ribbon)
60
-
61
- // 文字
62
- const textItem = new paper.PointText({
63
- point: [x + diagonalLength / 2, y + 60 / 2 + fontSize / 3],
64
- content: text,
65
- fontSize,
66
- fontFamily: ribbonFont,
67
- fillColor: new paper.Color(color),
68
- justification: 'center',
69
- })
70
- textItem.rotate(angle, new paper.Point(x + diagonalLength / 2, y + 60 / 2))
71
-
72
- if (opacity !== 1) textItem.opacity = opacity
73
- items.push(textItem)
74
-
75
- } else if (style === 'corner') {
76
- // 角落丝带
77
- const ribbonWidth = width
78
- const ribbonHeight = 50
79
-
80
- // 主丝带
81
- const ribbon = new paper.Path.Rectangle({
82
- point: [x, y],
83
- size: [ribbonWidth, ribbonHeight],
84
- fillColor: new paper.Color(backgroundColor),
85
- })
86
-
87
- if (borderColor) {
88
- ribbon.strokeColor = new paper.Color(borderColor)
89
- ribbon.strokeWidth = borderWidth
90
- }
91
-
92
- if (shadow) {
93
- ribbon.shadowColor = new paper.Color(shadow.color || '#000000')
94
- ribbon.shadowBlur = shadow.blur || 8
95
- ribbon.shadowOffset = new paper.Point(shadow.offsetX || 3, shadow.offsetY || 3)
96
- }
97
-
98
- if (opacity !== 1) ribbon.opacity = opacity
99
- items.push(ribbon)
100
-
101
- // 折叠部分
102
- const foldSize = 20
103
- const fold = new paper.Path()
104
- fold.add(new paper.Point(x, y + ribbonHeight))
105
- fold.add(new paper.Point(x, y + ribbonHeight + foldSize))
106
- fold.add(new paper.Point(x + foldSize, y + ribbonHeight))
107
- fold.closed = true
108
- fold.fillColor = new paper.Color(backgroundColor).multiply(0.8)
109
-
110
- if (borderColor) {
111
- fold.strokeColor = new paper.Color(borderColor)
112
- fold.strokeWidth = borderWidth
113
- }
114
-
115
- if (opacity !== 1) fold.opacity = opacity
116
- items.push(fold)
117
-
118
- // 文字
119
- const cornerTextItem = new paper.PointText({
120
- point: [x + ribbonWidth / 2, y + ribbonHeight / 2 + fontSize / 3],
121
- content: text,
122
- fontSize,
123
- fontFamily: ribbonFont,
124
- fillColor: new paper.Color(color),
125
- justification: 'center',
126
- })
127
-
128
- if (opacity !== 1) cornerTextItem.opacity = opacity
129
- items.push(cornerTextItem)
130
-
131
- } else {
132
- // 折叠丝带 (默认)
133
- const ribbonHeight = 50
134
-
135
- // 主丝带
136
- const ribbon = new paper.Path.Rectangle({
137
- point: [x, y],
138
- size: [width, ribbonHeight],
139
- fillColor: new paper.Color(backgroundColor),
140
- })
141
-
142
- if (borderColor) {
143
- ribbon.strokeColor = new paper.Color(borderColor)
144
- ribbon.strokeWidth = borderWidth
145
- }
146
-
147
- if (shadow) {
148
- ribbon.shadowColor = new paper.Color(shadow.color || '#000000')
149
- ribbon.shadowBlur = shadow.blur || 8
150
- ribbon.shadowOffset = new paper.Point(shadow.offsetX || 3, shadow.offsetY || 3)
151
- }
152
-
153
- if (opacity !== 1) ribbon.opacity = opacity
154
- items.push(ribbon)
155
-
156
- // 左右折叠三角
157
- const foldSize = 15
158
- const leftFold = new paper.Path()
159
- leftFold.add(new paper.Point(x, y))
160
- leftFold.add(new paper.Point(x - foldSize, y - foldSize))
161
- leftFold.add(new paper.Point(x, y - foldSize))
162
- leftFold.closed = true
163
- leftFold.fillColor = new paper.Color(backgroundColor).multiply(0.8)
164
- if (opacity !== 1) leftFold.opacity = opacity
165
- items.push(leftFold)
166
-
167
- const rightFold = new paper.Path()
168
- rightFold.add(new paper.Point(x + width, y))
169
- rightFold.add(new paper.Point(x + width + foldSize, y - foldSize))
170
- rightFold.add(new paper.Point(x + width, y - foldSize))
171
- rightFold.closed = true
172
- rightFold.fillColor = new paper.Color(backgroundColor).multiply(0.8)
173
- if (opacity !== 1) rightFold.opacity = opacity
174
- items.push(rightFold)
175
-
176
- // 文字
177
- const foldTextItem = new paper.PointText({
178
- point: [x + width / 2, y + ribbonHeight / 2 + fontSize / 3],
179
- content: text,
180
- fontSize,
181
- fontFamily: ribbonFont,
182
- fillColor: new paper.Color(color),
183
- justification: 'center',
184
- })
185
-
186
- if (opacity !== 1) foldTextItem.opacity = opacity
187
- items.push(foldTextItem)
188
- }
189
-
190
- return {
191
- success: true,
192
- type: 'ribbon',
193
- items: items.map(i => i.id),
194
- }
195
- }
196
-
197
- module.exports = createRibbon