@cognima/banners 0.0.1-beta

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 (48) hide show
  1. package/assets/fonts/Manrope/Manrope-Bold.ttf +0 -0
  2. package/assets/fonts/Manrope/Manrope-Regular.ttf +0 -0
  3. package/assets/fonts/Others/AbyssinicaSIL-Regular.ttf +0 -0
  4. package/assets/fonts/Others/ChirpRegular.ttf +0 -0
  5. package/assets/fonts/Poppins/Poppins-Bold.ttf +0 -0
  6. package/assets/fonts/Poppins/Poppins-Medium.ttf +0 -0
  7. package/assets/fonts/Poppins/Poppins-Regular.ttf +0 -0
  8. package/assets/placeholders/album_art.png +0 -0
  9. package/assets/placeholders/avatar.png +0 -0
  10. package/assets/placeholders/badge.jpg +0 -0
  11. package/assets/placeholders/badge.png +0 -0
  12. package/assets/placeholders/badge_2.jpg +0 -0
  13. package/assets/placeholders/badge_3.jpg +0 -0
  14. package/assets/placeholders/badge_4.jpg +0 -0
  15. package/assets/placeholders/badge_5.jpg +0 -0
  16. package/assets/placeholders/banner.jpeg +0 -0
  17. package/assets/placeholders/images.jpeg +0 -0
  18. package/index.js +153 -0
  19. package/package.json +34 -0
  20. package/src/animation-effects.js +631 -0
  21. package/src/cache-manager.js +258 -0
  22. package/src/community-banner.js +1536 -0
  23. package/src/constants.js +208 -0
  24. package/src/discord-profile.js +584 -0
  25. package/src/e-commerce-banner.js +1214 -0
  26. package/src/effects.js +355 -0
  27. package/src/error-handler.js +305 -0
  28. package/src/event-banner.js +1319 -0
  29. package/src/facebook-post.js +679 -0
  30. package/src/gradient-welcome.js +430 -0
  31. package/src/image-filters.js +1034 -0
  32. package/src/image-processor.js +1014 -0
  33. package/src/instagram-post.js +504 -0
  34. package/src/interactive-elements.js +1208 -0
  35. package/src/linkedin-post.js +658 -0
  36. package/src/marketing-banner.js +1089 -0
  37. package/src/minimalist-banner.js +892 -0
  38. package/src/modern-profile.js +755 -0
  39. package/src/performance-optimizer.js +216 -0
  40. package/src/telegram-header.js +544 -0
  41. package/src/test-runner.js +645 -0
  42. package/src/tiktok-post.js +713 -0
  43. package/src/twitter-header.js +604 -0
  44. package/src/validator.js +442 -0
  45. package/src/welcome-leave.js +445 -0
  46. package/src/whatsapp-status.js +386 -0
  47. package/src/youtube-thumbnail.js +681 -0
  48. package/utils.js +710 -0
@@ -0,0 +1,631 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Módulo de efeitos de animação para banners
5
+ *
6
+ * Este módulo fornece funções para criar efeitos de animação estáticos
7
+ * que simulam movimento e interatividade nos banners.
8
+ *
9
+ * @module animation-effects
10
+ * @author Cognima Team (melhorado)
11
+ * @version 2.0.0
12
+ */
13
+
14
+ const utils = require("../utils");
15
+
16
+ /**
17
+ * Adiciona um efeito de brilho (glow) a um elemento
18
+ *
19
+ * @param {CanvasRenderingContext2D} ctx - Contexto de renderização
20
+ * @param {number} x - Posição X do elemento
21
+ * @param {number} y - Posição Y do elemento
22
+ * @param {number} width - Largura do elemento
23
+ * @param {number} height - Altura do elemento
24
+ * @param {string} color - Cor do brilho
25
+ * @param {number} [intensity=0.5] - Intensidade do brilho (0-1)
26
+ * @param {number} [radius=20] - Raio do brilho
27
+ */
28
+ function addGlowEffect(ctx, x, y, width, height, color, intensity = 0.5, radius = 20) {
29
+ // Salva o estado atual do contexto
30
+ ctx.save();
31
+
32
+ // Configura o efeito de sombra para criar o brilho
33
+ ctx.shadowColor = color;
34
+ ctx.shadowBlur = radius;
35
+ ctx.shadowOffsetX = 0;
36
+ ctx.shadowOffsetY = 0;
37
+
38
+ // Desenha um retângulo com a cor do brilho e opacidade ajustada
39
+ ctx.fillStyle = utils.hexToRgba(color, intensity * 0.3);
40
+ ctx.fillRect(x, y, width, height);
41
+
42
+ // Restaura o estado do contexto
43
+ ctx.restore();
44
+ }
45
+
46
+ /**
47
+ * Adiciona um efeito de pulso (simulado estaticamente)
48
+ *
49
+ * @param {CanvasRenderingContext2D} ctx - Contexto de renderização
50
+ * @param {number} x - Posição X do elemento
51
+ * @param {number} y - Posição Y do elemento
52
+ * @param {number} radius - Raio do pulso
53
+ * @param {string} color - Cor do pulso
54
+ * @param {number} [intensity=0.5] - Intensidade do pulso (0-1)
55
+ */
56
+ function addPulseEffect(ctx, x, y, radius, color, intensity = 0.5) {
57
+ // Desenha múltiplos círculos com opacidade decrescente para simular pulso
58
+ for (let i = 0; i < 3; i++) {
59
+ const currentRadius = radius * (1 + i * 0.2);
60
+ const opacity = intensity * (1 - i * 0.3);
61
+
62
+ ctx.beginPath();
63
+ ctx.arc(x, y, currentRadius, 0, Math.PI * 2);
64
+ ctx.fillStyle = utils.hexToRgba(color, opacity);
65
+ ctx.fill();
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Adiciona um efeito de movimento (motion blur) a um elemento
71
+ *
72
+ * @param {CanvasRenderingContext2D} ctx - Contexto de renderização
73
+ * @param {number} x - Posição X do elemento
74
+ * @param {number} y - Posição Y do elemento
75
+ * @param {number} width - Largura do elemento
76
+ * @param {number} height - Altura do elemento
77
+ * @param {string} direction - Direção do movimento ("left", "right", "up", "down")
78
+ * @param {number} [intensity=0.5] - Intensidade do efeito (0-1)
79
+ */
80
+ function addMotionBlurEffect(ctx, x, y, width, height, direction, intensity = 0.5) {
81
+ // Número de cópias para criar o efeito de blur
82
+ const steps = Math.floor(intensity * 10) + 1;
83
+ const stepSize = 3;
84
+
85
+ // Salva o estado atual do contexto
86
+ ctx.save();
87
+
88
+ // Desenha múltiplas cópias com opacidade decrescente
89
+ for (let i = 1; i <= steps; i++) {
90
+ const opacity = (1 - i / steps) * intensity;
91
+ ctx.fillStyle = utils.hexToRgba("#FFFFFF", opacity);
92
+
93
+ let offsetX = 0;
94
+ let offsetY = 0;
95
+
96
+ switch (direction) {
97
+ case "left":
98
+ offsetX = -i * stepSize;
99
+ break;
100
+ case "right":
101
+ offsetX = i * stepSize;
102
+ break;
103
+ case "up":
104
+ offsetY = -i * stepSize;
105
+ break;
106
+ case "down":
107
+ offsetY = i * stepSize;
108
+ break;
109
+ }
110
+
111
+ ctx.fillRect(x + offsetX, y + offsetY, width, height);
112
+ }
113
+
114
+ // Restaura o estado do contexto
115
+ ctx.restore();
116
+ }
117
+
118
+ /**
119
+ * Adiciona um efeito de sombra 3D a um elemento
120
+ *
121
+ * @param {CanvasRenderingContext2D} ctx - Contexto de renderização
122
+ * @param {number} x - Posição X do elemento
123
+ * @param {number} y - Posição Y do elemento
124
+ * @param {number} width - Largura do elemento
125
+ * @param {number} height - Altura do elemento
126
+ * @param {number} [depth=5] - Profundidade da sombra
127
+ * @param {string} [color="#000000"] - Cor da sombra
128
+ * @param {number} [opacity=0.2] - Opacidade da sombra
129
+ */
130
+ function add3DShadowEffect(ctx, x, y, width, height, depth = 5, color = "#000000", opacity = 0.2) {
131
+ // Salva o estado atual do contexto
132
+ ctx.save();
133
+
134
+ // Desenha múltiplas camadas para criar o efeito 3D
135
+ for (let i = 1; i <= depth; i++) {
136
+ ctx.fillStyle = utils.hexToRgba(color, opacity / i);
137
+ ctx.fillRect(x + i, y + i, width, height);
138
+ }
139
+
140
+ // Restaura o estado do contexto
141
+ ctx.restore();
142
+ }
143
+
144
+ /**
145
+ * Adiciona um efeito de reflexo a um elemento
146
+ *
147
+ * @param {CanvasRenderingContext2D} ctx - Contexto de renderização
148
+ * @param {number} x - Posição X do elemento
149
+ * @param {number} y - Posição Y do elemento
150
+ * @param {number} width - Largura do elemento
151
+ * @param {number} height - Altura do elemento
152
+ * @param {number} [reflectionHeight=0.3] - Altura do reflexo em relação à altura do elemento (0-1)
153
+ * @param {number} [opacity=0.3] - Opacidade máxima do reflexo
154
+ */
155
+ function addReflectionEffect(ctx, x, y, width, height, reflectionHeight = 0.3, opacity = 0.3) {
156
+ // Salva o estado atual do contexto
157
+ ctx.save();
158
+
159
+ // Altura do reflexo
160
+ const rHeight = height * reflectionHeight;
161
+
162
+ // Cria um gradiente para o reflexo (mais opaco no topo, transparente embaixo)
163
+ const gradient = ctx.createLinearGradient(0, y + height, 0, y + height + rHeight);
164
+ gradient.addColorStop(0, utils.hexToRgba("#FFFFFF", opacity));
165
+ gradient.addColorStop(1, utils.hexToRgba("#FFFFFF", 0));
166
+
167
+ // Aplica o gradiente
168
+ ctx.fillStyle = gradient;
169
+
170
+ // Desenha o reflexo
171
+ ctx.fillRect(x, y + height, width, rHeight);
172
+
173
+ // Restaura o estado do contexto
174
+ ctx.restore();
175
+ }
176
+
177
+ /**
178
+ * Adiciona um efeito de destaque (highlight) a um elemento
179
+ *
180
+ * @param {CanvasRenderingContext2D} ctx - Contexto de renderização
181
+ * @param {number} x - Posição X do elemento
182
+ * @param {number} y - Posição Y do elemento
183
+ * @param {number} width - Largura do elemento
184
+ * @param {number} height - Altura do elemento
185
+ * @param {string} [color="#FFFFFF"] - Cor do destaque
186
+ * @param {number} [angle=45] - Ângulo do destaque em graus
187
+ * @param {number} [opacity=0.5] - Opacidade do destaque
188
+ */
189
+ function addHighlightEffect(ctx, x, y, width, height, color = "#FFFFFF", angle = 45, opacity = 0.5) {
190
+ // Salva o estado atual do contexto
191
+ ctx.save();
192
+
193
+ // Converte o ângulo para radianos
194
+ const radians = angle * Math.PI / 180;
195
+
196
+ // Calcula a largura do destaque
197
+ const highlightWidth = Math.sqrt(width * width + height * height) * 0.3;
198
+
199
+ // Calcula o centro do elemento
200
+ const centerX = x + width / 2;
201
+ const centerY = y + height / 2;
202
+
203
+ // Calcula os pontos de início e fim do destaque
204
+ const startX = centerX - Math.cos(radians) * width;
205
+ const startY = centerY - Math.sin(radians) * height;
206
+ const endX = centerX + Math.cos(radians) * width;
207
+ const endY = centerY + Math.sin(radians) * height;
208
+
209
+ // Cria um gradiente para o destaque
210
+ const gradient = ctx.createLinearGradient(startX, startY, endX, endY);
211
+ gradient.addColorStop(0, utils.hexToRgba(color, 0));
212
+ gradient.addColorStop(0.4, utils.hexToRgba(color, 0));
213
+ gradient.addColorStop(0.5, utils.hexToRgba(color, opacity));
214
+ gradient.addColorStop(0.6, utils.hexToRgba(color, 0));
215
+ gradient.addColorStop(1, utils.hexToRgba(color, 0));
216
+
217
+ // Aplica o gradiente
218
+ ctx.fillStyle = gradient;
219
+
220
+ // Recorta para a área do elemento
221
+ ctx.beginPath();
222
+ ctx.rect(x, y, width, height);
223
+ ctx.clip();
224
+
225
+ // Desenha o destaque
226
+ ctx.fillRect(x - highlightWidth / 2, y - highlightWidth / 2, width + highlightWidth, height + highlightWidth);
227
+
228
+ // Restaura o estado do contexto
229
+ ctx.restore();
230
+ }
231
+
232
+ /**
233
+ * Adiciona um efeito de partículas flutuantes
234
+ *
235
+ * @param {CanvasRenderingContext2D} ctx - Contexto de renderização
236
+ * @param {number} x - Posição X da área
237
+ * @param {number} y - Posição Y da área
238
+ * @param {number} width - Largura da área
239
+ * @param {number} height - Altura da área
240
+ * @param {number} [count=20] - Número de partículas
241
+ * @param {string} [color="#FFFFFF"] - Cor das partículas
242
+ * @param {number} [maxSize=5] - Tamanho máximo das partículas
243
+ */
244
+ function addFloatingParticlesEffect(ctx, x, y, width, height, count = 20, color = "#FFFFFF", maxSize = 5) {
245
+ // Salva o estado atual do contexto
246
+ ctx.save();
247
+
248
+ // Gera partículas aleatórias
249
+ for (let i = 0; i < count; i++) {
250
+ const particleX = x + Math.random() * width;
251
+ const particleY = y + Math.random() * height;
252
+ const particleSize = Math.random() * maxSize + 1;
253
+ const opacity = Math.random() * 0.5 + 0.1;
254
+
255
+ // Desenha a partícula
256
+ ctx.beginPath();
257
+ ctx.arc(particleX, particleY, particleSize, 0, Math.PI * 2);
258
+ ctx.fillStyle = utils.hexToRgba(color, opacity);
259
+ ctx.fill();
260
+ }
261
+
262
+ // Restaura o estado do contexto
263
+ ctx.restore();
264
+ }
265
+
266
+ /**
267
+ * Adiciona um efeito de ondulação (ripple)
268
+ *
269
+ * @param {CanvasRenderingContext2D} ctx - Contexto de renderização
270
+ * @param {number} x - Posição X do centro da ondulação
271
+ * @param {number} y - Posição Y do centro da ondulação
272
+ * @param {number} [maxRadius=100] - Raio máximo da ondulação
273
+ * @param {number} [rings=3] - Número de anéis da ondulação
274
+ * @param {string} [color="#FFFFFF"] - Cor da ondulação
275
+ * @param {number} [opacity=0.3] - Opacidade máxima da ondulação
276
+ */
277
+ function addRippleEffect(ctx, x, y, maxRadius = 100, rings = 3, color = "#FFFFFF", opacity = 0.3) {
278
+ // Salva o estado atual do contexto
279
+ ctx.save();
280
+
281
+ // Desenha múltiplos anéis para criar o efeito de ondulação
282
+ for (let i = 0; i < rings; i++) {
283
+ const radius = maxRadius * ((i + 1) / rings);
284
+ const ringOpacity = opacity * (1 - i / rings);
285
+
286
+ ctx.beginPath();
287
+ ctx.arc(x, y, radius, 0, Math.PI * 2);
288
+ ctx.strokeStyle = utils.hexToRgba(color, ringOpacity);
289
+ ctx.lineWidth = 2;
290
+ ctx.stroke();
291
+ }
292
+
293
+ // Restaura o estado do contexto
294
+ ctx.restore();
295
+ }
296
+
297
+ /**
298
+ * Adiciona um efeito de texto com sombra
299
+ *
300
+ * @param {CanvasRenderingContext2D} ctx - Contexto de renderização
301
+ * @param {string} text - Texto a ser desenhado
302
+ * @param {number} x - Posição X do texto
303
+ * @param {number} y - Posição Y do texto
304
+ * @param {string} [textColor="#FFFFFF"] - Cor do texto
305
+ * @param {string} [shadowColor="#000000"] - Cor da sombra
306
+ * @param {number} [shadowBlur=5] - Desfoque da sombra
307
+ * @param {number} [shadowOffsetX=2] - Deslocamento X da sombra
308
+ * @param {number} [shadowOffsetY=2] - Deslocamento Y da sombra
309
+ */
310
+ function addTextShadowEffect(ctx, text, x, y, textColor = "#FFFFFF", shadowColor = "#000000", shadowBlur = 5, shadowOffsetX = 2, shadowOffsetY = 2) {
311
+ // Salva o estado atual do contexto
312
+ ctx.save();
313
+
314
+ // Configura a sombra
315
+ ctx.shadowColor = shadowColor;
316
+ ctx.shadowBlur = shadowBlur;
317
+ ctx.shadowOffsetX = shadowOffsetX;
318
+ ctx.shadowOffsetY = shadowOffsetY;
319
+
320
+ // Desenha o texto
321
+ ctx.fillStyle = textColor;
322
+ ctx.fillText(text, x, y);
323
+
324
+ // Restaura o estado do contexto
325
+ ctx.restore();
326
+ }
327
+
328
+ /**
329
+ * Adiciona um efeito de texto com contorno
330
+ *
331
+ * @param {CanvasRenderingContext2D} ctx - Contexto de renderização
332
+ * @param {string} text - Texto a ser desenhado
333
+ * @param {number} x - Posição X do texto
334
+ * @param {number} y - Posição Y do texto
335
+ * @param {string} [fillColor="#FFFFFF"] - Cor de preenchimento do texto
336
+ * @param {string} [strokeColor="#000000"] - Cor do contorno
337
+ * @param {number} [lineWidth=2] - Largura do contorno
338
+ */
339
+ function addTextOutlineEffect(ctx, text, x, y, fillColor = "#FFFFFF", strokeColor = "#000000", lineWidth = 2) {
340
+ // Salva o estado atual do contexto
341
+ ctx.save();
342
+
343
+ // Configura o contorno
344
+ ctx.strokeStyle = strokeColor;
345
+ ctx.lineWidth = lineWidth;
346
+ ctx.lineJoin = "round";
347
+
348
+ // Desenha o contorno
349
+ ctx.strokeText(text, x, y);
350
+
351
+ // Desenha o texto
352
+ ctx.fillStyle = fillColor;
353
+ ctx.fillText(text, x, y);
354
+
355
+ // Restaura o estado do contexto
356
+ ctx.restore();
357
+ }
358
+
359
+ /**
360
+ * Adiciona um efeito de texto com gradiente
361
+ *
362
+ * @param {CanvasRenderingContext2D} ctx - Contexto de renderização
363
+ * @param {string} text - Texto a ser desenhado
364
+ * @param {number} x - Posição X do texto
365
+ * @param {number} y - Posição Y do texto
366
+ * @param {Array<string>} colors - Array de cores para o gradiente
367
+ * @param {string} [direction="horizontal"] - Direção do gradiente ("horizontal", "vertical", "diagonal")
368
+ */
369
+ function addTextGradientEffect(ctx, text, x, y, colors, direction = "horizontal") {
370
+ // Salva o estado atual do contexto
371
+ ctx.save();
372
+
373
+ // Obtém as dimensões do texto
374
+ const metrics = ctx.measureText(text);
375
+ const width = metrics.width;
376
+ const height = parseInt(ctx.font); // Aproximação da altura baseada no tamanho da fonte
377
+
378
+ // Cria o gradiente de acordo com a direção
379
+ let gradient;
380
+ switch (direction) {
381
+ case "vertical":
382
+ gradient = ctx.createLinearGradient(x, y - height, x, y);
383
+ break;
384
+ case "diagonal":
385
+ gradient = ctx.createLinearGradient(x, y - height, x + width, y);
386
+ break;
387
+ case "horizontal":
388
+ default:
389
+ gradient = ctx.createLinearGradient(x, y, x + width, y);
390
+ break;
391
+ }
392
+
393
+ // Adiciona as cores ao gradiente
394
+ for (let i = 0; i < colors.length; i++) {
395
+ gradient.addColorStop(i / (colors.length - 1), colors[i]);
396
+ }
397
+
398
+ // Aplica o gradiente
399
+ ctx.fillStyle = gradient;
400
+
401
+ // Desenha o texto
402
+ ctx.fillText(text, x, y);
403
+
404
+ // Restaura o estado do contexto
405
+ ctx.restore();
406
+ }
407
+
408
+ /**
409
+ * Adiciona um efeito de texto com animação de digitação (simulado estaticamente)
410
+ *
411
+ * @param {CanvasRenderingContext2D} ctx - Contexto de renderização
412
+ * @param {string} text - Texto completo
413
+ * @param {number} x - Posição X do texto
414
+ * @param {number} y - Posição Y do texto
415
+ * @param {number} [progress=0.7] - Progresso da digitação (0-1)
416
+ * @param {string} [color="#FFFFFF"] - Cor do texto
417
+ * @param {boolean} [showCursor=true] - Se deve mostrar o cursor
418
+ */
419
+ function addTypingEffect(ctx, text, x, y, progress = 0.7, color = "#FFFFFF", showCursor = true) {
420
+ // Salva o estado atual do contexto
421
+ ctx.save();
422
+
423
+ // Calcula quantos caracteres mostrar
424
+ const charCount = Math.floor(text.length * progress);
425
+ const visibleText = text.substring(0, charCount);
426
+
427
+ // Desenha o texto visível
428
+ ctx.fillStyle = color;
429
+ ctx.fillText(visibleText, x, y);
430
+
431
+ // Desenha o cursor se necessário
432
+ if (showCursor) {
433
+ const cursorX = x + ctx.measureText(visibleText).width;
434
+ ctx.fillRect(cursorX, y - parseInt(ctx.font) * 0.7, 2, parseInt(ctx.font) * 0.8);
435
+ }
436
+
437
+ // Restaura o estado do contexto
438
+ ctx.restore();
439
+ }
440
+
441
+ /**
442
+ * Adiciona um efeito de texto com animação de fade in (simulado estaticamente)
443
+ *
444
+ * @param {CanvasRenderingContext2D} ctx - Contexto de renderização
445
+ * @param {string} text - Texto a ser desenhado
446
+ * @param {number} x - Posição X do texto
447
+ * @param {number} y - Posição Y do texto
448
+ * @param {number} [progress=0.7] - Progresso do fade in (0-1)
449
+ * @param {string} [color="#FFFFFF"] - Cor do texto
450
+ */
451
+ function addFadeInEffect(ctx, text, x, y, progress = 0.7, color = "#FFFFFF") {
452
+ // Salva o estado atual do contexto
453
+ ctx.save();
454
+
455
+ // Calcula a opacidade baseada no progresso
456
+ const opacity = Math.min(1, progress);
457
+
458
+ // Desenha o texto com a opacidade calculada
459
+ ctx.fillStyle = utils.hexToRgba(color, opacity);
460
+ ctx.fillText(text, x, y);
461
+
462
+ // Restaura o estado do contexto
463
+ ctx.restore();
464
+ }
465
+
466
+ /**
467
+ * Adiciona um efeito de texto com animação de slide in (simulado estaticamente)
468
+ *
469
+ * @param {CanvasRenderingContext2D} ctx - Contexto de renderização
470
+ * @param {string} text - Texto a ser desenhado
471
+ * @param {number} x - Posição X final do texto
472
+ * @param {number} y - Posição Y do texto
473
+ * @param {number} [progress=0.7] - Progresso do slide in (0-1)
474
+ * @param {string} [direction="left"] - Direção do slide ("left", "right", "up", "down")
475
+ * @param {string} [color="#FFFFFF"] - Cor do texto
476
+ * @param {number} [distance=100] - Distância do slide
477
+ */
478
+ function addSlideInEffect(ctx, text, x, y, progress = 0.7, direction = "left", color = "#FFFFFF", distance = 100) {
479
+ // Salva o estado atual do contexto
480
+ ctx.save();
481
+
482
+ // Calcula a posição baseada no progresso e direção
483
+ let currentX = x;
484
+ let currentY = y;
485
+
486
+ switch (direction) {
487
+ case "left":
488
+ currentX = x + distance * (1 - progress);
489
+ break;
490
+ case "right":
491
+ currentX = x - distance * (1 - progress);
492
+ break;
493
+ case "up":
494
+ currentY = y + distance * (1 - progress);
495
+ break;
496
+ case "down":
497
+ currentY = y - distance * (1 - progress);
498
+ break;
499
+ }
500
+
501
+ // Desenha o texto na posição calculada
502
+ ctx.fillStyle = color;
503
+ ctx.fillText(text, currentX, currentY);
504
+
505
+ // Restaura o estado do contexto
506
+ ctx.restore();
507
+ }
508
+
509
+ /**
510
+ * Adiciona um efeito de texto com animação de escala (simulado estaticamente)
511
+ *
512
+ * @param {CanvasRenderingContext2D} ctx - Contexto de renderização
513
+ * @param {string} text - Texto a ser desenhado
514
+ * @param {number} x - Posição X do texto
515
+ * @param {number} y - Posição Y do texto
516
+ * @param {number} [progress=0.7] - Progresso da escala (0-1)
517
+ * @param {string} [color="#FFFFFF"] - Cor do texto
518
+ * @param {number} [minScale=0.5] - Escala mínima
519
+ */
520
+ function addScaleEffect(ctx, text, x, y, progress = 0.7, color = "#FFFFFF", minScale = 0.5) {
521
+ // Salva o estado atual do contexto
522
+ ctx.save();
523
+
524
+ // Calcula a escala baseada no progresso
525
+ const scale = minScale + (1 - minScale) * progress;
526
+
527
+ // Obtém as dimensões do texto
528
+ const metrics = ctx.measureText(text);
529
+ const width = metrics.width;
530
+
531
+ // Calcula o ponto central do texto
532
+ const centerX = x + width / 2;
533
+
534
+ // Aplica a transformação
535
+ ctx.translate(centerX, y);
536
+ ctx.scale(scale, scale);
537
+ ctx.translate(-centerX, -y);
538
+
539
+ // Desenha o texto
540
+ ctx.fillStyle = color;
541
+ ctx.fillText(text, x, y);
542
+
543
+ // Restaura o estado do contexto
544
+ ctx.restore();
545
+ }
546
+
547
+ /**
548
+ * Adiciona um efeito de texto com animação de rotação (simulado estaticamente)
549
+ *
550
+ * @param {CanvasRenderingContext2D} ctx - Contexto de renderização
551
+ * @param {string} text - Texto a ser desenhado
552
+ * @param {number} x - Posição X do texto
553
+ * @param {number} y - Posição Y do texto
554
+ * @param {number} [progress=0.7] - Progresso da rotação (0-1)
555
+ * @param {string} [color="#FFFFFF"] - Cor do texto
556
+ * @param {number} [maxAngle=30] - Ângulo máximo de rotação em graus
557
+ */
558
+ function addRotationEffect(ctx, text, x, y, progress = 0.7, color = "#FFFFFF", maxAngle = 30) {
559
+ // Salva o estado atual do contexto
560
+ ctx.save();
561
+
562
+ // Calcula o ângulo baseado no progresso
563
+ const angle = maxAngle * (1 - progress) * Math.PI / 180;
564
+
565
+ // Obtém as dimensões do texto
566
+ const metrics = ctx.measureText(text);
567
+ const width = metrics.width;
568
+
569
+ // Calcula o ponto central do texto
570
+ const centerX = x + width / 2;
571
+
572
+ // Aplica a transformação
573
+ ctx.translate(centerX, y);
574
+ ctx.rotate(angle);
575
+ ctx.translate(-centerX, -y);
576
+
577
+ // Desenha o texto
578
+ ctx.fillStyle = color;
579
+ ctx.fillText(text, x, y);
580
+
581
+ // Restaura o estado do contexto
582
+ ctx.restore();
583
+ }
584
+
585
+ /**
586
+ * Adiciona um efeito de texto com animação de bounce (simulado estaticamente)
587
+ *
588
+ * @param {CanvasRenderingContext2D} ctx - Contexto de renderização
589
+ * @param {string} text - Texto a ser desenhado
590
+ * @param {number} x - Posição X do texto
591
+ * @param {number} y - Posição Y do texto
592
+ * @param {number} [progress=0.7] - Progresso da animação (0-1)
593
+ * @param {string} [color="#FFFFFF"] - Cor do texto
594
+ * @param {number} [height=20] - Altura máxima do bounce
595
+ */
596
+ function addBounceEffect(ctx, text, x, y, progress = 0.7, color = "#FFFFFF", height = 20) {
597
+ // Salva o estado atual do contexto
598
+ ctx.save();
599
+
600
+ // Simula uma função de bounce
601
+ const bounceProgress = Math.abs(Math.sin(progress * Math.PI * 2));
602
+ const offset = bounceProgress * height;
603
+
604
+ // Desenha o texto com o offset calculado
605
+ ctx.fillStyle = color;
606
+ ctx.fillText(text, x, y - offset);
607
+
608
+ // Restaura o estado do contexto
609
+ ctx.restore();
610
+ }
611
+
612
+ module.exports = {
613
+ addGlowEffect,
614
+ addPulseEffect,
615
+ addMotionBlurEffect,
616
+ add3DShadowEffect,
617
+ addReflectionEffect,
618
+ addHighlightEffect,
619
+ addFloatingParticlesEffect,
620
+ addRippleEffect,
621
+ addTextShadowEffect,
622
+ addTextOutlineEffect,
623
+ addTextGradientEffect,
624
+ addTypingEffect,
625
+ addFadeInEffect,
626
+ addSlideInEffect,
627
+ addScaleEffect,
628
+ addRotationEffect,
629
+ addBounceEffect
630
+ };
631
+