Communitygithub.com

ComposioHQ/slack-gif-creator

Kit para criar GIFs animados otimizados para o Slack, com validadores de tamanho e primitivas de animação combináveis. Esta skill é aplicada sempre que um usuário solicitar GIFs animados ou animações de emoji para o Slack.

O que é slack-gif-creator?

O slack-gif-creator é um kit de ferramentas flexível projetado para criar GIFs animados que atendam às restrições técnicas do Slack, tanto para mensagens quanto para emojis. Ele fornece validadores rigorosos que verificam limites de tamanho de arquivo (2MB para mensagens, 64KB para emojis), dimensões ideais (480x480 para mensagens, 128x128 para emojis), FPS típico e paletas de cores recomendadas. Além dos validadores, a skill oferece um rico conjunto de primitivas de animação combináveis — como shake, bounce, spin, pulse, fade, zoom, explode, wiggle, slide, flip, morph, move e efeitos caleidoscópio — que podem ser misturados livremente para criar animações personalizadas. Utilitários auxiliares opcionais, como um construtor de GIFs (GIFBuilder) com otimização automática, renderização de texto com contorno, paletas de cores predefinidas, sistemas de partículas e funções de easing, facilitam a criação de animações com aparência profissional. A ferramenta segue a filosofia de liberdade criativa dentro dos limites técnicos do Slack, permitindo que o desenvolvedor ou agente de IA projete animações em fases (antecipação, ação, reação) e itere conforme necessário para cumprir as restrições de tamanho. Exemplos completos de código mostram como compor primitivas para criar reações simples, ações com impacto e movimentos combinados com shake. As dependências incluem as bibliotecas Python pillow, imageio e numpy.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ComposioHQ/awesome-codex-skills/tree/main/slack-gif-creator

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Criador de GIFs para Slack - Toolkit Flexível

Um toolkit para criar GIFs animados otimizados para o Slack. Fornece validadores para as restrições do Slack, primitivas de animação combináveis e utilitários auxiliares opcionais. Aplique estas ferramentas conforme necessário para alcançar a visão criativa.

Requisitos do Slack

O Slack tem requisitos específicos para GIFs com base no seu uso:

GIFs para Mensagens:

  • Tamanho máximo: ~2MB
  • Dimensões ideais: 480x480
  • FPS típico: 15-20
  • Limite de cores: 128-256
  • Duração: 2-5s

GIFs para Emojis:

  • Tamanho máximo: 64KB (limite rigoroso)
  • Dimensões ideais: 128x128
  • FPS típico: 10-12
  • Limite de cores: 32-48
  • Duração: 1-2s

GIFs para Emojis são desafiadores - o limite de 64KB é rigoroso. Estratégias que ajudam:

  • Limitar a 10-15 quadros no total
  • Usar no máximo 32-48 cores
  • Manter os designs simples
  • Evitar gradientes
  • Validar o tamanho do arquivo com frequência

Estrutura do Toolkit

Esta skill fornece três tipos de ferramentas:

  1. Validadores - Verificam se um GIF atende aos requisitos do Slack
  2. Primitivas de Animação - Blocos de construção combináveis para movimento (tremer, quicar, mover, caleidoscópio)
  3. Utilitários Auxiliares - Funções opcionais para necessidades comuns (texto, cores, efeitos)

A liberdade criativa completa está disponível em como essas ferramentas são aplicadas.

Validadores Principais

Para garantir que um GIF atenda às restrições do Slack, use estes validadores:

from core.gif_builder import GIFBuilder

# Após criar seu GIF, verifique se atende aos requisitos
builder = GIFBuilder(width=128, height=128, fps=10)
# ... adicione seus quadros como quiser ...

# Salve e verifique o tamanho
info = builder.save('emoji.gif', num_colors=48, optimize_for_emoji=True)

# O método save avisa automaticamente se o arquivo exceder os limites
# info dict contém: size_kb, size_mb, frame_count, duration_seconds

Validador de tamanho de arquivo:

from core.validators import check_slack_size

# Verifique se o GIF atende aos limites de tamanho
passes, info = check_slack_size('emoji.gif', is_emoji=True)
# Retorna: (True/False, dict com detalhes de tamanho)

Validador de dimensões:

from core.validators import validate_dimensions

# Verifique as dimensões
passes, info = validate_dimensions(128, 128, is_emoji=True)
# Retorna: (True/False, dict com detalhes da dimensão)

Validação completa:

from core.validators import validate_gif, is_slack_ready

# Execute todas as validações
all_pass, results = validate_gif('emoji.gif', is_emoji=True)

# Ou verificação rápida
if is_slack_ready('emoji.gif', is_emoji=True):
    print("Pronto para carregar!")

Primitivas de Animação

Estes são blocos de construção combináveis para movimento. Aplique-os a qualquer objeto em qualquer combinação:

Tremer (Shake)

from templates.shake import create_shake_animation

# Tremer um emoji
frames = create_shake_animation(
    object_type='emoji',
    object_data={'emoji': '😱', 'size': 80},
    num_frames=20,
    shake_intensity=15,
    direction='both'  # ou 'horizontal', 'vertical'
)

Quicar (Bounce)

from templates.bounce import create_bounce_animation

# Quicar um círculo
frames = create_bounce_animation(
    object_type='circle',
    object_data={'radius': 40, 'color': (255, 100, 100)},
    num_frames=30,
    bounce_height=150
)

Girar / Rotacionar (Spin / Rotate)

from templates.spin import create_spin_animation, create_loading_spinner

# Giro horário
frames = create_spin_animation(
    object_type='emoji',
    object_data={'emoji': '🔄', 'size': 100},
    rotation_type='clockwise',
    full_rotations=2
)

# Rotação oscilante
frames = create_spin_animation(rotation_type='wobble', full_rotations=3)

# Spinner de carregamento
frames = create_loading_spinner(spinner_type='dots')

Pulsar / Batimento Cardíaco (Pulse / Heartbeat)

from templates.pulse import create_pulse_animation, create_attention_pulse

# Pulso suave
frames = create_pulse_animation(
    object_data={'emoji': '❤️', 'size': 100},
    pulse_type='smooth',
    scale_range=(0.8, 1.2)
)

# Batimento cardíaco (dupla pulsação)
frames = create_pulse_animation(pulse_type='heartbeat')

# Pulso de atenção para GIFs de emoji
frames = create_attention_pulse(emoji='⚠️', num_frames=20)

Desaparecer (Fade)

from templates.fade import create_fade_animation, create_crossfade

# Aparecer
frames = create_fade_animation(fade_type='in')

# Desaparecer
frames = create_fade_animation(fade_type='out')

# Transição entre dois emojis
frames = create_crossfade(
    object1_data={'emoji': '😊', 'size': 100},
    object2_data={'emoji': '😂', 'size': 100}
)

Zoom

from templates.zoom import create_zoom_animation, create_explosion_zoom

# Zoom para dentro dramaticamente
frames = create_zoom_animation(
    zoom_type='in',
    scale_range=(0.1, 2.0),
    add_motion_blur=True
)

# Zoom para fora
frames = create_zoom_animation(zoom_type='out')

# Zoom explosivo
frames = create_explosion_zoom(emoji='💥')

Explodir / Fragmentar (Explode / Shatter)

from templates.explode import create_explode_animation, create_particle_burst

# Explosão em rajada
frames = create_explode_animation(
    explode_type='burst',
    num_pieces=25
)

# Efeito de fragmentação
frames = create_explode_animation(explode_type='shatter')

# Dissolver em partículas
frames = create_explode_animation(explode_type='dissolve')

# Rajada de partículas
frames = create_particle_burst(particle_count=30)

Balançar / Agitar (Wiggle / Jiggle)

from templates.wiggle import create_wiggle_animation, create_excited_wiggle

# Balanço gelatinoso
frames = create_wiggle_animation(
    wiggle_type='jello',
    intensity=1.0,
    cycles=2
)

# Movimento de onda
frames = create_wiggle_animation(wiggle_type='wave')

# Balanço animado para GIFs de emoji
frames = create_excited_wiggle(emoji='🎉')

Deslizar (Slide)

from templates.slide import create_slide_animation, create_multi_slide

# Deslizar da esquerda com ultrapassagem
frames = create_slide_animation(
    direction='left',
    slide_type='in',
    overshoot=True
)

# Deslizar atravessando
frames = create_slide_animation(direction='left', slide_type='across')

# Múltiplos objetos deslizando em sequência
objects = [
    {'data': {'emoji': '🎯', 'size': 60}, 'direction': 'left', 'final_pos': (120, 240)},
    {'data': {'emoji': '🎪', 'size': 60}, 'direction': 'right', 'final_pos': (240, 240)}
]
frames = create_multi_slide(objects, stagger_delay=5)

Virar (Flip)

from templates.flip import create_flip_animation, create_quick_flip

# Virada horizontal entre dois emojis
frames = create_flip_animation(
    object1_data={'emoji': '😊', 'size': 120},
    object2_data={'emoji': '😂', 'size': 120},
    flip_axis='horizontal'
)

# Virada vertical
frames = create_flip_animation(flip_axis='vertical')

# Virada rápida para GIFs de emoji
frames = create_quick_flip('👍', '👎')

Transformar / Metamorfosear (Morph / Transform)

from templates.morph import create_morph_animation, create_reaction_morph

# Transformação com transição
frames = create_morph_animation(
    object1_data={'emoji': '😊', 'size': 100},
    object2_data={'emoji': '😂', 'size': 100},
    morph_type='crossfade'
)

# Transformação por escala (encolhe enquanto o outro cresce)
frames = create_morph_animation(morph_type='scale')

# Transformação giratória (semelhante a virada 3D)
frames = create_morph_animation(morph_type='spin_morph')

Efeito de Movimento (Move Effect)

from templates.move import create_move_animation

# Movimento linear
frames = create_move_animation(
    object_type='emoji',
    object_data={'emoji': '🚀', 'size': 60},
    start_pos=(50, 240),
    end_pos=(430, 240),
    motion_type='linear',
    easing='ease_out'
)

# Movimento em arco (trajetória parabólica)
frames = create_move_animation(
    object_type='emoji',
    object_data={'emoji': '⚽', 'size': 60},
    start_pos=(50, 350),
    end_pos=(430, 350),
    motion_type='arc',
    motion_params={'arc_height': 150}
)

# Movimento circular
frames = create_move_animation(
    object_type='emoji',
    object_data={'emoji': '🌍', 'size': 50},
    motion_type='circle',
    motion_params={
        'center': (240, 240),
        'radius': 120,
        'angle_range': 360  # círculo completo
    }
)

# Movimento de onda
frames = create_move_animation(
    motion_type='wave',
    motion_params={
        'wave_amplitude': 50,
        'wave_frequency': 2
    }
)

# Ou use funções de easing de baixo nível
from core.easing import interpolate, calculate_arc_motion

for i in range(num_frames):
    t = i / (num_frames - 1)
    x = interpolate(start_x, end_x, t, easing='ease_out')
    # Ou: x, y = calculate_arc_motion(start, end, height, t)

Efeito Caleidoscópio (Kaleidoscope Effect)

from templates.kaleidoscope import apply_kaleidoscope, create_kaleidoscope_animation

# Aplicar a um único quadro
kaleido_frame = apply_kaleidoscope(frame, segments=8)

# Ou criar animação caleidoscópica
frames = create_kaleidoscope_animation(
    base_frame=my_frame,  # ou None para padrão de demonstração
    num_frames=30,
    segments=8,
    rotation_speed=1.0
)

# Efeitos de espelho simples (mais rápidos)
from templates.kaleidoscope import apply_simple_mirror

mirrored = apply_simple_mirror(frame, mode='quad')  # Espelho 4 vias
# modos: 'horizontal', 'vertical', 'quad', 'radial'

Para compor primitivas livremente, siga estes padrões:

# Exemplo: Quicar + tremer para impacto
for i in range(num_frames):
    frame = create_blank_frame(480, 480, bg_color)

    # Movimento de quicar
    t_bounce = i / (num_frames - 1)
    y = interpolate(start_y, ground_y, t_bounce, 'bounce_out')

    # Adicionar tremor no impacto (quando y atinge o chão)
    if y >= ground_y - 5:
        shake_x = math.sin(i * 2) * 10
        x = center_x + shake_x
    else:
        x = center_x

    draw_emoji(frame, '⚽', (x, y), size=60)
    builder.add_frame(frame)

Utilitários Auxiliares

