3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SVGAdvent Calendar 2024

Day 6

SVGアニメーションで作る!かわいいもふもふキャラクターGIF

Posted at

はじめに

SVGアニメーションを使って、かわいいもふもふキャラクターのGIFアニメーションを作成する方法を紹介します。PythonとSVGを組み合わせることで、軽量で高品質なアニメーションを実現できます。

image.png

fluffy_blob.gif

必要なライブラリ

import os
from PIL import Image
import cairosvg
import math

実装コード

以下のコードで、ふわふわと浮遊するもふもふキャラクターのアニメーションが作成できます。

import os
from PIL import Image
import cairosvg
import math

def generate_svg_frame_fluffy_blob(frame_num):
    # 浮遊とスクイーズのアニメーション計算
    float_height = -15 * math.sin(frame_num * math.pi / 7)
    squeeze = 0.1 * math.sin(frame_num * math.pi / 4)
    eye_blink = 'scale(1, 1)' if frame_num % 15 != 0 else 'scale(1, 0.1)'
    fluff_wave = 3 * math.sin(frame_num * math.pi / 5)
    
    return f"""
    <svg xmlns="http://www.w3.org/2000/svg" width="300" height="300" viewBox="0 0 300 300">
        <!-- 背景 -->
        <rect width="300" height="300" fill="#E6F3FF"/>
        
        <!-- 影 -->
        <ellipse cx="150" cy="250" rx="40" ry="15" fill="#A8C6FA" opacity="0.3"/>
        
        <!-- キャラクター本体 -->
        <g transform="translate(150, {200 + float_height}) scale({1 + squeeze}, {1 - squeeze})">
            <!-- もふもふ層1 -->
            {' '.join([f'''
                <circle cx="{40 * math.cos(i * math.pi / 8)}"
                        cy="{40 * math.sin(i * math.pi / 8)}"
                        r="{15 + fluff_wave + 2 * math.sin(frame_num * 0.2 + i)}"
                        fill="#E6EEFF" stroke="#CFE3FF" stroke-width="2"/>
            ''' for i in range(16)])}
            
            <!-- メインボディ -->
            <circle cx="0" cy="0" r="35" 
                    fill="#CFE3FF" stroke="#A8C6FA" stroke-width="2"/>
            
            <!-- 目 -->
            <g transform="{eye_blink}">
                <circle cx="-12" cy="-10" r="4" fill="#6B8EAE"/>
                <circle cx="12" cy="-10" r="4" fill="#6B8EAE"/>
                <circle cx="-12" cy="-11" r="1.5" fill="#FFF"/>
                <circle cx="12" cy="-11" r="1.5" fill="#FFF"/>
            </g>
            
            <!-- ほっぺ -->
            <circle cx="-20" cy="5" r="6" fill="#A8C6FA" opacity="0.4"/>
            <circle cx="20" cy="5" r="6" fill="#A8C6FA" opacity="0.4"/>
        </g>
        
        <!-- 周りのキラキラ -->
        {' '.join([f'''
            <path d="M {150 + 60 * math.cos(frame_num * 0.1 + i)} {100 + 40 * math.sin(frame_num * 0.1 + i)} 
                     l 3,-3 3,3 -3,3 -3,-3"
                  fill="#A8C6FA" opacity="{0.3 + 0.2 * math.sin(frame_num * 0.2 + i)}">
            </path>
        ''' for i in range(5)])}
    </svg>
    """

def create_animation(output_folder, num_frames):
    os.makedirs(output_folder, exist_ok=True)
    frames = []
    
    for i in range(num_frames):
        svg_content = generate_svg_frame_fluffy_blob(i)
        png_file = f"{output_folder}/frame_{i}.png"
        cairosvg.svg2png(bytestring=svg_content.encode('utf-8'), write_to=png_file)
        frames.append(Image.open(png_file))
    
    output_gif = "fluffy_blob.gif"
    frames[0].save(
        output_gif,
        save_all=True,
        append_images=frames[1:],
        optimize=True,
        duration=50,
        loop=0
    )
    
    return output_gif

# アニメーション生成
output_folder = "blob_frames"
num_frames = 30
animation = create_animation(output_folder, num_frames)

実装のポイント

1. もふもふ表現

  • 複数の円を重ねてもふもふ感を表現
  • math.sinを使って毛並みの揺れを表現
  • 異なる周期で動かすことでより自然な動きを実現

2. アニメーションの工夫

  • 浮遊感: float_heightによる上下運動
  • スクイーズ: squeezeによる伸縮
  • まばたき: eye_blinkによる目の開閉
  • キラキラエフェクト: 周囲を浮遊する装飾要素

3. カラーリング

  • 青系の優しい色調で統一
  • 半透明を活用した柔らかい印象
  • グラデーション的な重なりで立体感を表現

カスタマイズのヒント

  1. 色の変更

    • fill属性の値を変更することで、好みの色に調整可能
    • カラーコードは#E6F3FFのような16進数形式で指定
  2. 動きの調整

    • durationの値を変更してアニメーション速度を調整
    • math.sinの係数を変更して動きの大きさを調整
    • num_framesを増やしてよりなめらかな動きに
  3. キャラクターのサイズ

    • viewBoxや各要素の半径を調整してサイズを変更可能
    • stroke-widthを調整して線の太さを変更

まとめ

image.png

SVGとPythonを組み合わせることで、かわいいアニメーションGIFを作成できました。数学的な関数を使って自然な動きを表現し、SVGの特性を活かした軽量な実装が可能です。このコードを基に、独自のキャラクターやアニメーションを作成してみてください!

参考リンク

クラス図

シーケンス図

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?