Skip to content

Instantly share code, notes, and snippets.

@dicenull
Last active February 12, 2021 11:52
Show Gist options
  • Save dicenull/e62b88935f58d4ace008e31c6c56551f to your computer and use it in GitHub Desktop.
Save dicenull/e62b88935f58d4ace008e31c6c56551f to your computer and use it in GitHub Desktop.
動く絵文字メーカー
# include <Siv3D.hpp> // OpenSiv3D v0.4.3
// https://siv3d.github.io/ja-jp/news/v043/#3-gif
struct AnimationTexture
{
Array<Texture> textures;
// フレームの時間
Array<int32> delays;
int32 duration = 0;
explicit operator bool() const noexcept
{
return !textures.isEmpty();
}
Size size() const noexcept
{
if (!textures)
{
return Size(0, 0);
}
return textures.front().size();
}
size_t frames() const noexcept
{
return textures.size();
}
size_t getFrameIndex(int32 timeMillisec) const noexcept
{
return AnimatedGIFReader::MillisecToIndex(timeMillisec, delays, duration);
}
const Texture& getTexture(int32 timeMillisec) const noexcept
{
return textures[getFrameIndex(timeMillisec)];
}
};
void saveGif(String path, String str, Color fgColor, Color bgColor) {
const int size = 128;
MSRenderTexture renderTexture(size, size);
const Font font(60, Typeface::Heavy);
// GIF アニメ出力クラス
AnimatedGIFWriter gif(path, size / 2, size / 2);
AnimationTexture animation;
auto length = 30;
const auto width = font(str).region().w;
for(auto i : step(length))
{
renderTexture.clear(fgColor);
{
ScopedRenderTarget2D renderTarget(renderTexture);
double dx = (double)str.size() * 3 * i;
Transformer2D transform(Mat3x2::Translate(Vec2::Left() * dx + Vec2::Right() * width));
font(str).drawAt(64, 64, bgColor);
}
{
Graphics2D::Flush();
renderTexture.resolve();
}
Image image;
renderTexture.readAsImage(image);
// GIF アニメのフレームとして書き出し
gif.writeFrame(image.scaled(size / 2, size / 2), 0.1s);
}
gif.close();
}
void Main()
{
HSV fontColor = Palette::Orange, bgColor = Palette::White;
TextEditState text(U"emoji");
AnimatedGIFReader reader;
AnimationTexture animation;
Window::SetTitle(U"動く絵文字メーカー");
while (System::Update())
{
SimpleGUI::Headline(U"文字色", Vec2(240, 20));
{
// カラーピッカー
SimpleGUI::ColorPicker(fontColor, Vec2(240, 60));
}
SimpleGUI::Headline(U"背景色", Vec2(20, 20));
{
// カラーピッカー
SimpleGUI::ColorPicker(bgColor, Vec2(20, 60));
}
SimpleGUI::TextBox(text, Vec2(20, 200));
if (SimpleGUI::Button(U"Save", Vec2(320, 200))) {
auto path = text.text + U".gif";
saveGif(path, text.text, fontColor, bgColor);
const AnimatedGIFReader gif(path);
Array<Image> images;
if (gif.read(images, animation.delays, animation.duration))
{
animation.textures = images.map([](const Image& i) { return Texture(i); });
}
}
const int32 timeMillisec = static_cast<int32>(Scene::Time() * 1000);
if (animation.frames() > 0) {
animation.getTexture(timeMillisec).draw(Vec2(20, 400));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment