Skip to content

Instantly share code, notes, and snippets.

@voidproc
Created August 13, 2023 15:06
Show Gist options
  • Save voidproc/211db9df9d46c8c37a9123f30eb2a6a4 to your computer and use it in GitHub Desktop.
Save voidproc/211db9df9d46c8c37a9123f30eb2a6a4 to your computer and use it in GitHub Desktop.
# include <Siv3D.hpp> // OpenSiv3D v0.6.11
struct PolygonHighlightEffect : IEffect
{
Array<TrailMotion> trails;
Polygon polygon;
PolygonHighlightEffect(const Polygon& targetPolygon)
: polygon{ targetPolygon }
{
constexpr std::array<ColorF, 3> colors = { Palette::White, Palette::Magenta, Palette::Cyan };
for (int iTrail : step(3))
{
trails << TrailMotion{}
.setLifeTime(DisplayTime + 0.5 * iTrail)
.setColor(ColorF{ colors[iTrail], 1 - 0.2 * iTrail })
.setSizeFunction([=](double timeSec) {
const double size = 2 + 3 * iTrail;
const double sizeScale1 = timeSec < LifeTime ? 1 : 0;
const double sizeScale2 = timeSec < 0.1 ? timeSec / 0.1 : 1;
const double displayTimeScaled = DisplayTime * 0.7;
const double sizeScale3 = timeSec < displayTimeScaled ? 1 : EaseInExpo(1 - ((timeSec - displayTimeScaled) / (LifeTime - displayTimeScaled)));
return size * sizeScale1 * sizeScale2 * sizeScale3;
})
.setPositionFunction([&](double timeSec) {
const double t = Min(timeSec, DisplayTime);
const double t0_1 = t / (DisplayTime * 0.8);
const auto& vertices = polygon.outer();
const int index1 = ((int)(t0_1 * vertices.size())) % vertices.size();
const int index2 = (index1 + 1) % vertices.size();
double tmp;
const double lerpFactor = modf(t0_1 * vertices.size(), &tmp);
const auto v = vertices[index1].lerp(vertices[index2], EaseInExpo(lerpFactor));
return v;
});
}
}
bool update(double timeSec) override
{
for (auto& trail : trails)
{
trail.update();
}
{
const ScopedRenderStates2D blend{ BlendState::Additive };
for (const auto& trail : trails)
{
trail.draw();
}
}
return timeSec < 3.0;
}
private:
inline static constexpr double DisplayTime = 0.3;
inline static constexpr double LifeTime = 1.0;
};
void Main()
{
Scene::SetBackground(ColorF{ 0 });
const RectF rect{ Arg::center = Scene::CenterF().movedBy(-160, -140), SizeF{ 200, 180 }};
const Circle circle{ Scene::CenterF().movedBy(160, 140), 100 };
const Polygon star = Shape2D::Star(128, Scene::CenterF().movedBy(-160, 140));
const Polygon nstar = Shape2D::NStar(12, 128, 96, Scene::CenterF().movedBy(160, -140));
Effect effect;
while (System::Update())
{
rect.drawFrame(1, 0, Palette::Silver);
circle.drawFrame(1, 0, Palette::Silver);
star.drawFrame(1, Palette::Silver);
nstar.drawFrame(1, Palette::Silver);
if (rect.leftClicked())
{
effect.add<PolygonHighlightEffect>(rect.asPolygon());
}
else if (circle.leftClicked())
{
effect.add<PolygonHighlightEffect>(circle.asPolygon());
}
else if (star.leftClicked())
{
effect.add<PolygonHighlightEffect>(star);
}
else if (nstar.leftClicked())
{
effect.add<PolygonHighlightEffect>(nstar);
}
else if (Scene::Rect().leftClicked())
{
effect.add<PolygonHighlightEffect>(Scene::Rect().stretched(-1).asPolygon());
}
effect.update();
}
}
@voidproc
Copy link
Author

result_polygon_highlight.mp4

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