Do you want to improve the style of your application? Here's a glimpse into crafting a dynamic particle background using ImGui. This implementation introduces a mesmerizing interplay of lines and particles that react to cursor movements within an ImGui window.
The magic begins by initializing particles with random positions and velocities. Each particle finds its home within the ImGui window, equipped with a unique trajectory for future animation.
static bool initialized = false;
if (!initialized)
{
for (int i = 0; i < numParticles; ++i)
{
particlePositions[i] = ImVec2(
ImGui::GetWindowPos().x + ImGui::GetWindowSize().x * static_cast<float>(rand()) / RAND_MAX,
ImGui::GetWindowPos().y + ImGui::GetWindowSize().y * static_cast<float>(rand()) / RAND_MAX
);
particleVelocities[i] = ImVec2(
static_cast<float>((rand() % 11) - 5),
static_cast<float>((rand() % 11) - 5)
);
}
initialized = true;
}
The visual spectacle unfolds as lines are drawn between particles and the cursor, creating an intricate dance of connections. Opacity gracefully changes with distance, contributing to the ethereal ambiance.
ImVec2 cursorPos = ImGui::GetIO().MousePos;
for (int i = 0; i < numParticles; ++i)
{
// draw lines to particles
for (int j = i + 1; j < numParticles; ++j)
{
float distance = std::hypotf(particlePositions[j].x - particlePositions[i].x, particlePositions[j].y - particlePositions[i].y);
float opacity = 1.0f - (distance / 55.0f); // opacity change
if (opacity > 0.0f)
{
ImU32 lineColor = ImGui::GetColorU32(ImVec4(1.0f, 1.0f, 1.0f, opacity));
drawList->AddLine(particlePositions[i], particlePositions[j], lineColor);
}
}
// draw lines to cursor
float distanceToCursor = std::hypotf(cursorPos.x - particlePositions[i].x, cursorPos.y - particlePositions[i].y);
float opacityToCursor = 1.0f - (distanceToCursor / 52.0f); // Adjust the divisor to control the opacity change
if (opacityToCursor > 0.0f)
{
ImU32 lineColorToCursor = ImGui::GetColorU32(ImVec4(1.0f, 1.0f, 1.0f, opacityToCursor));
drawList->AddLine(cursorPos, particlePositions[i], lineColorToCursor);
}
}
Particles undergo a continuous update, adjusting positions while staying within the bounds of the ImGui window. Each particle leaves a luminous trail behind, rendering a stunning visual symphony.
float deltaTime = ImGui::GetIO().DeltaTime;
for (int i = 0; i < numParticles; ++i)
{
particlePositions[i].x += particleVelocities[i].x * deltaTime;
particlePositions[i].y += particleVelocities[i].y * deltaTime;
// Stay in window
if (particlePositions[i].x < ImGui::GetWindowPos().x)
particlePositions[i].x = ImGui::GetWindowPos().x + ImGui::GetWindowSize().x;
else if (particlePositions[i].x > ImGui::GetWindowPos().x + ImGui::GetWindowSize().x)
particlePositions[i].x = ImGui::GetWindowPos().x;
if (particlePositions[i].y < ImGui::GetWindowPos().y)
particlePositions[i].y = ImGui::GetWindowPos().y + ImGui::GetWindowSize().y;
else if (particlePositions[i].y > ImGui::GetWindowPos().y + ImGui::GetWindowSize().y)
particlePositions[i].y = ImGui::GetWindowPos().y;
ImU32 particleColour = ImGui::ColorConvertFloat4ToU32(settings::particleColour);
// render particles behind components
drawList->AddCircleFilled(particlePositions[i], 1.5f, particleColour);
}
Unlock the world of ImGui creativity by implementing this dynamic particle background. Tweak the parameters, explore color variations, and let your imagination run wild. The result is a captivating visual experience that adds a touch of enchantment to your ImGui applications.
Check out the full code and experiment with your own particle playground here.
Happy coding! 👋