关于 slack-gif-creator
slack-gif-creator 是用于制作 Slack 动图的工具包,适合需要生成消息 GIF 或表情 GIF 的创作者。它提供可组合的动画构件、组装优化工具及 Slack 尺寸和文件大小验证器。
主要功能
- 01验证文件大小和尺寸
- 02组合多种动画效果
- 03使用 GIFBuilder 组装与优化
- 04提供文本、颜色和视觉效果工具
- 05针对表情 GIF 优化
适用场景
- 01制作符合 Slack 限制的消息 GIF
- 02创建体积受限的表情 GIF
- 03组合动画效果制作反应动图
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ composiohq/ awesome-claude-skills --skill slack-gif-creator安装后在 Claude Code 中输入/slack-gif-creator确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSE.txtrequirements.txtcore/color_palettes.pyeasing.pyframe_composer.pygif_builder.pytypography.pyvalidators.pyvisual_effects.pytemplates/bounce.pyexplode.pyfade.pyflip.pykaleidoscope.pymorph.pymove.pypulse.pyshake.pyslide.pyspin.pywiggle.pyzoom.py详细介绍
Slack GIF Creator - 灵活工具包
一个用于创建针对 Slack 优化的动画 GIF 的工具包。提供用于检查 Slack 限制的验证器、可组合的动画基元,以及可选的辅助工具。可按需应用这些工具,实现创意构想。
Slack 的要求
Slack 会根据 GIF 的用途设定具体要求:
消息 GIF:
- 最大大小:约 2MB
- 最佳尺寸:480x480
- 常见 FPS:15-20
- 颜色限制:128-256
- 时长:2-5s
表情 GIF:
- 最大大小:64KB(严格限制)
- 最佳尺寸:128x128
- 常见 FPS:10-12
- 颜色限制:32-48
- 时长:1-2s
表情 GIF 的制作颇具挑战——64KB 的限制非常严格。以下策略有助于控制大小:
- 总帧数限制在 10-15 帧
- 最多使用 32-48 种颜色
- 保持设计简洁
- 避免渐变
- 经常验证文件大小
工具包结构
此技能提供三类工具:
- 验证器 - 检查 GIF 是否符合 Slack 的要求
- 动画基元 - 可组合的运动构建模块(抖动、弹跳、移动、万花筒)
- 辅助工具 - 用于常见需求的可选函数(文本、颜色、效果)
如何应用这些工具,完全由你自由决定。
核心验证器
要确保 GIF 符合 Slack 的限制,请使用以下验证器:
from core.gif_builder import GIFBuilder
# After creating your GIF, check if it meets requirements
builder = GIFBuilder(width=128, height=128, fps=10)
# ... add your frames however you want ...
# Save and check size
info = builder.save('emoji.gif', num_colors=48, optimize_for_emoji=True)
# The save method automatically warns if file exceeds limits
# info dict contains: size_kb, size_mb, frame_count, duration_seconds
文件大小验证器:
from core.validators import check_slack_size
# Check if GIF meets size limits
passes, info = check_slack_size('emoji.gif', is_emoji=True)
# Returns: (True/False, dict with size details)
尺寸验证器:
from core.validators import validate_dimensions
# Check dimensions
passes, info = validate_dimensions(128, 128, is_emoji=True)
# Returns: (True/False, dict with dimension details)
完整验证:
from core.validators import validate_gif, is_slack_ready
# Run all validations
all_pass, results = validate_gif('emoji.gif', is_emoji=True)
# Or quick check
if is_slack_ready('emoji.gif', is_emoji=True):
print("Ready to upload!")
动画基元
这些是可组合的运动构建模块。可对任意对象以任意组合方式应用:
抖动
from templates.shake import create_shake_animation
# Shake an emoji
frames = create_shake_animation(
object_type='emoji',
object_data={'emoji': '😱', 'size': 80},
num_frames=20,
shake_intensity=15,
direction='both' # or 'horizontal', 'vertical'
)
弹跳
from templates.bounce import create_bounce_animation
# Bounce a circle
frames = create_bounce_animation(
object_type='circle',
object_data={'radius': 40, 'color': (255, 100, 100)},
num_frames=30,
bounce_height=150
)
旋转
from templates.spin import create_spin_animation, create_loading_spinner
# Clockwise spin
frames = create_spin_animation(
object_type='emoji',
object_data={'emoji': '🔄', 'size': 100},
rotation_type='clockwise',
full_rotations=2
)
# Wobble rotation
frames = create_spin_animation(rotation_type='wobble', full_rotations=3)
# Loading spinner
frames = create_loading_spinner(spinner_type='dots')
脉动 / 心跳
from templates.pulse import create_pulse_animation, create_attention_pulse
# Smooth pulse
frames = create_pulse_animation(
object_data={'emoji': '❤️', 'size': 100},
pulse_type='smooth',
scale_range=(0.8, 1.2)
)
# Heartbeat (double-pump)
frames = create_pulse_animation(pulse_type='heartbeat')
# Attention pulse for emoji GIFs
frames = create_attention_pulse(emoji='⚠️', num_frames=20)
淡入淡出
from templates.fade import create_fade_animation, create_crossfade
# Fade in
frames = create_fade_animation(fade_type='in')
# Fade out
frames = create_fade_animation(fade_type='out')
# Crossfade between two emojis
frames = create_crossfade(
object1_data={'emoji': '😊', 'size': 100},
object2_data={'emoji': '😂', 'size': 100}
)
缩放
from templates.zoom import create_zoom_animation, create_explosion_zoom
# Zoom in dramatically
frames = create_zoom_animation(
zoom_type='in',
scale_range=(0.1, 2.0),
add_motion_blur=True
)
# Zoom out
frames = create_zoom_animation(zoom_type='out')
# Explosion zoom
frames = create_explosion_zoom(emoji='💥')
爆炸 / 粉碎
from templates.explode import create_explode_animation, create_particle_burst
# Burst explosion
frames = create_explode_animation(
explode_type='burst',
num_pieces=25
)
# Shatter effect
frames = create_explode_animation(explode_type='shatter')
# Dissolve into particles
frames = create_explode_animation(explode_type='dissolve')
# Particle burst
frames = create_particle_burst(particle_count=30)
摆动 / 抖动
from templates.wiggle import create_wiggle_animation, create_excited_wiggle
# Jello wobble
frames = create_wiggle_animation(
wiggle_type='jello',
intensity=1.0,
cycles=2
)
# Wave motion
frames = create_wiggle_animation(wiggle_type='wave')
# Excited wiggle for emoji GIFs
frames = create_excited_wiggle(emoji='🎉')
滑动
from templates.slide import create_slide_animation, create_multi_slide
# Slide in from left with overshoot
frames = create_slide_animation(
direction='left',
slide_type='in',
overshoot=True
)
# Slide across
frames = create_slide_animation(direction='left', slide_type='across')
# Multiple objects sliding in sequence
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)
翻转
from templates.flip import create_flip_animation, create_quick_flip
# Horizontal flip between two emojis
frames = create_flip_animation(
object1_data={'emoji': '😊', 'size': 120},
object2_data={'emoji': '😂', 'size': 120},
flip_axis='horizontal'
)
# Vertical flip
frames = create_flip_animation(flip_axis='vertical')
# Quick flip for emoji GIFs
frames = create_quick_flip('👍', '👎')
变形 / 转换
from templates.morph import create_morph_animation, create_reaction_morph
# Crossfade morph
frames = create_morph_animation(
object1_data={'emoji': '😊', 'size': 100},
object2_data={'emoji': '😂', 'size': 100},
morph_type='crossfade'
)
# Scale morph (shrink while other grows)
frames = create_morph_animation(morph_type='scale')
# Spin morph (3D flip-like)
frames = create_morph_animation(morph_type='spin_morph')
移动效果
from templates.move import create_move_animation
# Linear movement
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'
)
# Arc movement (parabolic trajectory)
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}
)
# Circular movement
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 # full circle
}
)
# Wave movement
frames = create_move_animation(
motion_type='wave',
motion_params={
'wave_amplitude': 50,
'wave_frequency': 2
}
)
# Or use low-level easing functions
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')
# Or: x, y = calculate_arc_motion(start, end, height, t)
万花筒效果
from templates.kaleidoscope import apply_kaleidoscope, create_kaleidoscope_animation
# Apply to a single frame
kaleido_frame = apply_kaleidoscope(frame, segments=8)
# Or create animated kaleidoscope
frames = create_kaleidoscope_animation(
base_frame=my_frame, # or None for demo pattern
num_frames=30,
segments=8,
rotation_speed=1.0
)
# Simple mirror effects (faster)
from templates.kaleidoscope import apply_simple_mirror
mirrored = apply_simple_mirror(frame, mode='quad') # 4-way mirror
# modes: 'horizontal', 'vertical', 'quad', 'radial'
如需自由组合基元,请遵循以下模式:
# Example: Bounce + shake for impact
for i in range(num_frames):
frame = create_blank_frame(480, 480, bg_color)
# Bounce motion
t_bounce = i / (num_frames - 1)
y = interpolate(start_y, ground_y, t_bounce, 'bounce_out')
# Add shake on impact (when y reaches ground)
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)
辅助工具
这些是满足常见需求的可选辅助工具。可按需使用、修改或替换为自定义实现。
GIF 构建器(组装与优化)
from core.gif_builder import GIFBuilder
# Create builder with your chosen settings
builder = GIFBuilder(width=480, height=480, fps=20)
# Add frames (however you created them)
for frame in my_frames:
builder.add_frame(frame)
# Save with optimization
builder.save('output.gif',
num_colors=128,
optimize_for_emoji=False)
主要功能:
- 自动量化颜色
- 移除重复帧
- 针对 Slack 限制发出大小警告
- 表情模式(激进优化)
文本渲染
对于表情等小型 GIF,文本可读性较难保证。常见的解决方法是添加描边:
from core.typography import draw_text_with_outline, TYPOGRAPHY_SCALE
# Text with outline (helps readability)
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
)
如需实现自定义文本渲染,可使用 PIL 的 ImageDraw.text(),它适用于较大的 GIF。
颜色管理
专业美观的 GIF 通常使用协调统一的调色板:
from core.color_palettes import get_palette
# Get a pre-made palette
palette = get_palette('vibrant') # or 'pastel', 'dark', 'neon', 'professional'
bg_color = palette['background']
text_color = palette['primary']
accent_color = palette['accent']
如需直接处理颜色,可使用 RGB 元组——选择适合具体场景的方式即可。
视觉效果
可在强调时刻使用的可选效果:
from core.visual_effects import ParticleSystem, create_impact_flash, create_shockwave_rings
# Particle system
particles = ParticleSystem()
particles.emit_sparkles(x=240, y=200, count=15)
particles.emit_confetti(x=240, y=200, count=20)
# Update and render each frame
particles.update()
particles.render(frame)
# Flash effect
frame = create_impact_flash(frame, position=(240, 200), radius=100)
# Shockwave rings
frame = create_shockwave_rings(frame, position=(240, 200), radii=[30, 60, 90])
缓动函数
平滑运动使用缓动,而非线性插值:
from core.easing import interpolate
# Object falling (accelerates)
y = interpolate(start=0, end=400, t=progress, easing='ease_in')
# Object landing (decelerates)
y = interpolate(start=0, end=400, t=progress, easing='ease_out')
# Bouncing
y = interpolate(start=0, end=400, t=progress, easing='bounce_out')
# Overshoot (elastic)
scale = interpolate(start=0.5, end=1.0, t=progress, easing='elastic_out')
可用的缓动包括:linear、ease_in、ease_out、ease_in_out、bounce_out、elastic_out、back_out(过冲),以及 core/easing.py 中的更多函数。
帧合成
如有需要,可使用以下基础绘图工具:
from core.frame_composer import (
create_gradient_background, # Gradient backgrounds
draw_emoji_enhanced, # Emoji with optional shadow
draw_circle_with_shadow, # Shapes with depth
draw_star # 5-pointed stars
)
# Gradient background
frame = create_gradient_background(480, 480, top_color, bottom_color)
# Emoji with shadow
draw_emoji_enhanced(frame, '🎉', position=(200, 200), size=80, shadow=True)
优化策略
当 GIF 文件过大时:
消息 GIF(>2MB):
- 减少帧数(降低 FPS 或缩短时长)
- 减少颜色(从 128 种降至 64 种)
- 缩小尺寸(从 480x480 降至 320x320)
- 启用重复帧移除
表情 GIF(>64KB)——应大幅优化:
- 总帧数限制在 10-12 帧
- 最多使用 32-40 种颜色
- 避免渐变(纯色压缩效果更好)
- 简化设计(减少元素)
- 在保存方法中使用
optimize_for_emoji=True
组合模式示例
简单反应(脉动)
builder = GIFBuilder(128, 128, 10)
for i in range(12):
frame = Image.new('RGB', (128, 128), (240, 248, 255))
# Pulsing scale
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)
# Validate
from core.validators import check_slack_size
check_slack_size('reaction.gif', is_emoji=True)
带冲击效果的动作(弹跳 + 闪光)
builder = GIFBuilder(480, 480, 20)
# Phase 1: Object falls
for i in range(15):
frame = create_gradient_background(480, 480, (240, 248, 255), (200, 230, 255))
t = i / 14
y = interpolate(0, 350, t, 'ease_in')
draw_emoji_enhanced(frame, '⚽', position=(220, int(y)), size=80)
builder.add_frame(frame)
# Phase 2: Impact + flash
for i in range(8):
frame = create_gradient_background(480, 480, (240, 248, 255), (200, 230, 255))
# Flash on first frames
if i < 3:
frame = create_impact_flash(frame, (240, 350), radius=120, intensity=0.6)
draw_emoji_enhanced(frame, '⚽', position=(220, 350), size=80)
# Text appears
if i > 2:
draw_text_with_outline(frame, "GOAL!", position=(240, 150),
font_size=60, text_color=(255, 68, 68),
outline_color=(0, 0, 0), outline_width=4, centered=True)
builder.add_frame(frame)
builder.save('goal.gif', num_colors=128)
组合基元(移动 + 抖动)
from templates.shake import create_shake_animation
# Create shake animation
shake_frames = create_shake_animation(
object_type='emoji',
object_data={'emoji': '😰', 'size': 70},
num_frames=20,
shake_intensity=12
)
# Create moving element that triggers the shake
builder = GIFBuilder(480, 480, 20)
for i in range(40):
t = i / 39
if i < 20:
# Before trigger - use blank frame with moving object
frame = create_blank_frame(480, 480, (255, 255, 255))
x = interpolate(50, 300, t * 2, 'linear')
draw_emoji_enhanced(frame, '🚗', position=(int(x), 300), size=60)
draw_emoji_enhanced(frame, '😰', position=(350, 200), size=70)
else:
# After trigger - use shake frame
frame = shake_frames[i - 20]
# Add the car in final position
draw_emoji_enhanced(frame, '🚗', position=(300, 300), size=60)
builder.add_frame(frame)
builder.save('scare.gif')
理念
这个工具包提供的是构建模块,而非固定配方。处理 GIF 请求时:
- 理解创作构想 - 需要发生什么?氛围如何?
- 设计动画 - 将其拆分为多个阶段(预备、动作、反应)
- 按需应用基本元素 - 抖动、弹跳、移动、特效——自由组合
- 验证限制 - 检查文件大小,尤其是表情符号 GIF
- 按需迭代 - 如果超出大小限制,则减少帧数或颜色
目标是在 Slack 的技术限制内释放创作自由。
依赖项
使用此工具包前,仅在尚未安装这些依赖项时进行安装:
pip install pillow imageio numpy