Last active
February 12, 2021 11:52
-
-
Save dicenull/e62b88935f58d4ace008e31c6c56551f to your computer and use it in GitHub Desktop.
動く絵文字メーカー
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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