Estes são auxiliares opcionais para necessidades comuns. Use, modifique ou substitua estes por implementações personalizadas conforme necessário.

Construtor de GIF (Montagem e Otimização)

from core.gif_builder import GIFBuilder

# Crie o construtor com suas configurações escolhidas
builder = GIFBuilder(width=480, height=480, fps=20)

# Adicione quadros (como você os criou)
for frame in my_frames:
    builder.add_frame(frame)

# Salve com otimização
builder.save('output.gif',
             num_colors=128,
             optimize_for_emoji=False)

Principais características:

  • Quantização automática de cores
  • Remoção de quadros duplicados
  • Avisos de tamanho para limites do Slack
  • Modo emoji (otimização agressiva)

Renderização de Texto

Para GIFs pequenos como emojis, a legibilidade do texto é desafiadora. Uma solução comum envolve adicionar contornos:

from core.typography import draw_text_with_outline, TYPOGRAPHY_SCALE

# Texto com contorno (ajuda na legibilidade)
draw_text_with_outline(
    frame, "BONK!",
    position=(240, 100),
    font_size=TYPOGRAPHY_SCALE['h1'],  # 60px
    text_color=(255, 68, 68),
    outline_color=(0, 0, 0),
    outline_width=4,
    centered=True
)

Para implementar renderização de texto personalizada, use ImageDraw.text() do PIL, que funciona bem para GIFs maiores.

Gerenciamento de Cores

GIFs com aparência profissional geralmente usam paletas de cores coesas:

from core.color_palettes import get_palette

# Obter uma paleta pronta
palette = get_palette('vibrant')  # ou 'pastel', 'dark', 'neon', 'professional'

bg_color = palette['background']
text_color = palette['primary']
accent_color = palette['accent']

Para trabalhar com cores diretamente, use tuplas RGB - o que funcionar para o caso de uso.

Efeitos Visuais

Efeitos opcionais para momentos de impacto:

from core.visual_effects import ParticleSystem, create_impact_flash, create_shockwave_rings

# Sistema de partículas
particles = ParticleSystem()
particles.emit_sparkles(x=240, y=200, count=15)
particles.emit_confetti(x=240, y=200, count=20)

# Atualizar e renderizar cada quadro
particles.update()
particles.render(frame)

# Efeito de flash
frame = create_impact_flash(frame, position=(240, 200), radius=100)

# Anéis de onda de choque
frame = create_shockwave_rings(frame, position=(240, 200), radii=[30, 60, 90])

Funções de Easing

Movimento suave usa easing em vez de interpolação linear:

from core.easing import interpolate

# Objeto caindo (acelera)
y = interpolate(start=0, end=400, t=progress, easing='ease_in')

# Objeto aterrissando (desacelera)
y = interpolate(start=0, end=400, t=progress, easing='ease_out')

# Quicando
y = interpolate(start=0, end=400, t=progress, easing='bounce_out')

# Ultrapassagem (elástico)
scale = interpolate(start=0.5, end=1.0, t=progress, easing='elastic_out')

Easings disponíveis: linear, ease_in, ease_out, ease_in_out, bounce_out, elastic_out, back_out (ultrapassagem) e mais em core/easing.py.

Composição de Quadros

Utilitários básicos de desenho, se precisar:

from core.frame_composer import (
    create_gradient_background,  # Fundos gradientes
    draw_emoji_enhanced,         # Emoji com sombra opcional
    draw_circle_with_shadow,     # Formas com profundidade
    draw_star                    # Estrelas de 5 pontas
)

# Fundo gradiente
frame = create_gradient_background(480, 480, top_color, bottom_color)

# Emoji com sombra
draw_emoji_enhanced(frame, '🎉', position=(200, 200), size=80, shadow=True)

Estratégias de Otimização

Quando seu GIF estiver muito grande:

Para GIFs de Mensagens (>2MB):

  1. Reduza quadros (menor FPS ou duração mais curta)
  2. Reduza cores (128 → 64 cores)
  3. Reduza dimensões (480x480 → 320x320)
  4. Ative a remoção de quadros duplicados

