2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GitHubのREADMEに綺麗なものを飾りたい!C 言語で作るアニメーション SVG バナー

2
Last updated at Posted at 2025-12-02

はじめに

みなさんはGitHubプロフィールのREADMEを、どれくらい装飾していますか?
バッジを貼ったり、スクショを並べたり、いろいろ工夫はできるのですが、「ちょっとだけ凝ったヘッダー画像を置きたい」と思う瞬間がありませんか?

もちろん、READMEは本来“自分の技術を紹介する場所”なので必ずしも飾る必要はありません。
が、綺麗なREADMEって見ているだけでテンション上がりますよね。

そこで、C言語でSVGを直接生成して、README用のバナーを自動で作るツールを作りました。
それが今回紹介するsvg4readmeです。
svgでREADMEをちょっと豪華に装飾する方法を広めるという名目で紹介します。

リポジトリはこちらです。
GitHub: https://github.com/Aotumuri/svg4readme

簡単な紹介

コードはCodex CLIに書かせました。
一部自分で付け足している部分があります。

GitHubのREADMEでは、基本的に凝ったUIを直接書くことができないので、画像に頼らざるおえません。
そこで今回は『アニメーションさせたい』という思いも含めて、svgを使ったバナーを作りました。
Cでsvgを組み立てて流すという形にしています。

実際のバナー

時折流れ星が降るようになっています。
Qiitaではsvgが添付できなかったので上記したリポジトリからぜひ見てください。
スクリーンショット 2025-12-02 19.27.10.png

無駄に色違いもあったりします。
スクリーンショット 2025-12-02 19.31.24.png

仕組み

このツールの構成はざっくり書くと以下のようになります。
複雑な処理はさせていないつもりです。

  1. config.h / config.c に、ユーザー名や説明文などのプロフィール情報を定義する
  2. waves_svg.c / fire_svg.c が、Cでsvgの <path><text> を組み立てる
  3. printf でsvgを標準出力に吐き出す
  4. シェルでリダイレクトして *.svg ファイルとして保存する

問題点

このリポジトリは多数の問題を抱えていると思います。

  • アニメーションがすべてハードコーディングされている点
  • Qiitaのようなsvgが使えないサイトでは意味をなさない点

前者については、数値パラメータをyamlなどで外部化しようかな、とは一瞬考えました。
しかし、そもそもこれをforkして使うような酔狂な方が現れるとは思えませんし、もし現れたとしても、そういう人は多分いちから自分で作り直すだろうな…という結論に至り、やめました。

後者については、もう仕方のない話です。
Qiitaに貼れないならpngかgifにすればいいのですが、そのための生成ツールは別途(mp4->gifコンバーターなど)存在しているため、このプロジェクト内で対応する意味は薄いかなと思っています。

おまけ

以下のコードを見るとわかるのですが、真ん中にあるバーは座標が固定です。
config.c の中身を長くするとバーを貫通します。
ここら辺は関数で切り出したり、柔軟に二段組に自動で変わったりなどを作ればよかったですね。

問題のコード部分
    // 情報パネル:使用言語
    printf("<g id='info' transform='translate(%.1f, %.1f)' opacity='0.85'>\n", brandX + 15.0 , boxY + 40.0);
    printf("  <text font-size='36' font-family='Inter, sans-serif' fill='url(#textGrad)'>%s</text>\n", get_first_title());
    printf("  <text y='42' x='15' font-size='30' fill='rgba(255,255,255,0.85)'>%s</text>\n", get_first_desc1());
    printf("  <text y='82' x='15' font-size='30' fill='rgba(255,255,255,0.85)'>%s</text>\n", get_first_desc2());
    printf("</g>\n");

    /*
    以下のbarX、barYを見る通りbrandX/brandY依存の固定(そして元の変数も固定)なので
    文章がどれだけ長くなろうがそこにい続けます。
    文字数をカウントして閾値以上になったら二段構えにするような仕組みを作った方がよかったですかね...
    */
    double barX = brandX + 500.0;   // 横位置(名前の少し右)
    double barY = brandY + 40.0;   // 開始位置(矩形の上端)
    double barHeight = 100.0;      // 棒の高さ
    printf("<rect x='%.1f' y='%.1f' width='4' height='%.1f' "
        "fill='rgba(120,180,255,0.35)' stroke='rgba(180,220,255,0.45)' "
        "rx='2' ry='2'/>\n",
        barX, barY, barHeight);

    // 情報パネル:使用言語
    printf("<g id='info' transform='translate(%.1f, %.1f)' opacity='0.85'>\n", barX + 25.0 , boxY + 40.0);
    printf("  <text font-size='36' font-family='Inter, sans-serif' fill='url(#textGrad)'>%s</text>\n", get_second_title());
    printf("  <text y='42' x='15' font-size='30' fill='rgba(255,255,255,0.85)'>%s</text>\n", get_second_desc1());
    printf("  <text y='82' x='15' font-size='30' fill='rgba(255,255,255,0.85)'>%s</text>\n", get_second_desc2());
    printf("</g>\n");

おわりに

「READMEをちょっとだけ豪華にしたい」という人には、興味深いものなのではないでしょうか?
おそらくですが、これと同じようなリポジトリも多いと思いますので、おすすめがあったら教えて欲しいです。
時間があったら夜景などの他の種類を増やそうかなと思っています。

ここまで読んでいただき、ありがとうございました。

2
0
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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?