foliko 1.1.7 → 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 (113) hide show
  1. package/.agent/agents/poster-expert.md +228 -0
  2. package/.agent/data/default.json +10 -0
  3. package/.agent/data/plugins-state.json +1 -1
  4. package/.agent/mcp_config.json +0 -6
  5. package/.agent/plugins/test-plugin.py +15 -0
  6. package/.agent/plugins/test_nested_plugin.py +85 -0
  7. package/.agent/sessions/cli_default.json +83 -803
  8. package/.agent/sessions/weixin_o9cq80zgZqKPA2-s59PN43GdDy1w@im.wechat.json +189 -0
  9. package/.claude/settings.local.json +8 -1
  10. package/cli/src/ui/chat-ui.js +32 -21
  11. package/foliko_poster.png +0 -0
  12. package/output/business_poster_final.png +0 -0
  13. package/output/emoji_test_v2.png +0 -0
  14. package/output/foliko-ai-launch-poster.png +0 -0
  15. package/output/foliko-poster.png +0 -0
  16. package/output/muji_style_poster.png +0 -0
  17. package/output/new_product_launch.png +0 -0
  18. package/output/news_poster_625yi_subsidy.png +0 -0
  19. package/output/tech_future_2026.png +0 -0
  20. package/output/tech_future_poster.png +0 -0
  21. package/package.json +2 -2
  22. package/plugins/default-plugins.js +60 -7
  23. package/plugins/extension-executor-plugin.js +32 -22
  24. package/plugins/feishu-plugin.js +2 -2
  25. package/plugins/python-plugin-loader.js +461 -40
  26. package/plugins/python-plugin-loader.js.bak +856 -0
  27. package/plugins/subagent-plugin.js +0 -121
  28. package/plugins/telegram-plugin.js +2 -2
  29. package/plugins/weixin-plugin.js +40 -31
  30. package/poster.png +0 -0
  31. package/skills/foliko-dev/SKILL.md +6 -0
  32. package/skills/python-plugin-dev/SKILL.md +124 -2
  33. package/src/core/agent-chat.js +220 -281
  34. package/src/core/agent.js +127 -29
  35. package/src/executors/mcp-executor.js +282 -26
  36. package/src/utils/plugin-helpers.js +22 -4
  37. package/system.md +362 -109
  38. package/test-scan.js +18 -0
  39. package/.agent/memory/feedback/mnt7jrlt-d67qs7.md +0 -15
  40. package/.agent/memory/feedback/mnt88ja3-al4fuy.md +0 -9
  41. package/.agent/plugins/poster-plugin/README.md +0 -304
  42. package/.agent/plugins/poster-plugin/emojis/rocket.png +0 -1
  43. package/.agent/plugins/poster-plugin/fonts/PatuaOne-Regular.ttf +0 -0
  44. package/.agent/plugins/poster-plugin/fonts/SegoeUI Emoji.ttf +0 -0
  45. package/.agent/plugins/poster-plugin/fonts//345/276/256/350/275/257/351/233/205/351/273/221.ttf +0 -0
  46. 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
  47. package/.agent/plugins/poster-plugin/index.js +0 -13
  48. package/.agent/plugins/poster-plugin/package.json +0 -29
  49. package/.agent/plugins/poster-plugin/src/canvas.js +0 -224
  50. package/.agent/plugins/poster-plugin/src/components/arrow.js +0 -84
  51. package/.agent/plugins/poster-plugin/src/components/avatar.js +0 -71
  52. package/.agent/plugins/poster-plugin/src/components/badge.js +0 -85
  53. package/.agent/plugins/poster-plugin/src/components/barcode.js +0 -120
  54. package/.agent/plugins/poster-plugin/src/components/bubble.js +0 -153
  55. package/.agent/plugins/poster-plugin/src/components/button.js +0 -124
  56. package/.agent/plugins/poster-plugin/src/components/card.js +0 -88
  57. package/.agent/plugins/poster-plugin/src/components/chart.js +0 -127
  58. package/.agent/plugins/poster-plugin/src/components/chip.js +0 -88
  59. package/.agent/plugins/poster-plugin/src/components/columns.js +0 -107
  60. package/.agent/plugins/poster-plugin/src/components/cta.js +0 -87
  61. package/.agent/plugins/poster-plugin/src/components/divider.js +0 -55
  62. package/.agent/plugins/poster-plugin/src/components/feature.js +0 -85
  63. package/.agent/plugins/poster-plugin/src/components/featureGrid.js +0 -117
  64. package/.agent/plugins/poster-plugin/src/components/frame.js +0 -230
  65. package/.agent/plugins/poster-plugin/src/components/grid.js +0 -118
  66. package/.agent/plugins/poster-plugin/src/components/highlightText.js +0 -144
  67. package/.agent/plugins/poster-plugin/src/components/icon.js +0 -94
  68. package/.agent/plugins/poster-plugin/src/components/imageFrame.js +0 -155
  69. package/.agent/plugins/poster-plugin/src/components/index.js +0 -81
  70. package/.agent/plugins/poster-plugin/src/components/listItem.js +0 -147
  71. package/.agent/plugins/poster-plugin/src/components/notification.js +0 -123
  72. package/.agent/plugins/poster-plugin/src/components/progress.js +0 -79
  73. package/.agent/plugins/poster-plugin/src/components/progressCircle.js +0 -117
  74. package/.agent/plugins/poster-plugin/src/components/qrcode.js +0 -74
  75. package/.agent/plugins/poster-plugin/src/components/quote.js +0 -97
  76. package/.agent/plugins/poster-plugin/src/components/rating.js +0 -85
  77. package/.agent/plugins/poster-plugin/src/components/ribbon.js +0 -193
  78. package/.agent/plugins/poster-plugin/src/components/seal.js +0 -146
  79. package/.agent/plugins/poster-plugin/src/components/star.js +0 -70
  80. package/.agent/plugins/poster-plugin/src/components/statCard.js +0 -105
  81. package/.agent/plugins/poster-plugin/src/components/stepper.js +0 -118
  82. package/.agent/plugins/poster-plugin/src/components/table.js +0 -167
  83. package/.agent/plugins/poster-plugin/src/components/tagCloud.js +0 -85
  84. package/.agent/plugins/poster-plugin/src/components/timeline.js +0 -117
  85. package/.agent/plugins/poster-plugin/src/components/watermark.js +0 -52
  86. package/.agent/plugins/poster-plugin/src/composer.js +0 -2146
  87. package/.agent/plugins/poster-plugin/src/elements/artText.js +0 -60
  88. package/.agent/plugins/poster-plugin/src/elements/background.js +0 -84
  89. package/.agent/plugins/poster-plugin/src/elements/circle.js +0 -31
  90. package/.agent/plugins/poster-plugin/src/elements/image.js +0 -28
  91. package/.agent/plugins/poster-plugin/src/elements/index.js +0 -28
  92. package/.agent/plugins/poster-plugin/src/elements/line.js +0 -23
  93. package/.agent/plugins/poster-plugin/src/elements/polygon.js +0 -63
  94. package/.agent/plugins/poster-plugin/src/elements/rectangle.js +0 -32
  95. package/.agent/plugins/poster-plugin/src/elements/richText.js +0 -230
  96. package/.agent/plugins/poster-plugin/src/elements/svg.js +0 -108
  97. package/.agent/plugins/poster-plugin/src/elements/text.js +0 -109
  98. package/.agent/plugins/poster-plugin/src/fonts.js +0 -243
  99. package/.agent/plugins/poster-plugin/src/index.js +0 -2081
  100. package/.agent/plugins/poster-plugin/src/presets.js +0 -36
  101. package/.agent/plugins/poster-plugin/src/templates/business.js +0 -60
  102. package/.agent/plugins/poster-plugin/src/templates/gradient.js +0 -64
  103. package/.agent/plugins/poster-plugin/src/templates/index.js +0 -43
  104. package/.agent/plugins/poster-plugin/src/templates/modern.js +0 -69
  105. package/.agent/plugins/poster-plugin/src/templates/simple.js +0 -58
  106. package/.agent/plugins/poster-plugin/src/templates/social.js +0 -62
  107. package/.agent/plugins/poster-plugin/src/templates/tech.js +0 -84
  108. package/.agent/plugins/poster-plugin/src/utils/imageLoader.js +0 -84
  109. package/.agent/plugins/poster-plugin/test-background.svg +0 -1
  110. package/.agent/plugins/poster-plugin/test-full-poster.svg +0 -2
  111. package/.agent/plugins/poster-plugin/test-image.png +0 -0
  112. package/.agent/plugins/poster-plugin/yarn.lock +0 -1007
  113. package/output/zen_silence.png +0 -0
@@ -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,97 +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 {string} args.text - 引用文字
17
- * @param {string} args.author - 作者
18
- * @param {string} args.background - 背景色
19
- * @param {string} args.borderColor - 左边框颜色
20
- * @param {number} args.borderWidth - 左边框宽度
21
- * @param {number} args.padding - 内边距
22
- * @param {number} args.radius - 圆角半径
23
- * @param {string} args.textColor - 文字颜色
24
- * @param {string} args.authorColor - 作者颜色
25
- * @param {number} args.fontSize - 字体大小
26
- */
27
- function createQuote(project, canvas, args) {
28
- const {
29
- x, y,
30
- width = 400,
31
- text,
32
- author,
33
- background = '#f8fafc',
34
- borderColor = '#6366f1',
35
- borderWidth = 4,
36
- padding = 20,
37
- radius = 8,
38
- textColor = '#1e293b',
39
- authorColor = '#64748b',
40
- fontSize = 18,
41
- } = args
42
-
43
- const elements = []
44
-
45
- // 绘制背景
46
- const bg = new paper.Path.Rectangle({
47
- point: [x, y],
48
- size: [width, author ? 80 + fontSize * 2 : 40 + fontSize * 1.5],
49
- radius: radius,
50
- })
51
- bg.fillColor = new paper.Color(background)
52
- elements.push({ type: 'rectangle', id: bg.id })
53
-
54
- // 绘制左边框
55
- const border = new paper.Path.Rectangle({
56
- point: [x, y],
57
- size: [borderWidth, author ? 80 + fontSize * 2 : 40 + fontSize * 1.5],
58
- })
59
- border.fillColor = new paper.Color(borderColor)
60
- elements.push({ type: 'rectangle', id: border.id })
61
-
62
- // 绘制引用符号
63
- const quoteMark = new paper.PointText({
64
- point: [x + padding + 10, y + padding + fontSize],
65
- content: '"',
66
- fontSize: fontSize * 2,
67
- fillColor: new paper.Color(borderColor),
68
- justification: 'left',
69
- })
70
- elements.push({ type: 'text', id: quoteMark.id })
71
-
72
- // 绘制引用文字
73
- const quoteText = new paper.PointText({
74
- point: [x + padding + 30, y + padding + fontSize * 1.5],
75
- content: text,
76
- fontSize: fontSize,
77
- fillColor: new paper.Color(textColor),
78
- justification: 'left',
79
- })
80
- elements.push({ type: 'text', id: quoteText.id })
81
-
82
- // 绘制作者
83
- if (author) {
84
- const authorText = new paper.PointText({
85
- point: [x + padding, y + padding + fontSize * 2.5 + 10],
86
- content: `— ${author}`,
87
- fontSize: fontSize * 0.8,
88
- fillColor: new paper.Color(authorColor),
89
- justification: 'left',
90
- })
91
- elements.push({ type: 'text', id: authorText.id })
92
- }
93
-
94
- return { success: true, elements }
95
- }
96
-
97
- 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,193 +0,0 @@
1
- /**
2
- * 丝带/飘带组件
3
- */
4
-
5
- const paper = require('paper')
6
-
7
- /**
8
- * 创建丝带
9
- */
10
- function createRibbon(project, args) {
11
- const {
12
- x = 0,
13
- y = 0,
14
- width = 300,
15
- text = '',
16
- fontSize = 28,
17
- fontFamily,
18
- color = '#ffffff',
19
- backgroundColor = '#e74c3c',
20
- borderColor,
21
- borderWidth = 2,
22
- shadow,
23
- position = 'top', // top, bottom, left, right
24
- style = 'fold', // fold, diagonal, corner
25
- opacity = 1,
26
- } = args
27
-
28
- const items = []
29
-
30
- if (style === 'diagonal') {
31
- // 对角丝带
32
- const diagonalLength = Math.sqrt(width ** 2 + 60 ** 2)
33
- const angle = Math.atan2(60, width) * 180 / Math.PI
34
-
35
- const ribbon = new paper.Path.Rectangle({
36
- point: [x, y],
37
- size: [diagonalLength, 60],
38
- radius: 4,
39
- fillColor: new paper.Color(backgroundColor),
40
- })
41
- ribbon.rotate(angle, new paper.Point(x, y))
42
-
43
- if (borderColor) {
44
- ribbon.strokeColor = new paper.Color(borderColor)
45
- ribbon.strokeWidth = borderWidth
46
- }
47
-
48
- if (shadow) {
49
- ribbon.shadowColor = new paper.Color(shadow.color || '#000000')
50
- ribbon.shadowBlur = shadow.blur || 8
51
- ribbon.shadowOffset = new paper.Point(shadow.offsetX || 3, shadow.offsetY || 3)
52
- }
53
-
54
- if (opacity !== 1) ribbon.opacity = opacity
55
- items.push(ribbon)
56
-
57
- // 文字
58
- const textItem = new paper.PointText({
59
- point: [x + diagonalLength / 2, y + 60 / 2 + fontSize / 3],
60
- content: text,
61
- fontSize,
62
- fontFamily: fontFamily || 'sans-serif',
63
- fillColor: new paper.Color(color),
64
- justification: 'center',
65
- })
66
- textItem.rotate(angle, new paper.Point(x + diagonalLength / 2, y + 60 / 2))
67
-
68
- if (opacity !== 1) textItem.opacity = opacity
69
- items.push(textItem)
70
-
71
- } else if (style === 'corner') {
72
- // 角落丝带
73
- const ribbonWidth = width
74
- const ribbonHeight = 50
75
-
76
- // 主丝带
77
- const ribbon = new paper.Path.Rectangle({
78
- point: [x, y],
79
- size: [ribbonWidth, ribbonHeight],
80
- fillColor: new paper.Color(backgroundColor),
81
- })
82
-
83
- if (borderColor) {
84
- ribbon.strokeColor = new paper.Color(borderColor)
85
- ribbon.strokeWidth = borderWidth
86
- }
87
-
88
- if (shadow) {
89
- ribbon.shadowColor = new paper.Color(shadow.color || '#000000')
90
- ribbon.shadowBlur = shadow.blur || 8
91
- ribbon.shadowOffset = new paper.Point(shadow.offsetX || 3, shadow.offsetY || 3)
92
- }
93
-
94
- if (opacity !== 1) ribbon.opacity = opacity
95
- items.push(ribbon)
96
-
97
- // 折叠部分
98
- const foldSize = 20
99
- const fold = new paper.Path()
100
- fold.add(new paper.Point(x, y + ribbonHeight))
101
- fold.add(new paper.Point(x, y + ribbonHeight + foldSize))
102
- fold.add(new paper.Point(x + foldSize, y + ribbonHeight))
103
- fold.closed = true
104
- fold.fillColor = new paper.Color(backgroundColor).multiply(0.8)
105
-
106
- if (borderColor) {
107
- fold.strokeColor = new paper.Color(borderColor)
108
- fold.strokeWidth = borderWidth
109
- }
110
-
111
- if (opacity !== 1) fold.opacity = opacity
112
- items.push(fold)
113
-
114
- // 文字
115
- const textItem = new paper.PointText({
116
- point: [x + ribbonWidth / 2, y + ribbonHeight / 2 + fontSize / 3],
117
- content: text,
118
- fontSize,
119
- fontFamily: fontFamily || 'sans-serif',
120
- fillColor: new paper.Color(color),
121
- justification: 'center',
122
- })
123
-
124
- if (opacity !== 1) textItem.opacity = opacity
125
- items.push(textItem)
126
-
127
- } else {
128
- // 折叠丝带 (默认)
129
- const ribbonHeight = 50
130
-
131
- // 主丝带
132
- const ribbon = new paper.Path.Rectangle({
133
- point: [x, y],
134
- size: [width, ribbonHeight],
135
- fillColor: new paper.Color(backgroundColor),
136
- })
137
-
138
- if (borderColor) {
139
- ribbon.strokeColor = new paper.Color(borderColor)
140
- ribbon.strokeWidth = borderWidth
141
- }
142
-
143
- if (shadow) {
144
- ribbon.shadowColor = new paper.Color(shadow.color || '#000000')
145
- ribbon.shadowBlur = shadow.blur || 8
146
- ribbon.shadowOffset = new paper.Point(shadow.offsetX || 3, shadow.offsetY || 3)
147
- }
148
-
149
- if (opacity !== 1) ribbon.opacity = opacity
150
- items.push(ribbon)
151
-
152
- // 左右折叠三角
153
- const foldSize = 15
154
- const leftFold = new paper.Path()
155
- leftFold.add(new paper.Point(x, y))
156
- leftFold.add(new paper.Point(x - foldSize, y - foldSize))
157
- leftFold.add(new paper.Point(x, y - foldSize))
158
- leftFold.closed = true
159
- leftFold.fillColor = new paper.Color(backgroundColor).multiply(0.8)
160
- if (opacity !== 1) leftFold.opacity = opacity
161
- items.push(leftFold)
162
-
163
- const rightFold = new paper.Path()
164
- rightFold.add(new paper.Point(x + width, y))
165
- rightFold.add(new paper.Point(x + width + foldSize, y - foldSize))
166
- rightFold.add(new paper.Point(x + width, y - foldSize))
167
- rightFold.closed = true
168
- rightFold.fillColor = new paper.Color(backgroundColor).multiply(0.8)
169
- if (opacity !== 1) rightFold.opacity = opacity
170
- items.push(rightFold)
171
-
172
- // 文字
173
- const textItem = new paper.PointText({
174
- point: [x + width / 2, y + ribbonHeight / 2 + fontSize / 3],
175
- content: text,
176
- fontSize,
177
- fontFamily: fontFamily || 'sans-serif',
178
- fillColor: new paper.Color(color),
179
- justification: 'center',
180
- })
181
-
182
- if (opacity !== 1) textItem.opacity = opacity
183
- items.push(textItem)
184
- }
185
-
186
- return {
187
- success: true,
188
- type: 'ribbon',
189
- items: items.map(i => i.id),
190
- }
191
- }
192
-
193
- module.exports = createRibbon
@@ -1,146 +0,0 @@
1
- /**
2
- * 印章组件 - 印章效果
3
- */
4
-
5
- const paper = require('paper')
6
-
7
- /**
8
- * 创建印章
9
- */
10
- function createSeal(project, args) {
11
- const {
12
- x = 0,
13
- y = 0,
14
- size = 100,
15
- text = '印章',
16
- fontSize = 24,
17
- fontFamily,
18
- color = '#e74c3c',
19
- borderColor,
20
- style = 'circle', // circle, square, star, hexagon
21
- borderWidth = 3,
22
- opacity = 1,
23
- } = args
24
-
25
- const items = []
26
- const centerX = x + size / 2
27
- const centerY = y + size / 2
28
-
29
- // 印章边框
30
- let border
31
- switch (style) {
32
- case 'circle':
33
- border = new paper.Path.Circle({
34
- center: [centerX, centerY],
35
- radius: size / 2 - borderWidth,
36
- })
37
- break
38
- case 'square':
39
- const squareSize = size - borderWidth * 2
40
- border = new paper.Path.Rectangle({
41
- point: [x + borderWidth, y + borderWidth],
42
- size: [squareSize, squareSize],
43
- radius: 4,
44
- })
45
- break
46
- case 'star':
47
- border = createStarPath(centerX, centerY, size / 2 - borderWidth, size / 2 - borderWidth - 10, 5)
48
- break
49
- case 'hexagon':
50
- border = createPolygonPath(centerX, centerY, size / 2 - borderWidth, 6)
51
- break
52
- default:
53
- border = new paper.Path.Circle({
54
- center: [centerX, centerY],
55
- radius: size / 2 - borderWidth,
56
- })
57
- }
58
-
59
- border.strokeColor = new paper.Color(color)
60
- border.strokeWidth = borderWidth
61
- border.fillColor = null
62
- if (opacity !== 1) border.opacity = opacity
63
- items.push(border)
64
-
65
- // 内边框
66
- const innerBorder = border.clone()
67
- innerBorder.scale(0.85, 0.85, new paper.Point(centerX, centerY))
68
- innerBorder.strokeWidth = 1
69
- if (opacity !== 1) innerBorder.opacity = opacity
70
- items.push(innerBorder)
71
-
72
- // 文字
73
- const textItem = new paper.PointText({
74
- point: [centerX, centerY + fontSize / 3],
75
- content: text,
76
- fontSize,
77
- fontFamily: fontFamily || 'serif',
78
- fillColor: new paper.Color(color),
79
- justification: 'center',
80
- })
81
-
82
- if (opacity !== 1) textItem.opacity = opacity
83
- items.push(textItem)
84
-
85
- // 顶部文字(如果适用)
86
- const topText = new paper.PointText({
87
- point: [centerX, centerY - size / 4],
88
- content: '★',
89
- fontSize: 16,
90
- fontFamily: fontFamily || 'serif',
91
- fillColor: new paper.Color(color),
92
- justification: 'center',
93
- })
94
- if (opacity !== 1) topText.opacity = opacity
95
- items.push(topText)
96
-
97
- // 底部星星装饰
98
- const bottomStar = new paper.PointText({
99
- point: [centerX, centerY + size / 3],
100
- content: '★ ★ ★',
101
- fontSize: 12,
102
- fontFamily: fontFamily || 'serif',
103
- fillColor: new paper.Color(color),
104
- justification: 'center',
105
- letterSpacing: 8,
106
- })
107
- if (opacity !== 1) bottomStar.opacity = opacity
108
- items.push(bottomStar)
109
-
110
- return {
111
- success: true,
112
- type: 'seal',
113
- items: items.map(i => i.id),
114
- }
115
- }
116
-
117
- /**
118
- * 创建五角星路径
119
- */
120
- function createStarPath(cx, cy, outerR, innerR, points) {
121
- const path = new paper.Path()
122
- const angleStep = Math.PI / points
123
-
124
- for (let i = 0; i < points * 2; i++) {
125
- const r = i % 2 === 0 ? outerR : innerR
126
- const angle = i * angleStep - Math.PI / 2
127
- path.add(new paper.Point(cx + r * Math.cos(angle), cy + r * Math.sin(angle)))
128
- }
129
- path.closed = true
130
- return path
131
- }
132
-
133
- /**
134
- * 创建多边形路径
135
- */
136
- function createPolygonPath(cx, cy, radius, sides) {
137
- const path = new paper.Path()
138
- for (let i = 0; i < sides; i++) {
139
- const angle = (i * 2 * Math.PI / sides) - Math.PI / 2
140
- path.add(new paper.Point(cx + radius * Math.cos(angle), cy + radius * Math.sin(angle)))
141
- }
142
- path.closed = true
143
- return path
144
- }
145
-
146
- module.exports = createSeal
@@ -1,70 +0,0 @@
1
- /**
2
- * 星形组件 - 支持多角星形
3
- */
4
-
5
- const paper = require('paper')
6
-
7
- /**
8
- * 创建星形组件
9
- * @param {Object} project - Paper.js 项目
10
- * @param {Object} canvas - 画布对象
11
- * @param {Object} params - 组件参数
12
- */
13
- function createStar(project, canvas, params) {
14
- const {
15
- cx,
16
- cy,
17
- points = 5,
18
- innerRadius: providedInnerRadius,
19
- outerRadius,
20
- fill,
21
- stroke,
22
- strokeWidth = 1,
23
- opacity = 1,
24
- rotation = 0
25
- } = params
26
-
27
- // 计算内半径
28
- const innerRadius = providedInnerRadius || outerRadius * 0.4
29
-
30
- // 创建星形路径
31
- const path = new paper.Path()
32
- const angleStep = Math.PI / points
33
-
34
- for (let i = 0; i < points * 2; i++) {
35
- const radius = i % 2 === 0 ? outerRadius : innerRadius
36
- const angle = i * angleStep - Math.PI / 2 + (rotation * Math.PI / 180)
37
- const x = cx + radius * Math.cos(angle)
38
- const y = cy + radius * Math.sin(angle)
39
-
40
- if (i === 0) {
41
- path.moveTo(x, y)
42
- } else {
43
- path.lineTo(x, y)
44
- }
45
- }
46
- path.closePath()
47
-
48
- // 设置样式
49
- if (fill) {
50
- path.fillColor = new paper.Color(fill)
51
- }
52
- if (stroke) {
53
- path.strokeColor = new paper.Color(stroke)
54
- path.strokeWidth = strokeWidth
55
- }
56
- path.opacity = opacity
57
-
58
- // 关键:将元素添加到活动层
59
- if (project && project.activeLayer) {
60
- project.activeLayer.addChild(path)
61
- }
62
-
63
- return {
64
- success: true,
65
- elements: [{ type: 'path', id: path.id }],
66
- type: 'star'
67
- }
68
- }
69
-
70
- module.exports = createStar