Para GIFs de Emoji (>64KB) - seja agressivo:

  1. Limite a 10-12 quadros no total
  2. Use no máximo 32-40 cores
  3. Evite gradientes (cores sólidas comprimem melhor)
  4. Simplifique o design (menos elementos)
  5. Use optimize_for_emoji=True no método save

Exemplos de Padrões de Composição

Reação Simples (Pulsando)

builder = GIFBuilder(128, 128, 10)

for i in range(12):
    frame = Image.new('RGB', (128, 128), (240, 248, 255))

    # Escala pulsante
    scale = 1.0 + math.sin(i * 0.5) * 0.15
    size = int(60 * scale)

    draw_emoji_enhanced(frame, '😱', position=(64-size//2, 64-size//2),
                       size=size, shadow=False)
    builder.add_frame(frame)

builder.save('reaction.gif', num_colors=40, optimize_for_emoji=True)

# Validar
from core.validators import check_slack_size
check_slack_size('reaction.gif', is_emoji=True)

Impacto com Efeitos

builder = GIFBuilder(480, 480, 20)

for i in range(30):
    frame = Image.new('RGB', (480, 480), (255, 255, 255))
    t = i / 29  # progresso

    if i < 5:
        # Quadros iniciais: zoom de ataque
        scale = 1.0 + (5 - i) * 0.2
        size = int(60 * scale)
        x, y = 240, 300 - (5 - i) * 40
    elif i == 5:
        # Quadro de impacto: flash
        frame = create_impact_flash(frame, (240, 240), 150)
        x, y = 240, 240
        size = 60
    else:
        # Quadros posteriores: tremor
        shake = math.sin((i - 5) * 3) * (15 - (i - 5))
        x, y = 240 + shake, 240
        size = 60

    draw_emoji_enhanced(frame, '💥', (x - size//2, y - size//2),
                       size=size, shadow=True)
    builder.add_frame(frame)

builder.save('impact.gif', num_colors=128)

Transição com Deslizar e Desaparecer

from templates.slide import create_slide_animation
from templates.fade import create_crossfade

# Primeiro: slide in
slide_frames = create_slide_animation(
    object_type='emoji',
    object_data={'emoji': '😊', 'size': 80},
    direction='left',
    slide_type='in',
    overshoot=False,
    num_frames=15
)

# Depois: crossfade para 😂
crossfade_frames = create_crossfade(
    object1_data={'emoji': '😊', 'size': 80},
    object2_data={'emoji': '😂', 'size': 80},
    num_frames=10
)

# Combinar todas as sequências
builder = GIFBuilder(128, 128, 10)
for frame in slide_frames:
    builder.add_frame(frame)
for frame in crossfade_frames:
    builder.add_frame(frame)

builder.save('reaction_sequence.gif', num_colors=40, optimize_for_emoji=True)

Boas Práticas e Dicas

Diretrizes de Design

  1. Comece pequeno - Para emojis, sempre comece com 10-12 quadros. É mais fácil adicionar do que remover.
  2. Valide cedo, valide frequentemente - Use check_slack_size() no meio do processo.
  3. Evite gradientes para emojis - Eles são grandes em termos de compressão. Use cores sólidas.
  4. Use desfoque de movimento com moderação - Pode aumentar significativamente o tamanho do arquivo.
  5. Regra de ouro para emojis: mais simples é melhor - Emojis com designs limpos e cores limitadas têm melhor desempenho.

Escolha de Primitivas

  • Para chamar a atenção: Pulse, Wiggle, Explode
  • Para movimento: Shake, Bounce, Slide, Move
  • Para transformação: Morph, Flip, Fade
  • Para efeitos: Kaleidoscope, Zoom, Particle Effects

Combinações Criativas

  • Bounce + Shake = Impacto (bola quicando que treme ao pousar)
  • Slide + Fade = Aparição suave (deslizar enquanto aparece)
  • Pulse + Wiggle = Entusiasmo (emoji animado pulsando)
  • Spin + Zoom = Revelação dramática (girar enquanto aumenta)
  • Kaleidoscope + Rotate = Efeito hipnótico

Lembre-se: Todas as primitivas podem ser combinadas, encadeadas, sobrepostas e personalizadas. Essas ferramentas são blocos de construção - sinta-se à vontade para adaptá-las de qualquer forma que atinja sua visão criativa.

Tratamento de Erros

from core.exceptions import SlackGIFError, SizeLimitError

try:
    builder.save('output.gif')
except SizeLimitError as e:
    print(f"GIF muito grande: {e.size_kb}KB")
    print(f"Limite: {e.limit_kb}KB")
    # Aplicar otimizações
except SlackGIFError as e:
    print(f"Erro de validação: {e}")

Personalização Avançada

Para controle total sobre a animação:

# Modificar parâmetros de movimento existentes
from templates.shake import ShakeConfig

config = ShakeConfig(
    intensity=20,
    frequency=3.0,
    decay=0.95,  # tremor diminui com o tempo
    direction='both'
)
frames = create_shake_animation(
    object_type='emoji',
    object_data={'emoji': '😱', 'size': 80},
    num_frames=30,
    config=config
)

Para animações complexas que exigem controle quadro a quadro, use a abordagem de composição direta:

for i in range(num_frames):
    frame = create_base_frame()
    
    # Aplicar múltiplos efeitos
    frame = apply_effect1(frame, params_i1)
    frame = apply_effect2(frame, params_i2)
    
    builder.add_frame(frame)

Recursos-chave:

  • core/frame_composer.py - Utilitários de composição de quadros
  • core/easing.py - Funções de easing para movimento suave
  • core/color_palettes.py - Paletas de cores predefinidas
  • core/visual_effects.py - Efeitos especiais (partículas, flashes)
  • core/typography.py - Utilitários de texto com contorno para legibilidade

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

ComposioHQ/-21risk-automation

Automate 21risk tasks via Rube MCP (Composio). Always search tools first for current schemas.

ComposioHQ/-2chat-automation

Automate 2chat tasks via Rube MCP (Composio). Always search tools first for current schemas.

ComposioHQ/ably-automation

Automate Ably tasks via Rube MCP (Composio). Always search tools first for current schemas.

ComposioHQ/abstract-automation

Automate Abstract tasks via Rube MCP (Composio). Always search tools first for current schemas.

ComposioHQ/abuselpdb-automation

Automate Abuselpdb tasks via Rube MCP (Composio). Always search tools first for current schemas.

ComposioHQ/abyssale-automation

Automate Abyssale tasks via Rube MCP (Composio). Always search tools first for current schemas.

ComposioHQ/accelo-automation

Automate Accelo tasks via Rube MCP (Composio). Always search tools first for current schemas.

ComposioHQ/accredible-certificates-automation

Automate Accredible Certificates tasks via Rube MCP (Composio). Always search tools first for current schemas.

ComposioHQ/acculynx-automation

Automate Acculynx tasks via Rube MCP (Composio). Always search tools first for current schemas.

ComposioHQ/active-campaign-automation

Automate ActiveCampaign tasks via Rube MCP (Composio). Always search tools first for current schemas.

ComposioHQ/addresszen-automation

Automate Addresszen tasks via Rube MCP (Composio). Always search tools first for current schemas.

ComposioHQ/adobe-automation

Automate Adobe tasks via Rube MCP (Composio). Always search tools first for current schemas.

ComposioHQ/adrapid-automation

Automate Adrapid tasks via Rube MCP (Composio). Always search tools first for current schemas.

ComposioHQ/adyntel-automation

Automate Adyntel tasks via Rube MCP (Composio). Always search tools first for current schemas.

ComposioHQ/aeroleads-automation

Automate Aeroleads tasks via Rube MCP (Composio). Always search tools first for current schemas.

ComposioHQ/aero-workflow-automation

Automate Aero Workflow tasks via Rube MCP (Composio). Always search tools first for current schemas.

ComposioHQ/affinda-automation

Automate Affinda tasks via Rube MCP (Composio). Always search tools first for current schemas.

ComposioHQ/affinity-automation

Automate Affinity tasks via Rube MCP (Composio). Always search tools first for current schemas.

ComposioHQ/agencyzoom-automation

Automate Agencyzoom tasks via Rube MCP (Composio). Always search tools first for current schemas.

ComposioHQ/agent-deep-links

Build, validate, and troubleshoot deep links for Codex, Cursor, VS Code, Visual Studio, and similar tools. Use when users ask for clickable links (especially in Slack) that open threads, files, folders, or app settings.

Habilidades Relacionadas