Skip to content

Instantly share code, notes, and snippets.

@voidproc
Last active August 27, 2023 09:52
Show Gist options
  • Save voidproc/03e52beb8b9dba12871754f43c385b1a to your computer and use it in GitHub Desktop.
Save voidproc/03e52beb8b9dba12871754f43c385b1a to your computer and use it in GitHub Desktop.
# include <Siv3D.hpp> // OpenSiv3D v0.6.11
void DrawText(StringView text, const Vec2& pos, const Vec2& scale, const Color& color, const Color& outlineColor, double outlineWidth, double letterSpacingScale)
{
Vec2 penPos{ pos };
{
const auto& font = FontAsset(U"LI");
const ScopedCustomShader2D shader{ Font::GetPixelShader(font.method(), TextStyle::Type::Outline) };
Graphics2D::SetSDFParameters(TextStyle::Outline(outlineWidth, 0.0, outlineColor));
for (auto [index, glyph] : Indexed(font.getGlyphs(text)))
{
glyph.texture.scaled(scale).draw(penPos + glyph.getOffset(), color);
penPos.x += glyph.xAdvance * scale.x * letterSpacingScale;
}
}
}
void DrawTextAt(StringView text, const Vec2& pos, const Vec2& scale, const Color& color, const Color& outlineColor, double outlineWidth, double letterSpacingScale)
{
const auto region = FontAsset(U"LI")(text).region();
DrawText(text, pos.movedBy(-region.w * scale.x * 0.9 / 2, -region.h * scale.y / 2), scale, color, outlineColor, outlineWidth, letterSpacingScale);
}
double Time0_1(double beginSec, double durationSec, double easing(double) = EaseInLinear, double timeSec = Scene::Time())
{
return easing(Clamp((timeSec - beginSec) / durationSec, 0.0, 1.0));
}
void Main()
{
Scene::SetBackground(ColorF{ U"#fcd22e" });
const Texture bee{ U"🐝"_emoji };
FontAsset::Register(U"LI", FontMethod::MSDF, 48, Typeface::Black, FontStyle::BoldItalic);
while (System::Update())
{
const double moveCamXY = 800.0 - 800.0 * Time0_1(1.3, 0.5, EaseOutSine);
const Transformer2D transformer1{ Mat3x2::Scale(1.3, Scene::CenterF()).translated(Vec2{ 0 - moveCamXY / 2, -40 - moveCamXY }) };
// Layout
const Vec2 beePosBase = Scene::CenterF().movedBy(0, -100);
const Vec2 beePos = beePosBase + Vec2{ 800 - 800 * Time0_1(1.3, 2.5, EaseOutQuad), 0 };
const Vec2 label1Pos = beePosBase.movedBy(0, 100);
const Vec2 label2Pos = label1Pos.movedBy(0, 70);
const Vec2 framePos = (label1Pos + label2Pos) / 2;
{
const double color = Time0_1(1.5, 3.2, EaseOutSine);
const double alpha = Time0_1(1.5, 0.4);
const ScopedColorMul2D colorMul{ ColorF(0.6 + 0.4 * color, alpha) };
const double frameScale = Time0_1(1.5, 0.7, EaseOutBounce);
const Transformer2D transformer2{ Mat3x2::Scale(frameScale, Scene::Center()) };
// Frame
const auto frame = Shape2D::Ngon(6, 180, framePos, 0).asPolygon();
// shadow
const double shadowMoveXY = 10.0 * Time0_1(3.5, 0.7);
frame.scaledAt(framePos, 1.05).movedBy(shadowMoveXY * 0.8, shadowMoveXY * 1.1).draw(ColorF{0, 0.15});
// white outline
frame.drawFrame(14.0, ColorF{ 1 });
// blue
frame.draw(ColorF{ U"#434299" });
// red
const auto vertices = frame.vertices()
.map([&](const auto& v) { return v.y < framePos.y ? Vec2{ v.x, framePos.y + 7 } : Vec2{ v }; });
Polygon{ vertices }.draw(ColorF{ U"#e23118" });
// shadow (inner)
frame.scaledAt(framePos, 0.97).drawFrame(12.0, ColorF{ 0, 0.2 });
// gold outline
frame.drawFrame(9.0, ColorF{ U"#d08e44" });
// outline gleam
{
const ScopedRenderStates2D blend{ BlendState::Additive };
const double alpha = (1.0 - Time0_1(4.2, 1.2)) * Time0_1(4.2, 1.2);
frame.outline(Scene::Time() * 1500, 700).draw(9.0, ColorF{ 0.50 * alpha });
frame.outline(Scene::Time() * 1450, 700).draw(9.0, ColorF{ 0.30 * alpha });
frame.outline(Scene::Time() * 1400, 700).draw(9.0, ColorF{ 0.10 * alpha });
}
// Label1
DrawTextAt(U"ハチアブ", label1Pos.movedBy(-6, 0), Vec2{ 1.45, 1.95 }, ColorF{ U"#fff02e" }.withAlpha(alpha), ColorF{0}.withAlpha(alpha), 0.75, 0.9);
// Label2
const Vec2 label2APos = label2Pos.movedBy(-10, 4);
const Vec2 label2BPos = label2Pos.movedBy(10, 48);
const Vec2 shadowOffset{ 6, 2 };
const Vec2 label2Scale{ 1.3, 1.2 };
const ColorF label2ShadowColor = ColorF{ 1, alpha };
const ColorF label2ShadowOutlineColor = AlphaF(0);
const ColorF label2Color = ColorF{ U"#33336f" }.withAlpha(alpha);
const ColorF label2OutlineColor = ColorF{ 1 }.withAlpha(alpha);
DrawTextAt(U"ハイパー", label2APos + shadowOffset, label2Scale, label2ShadowColor, label2ShadowOutlineColor, 0, 0.85);
DrawTextAt(U"ジェット", label2BPos + shadowOffset, label2Scale, label2ShadowColor, label2ShadowOutlineColor, 0, 0.85);
DrawTextAt(U"ハイパー", label2APos, label2Scale, label2Color, label2OutlineColor, 0.6, 0.85);
DrawTextAt(U"ジェット", label2BPos, label2Scale, label2Color, label2OutlineColor, 0.6, 0.85);
}
// Bee
{
const ScopedRenderStates2D blend{ BlendState::Additive };
// flash
const double alpha = 0.9 * Time0_1(3.5, 1.0);
Shape2D::NStar(16, 72, 32, beePosBase, Periodic::Sawtooth0_1(30s) * Math::TwoPi).draw(ColorF(0.4, alpha));
Shape2D::NStar(24, 80, 48, beePosBase, -Periodic::Sawtooth0_1(40s) * Math::TwoPi).draw(ColorF(0.2, alpha));
// light
Circle{ beePosBase, 200 }.drawShadow(Vec2{}, 300.0, 150.0, ColorF{ 1.0, 0.10 * alpha });
}
bee.scaled(0.75).drawAt(beePos);
}
}
@voidproc
Copy link
Author

b.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment