Skip to content

Conversation

mathsvisualization
Copy link

@mathsvisualization mathsvisualization commented Jul 18, 2025

🎮 ImGui Integration in ManimGL

This repo adds ImGui (Immediate Mode GUI) support to ManimGL, enabling real-time control over scene objects like color, opacity, and selection. Built on top of InteractiveScene, this integration gives full GUI control during animation playback inside the Manim window.


✨ Features

  • Live ImGui control panel embedded inside Manim window
  • Control any Mobject’s:
    • ✅ Fill color
    • ✅ Opacity
    • ✅ Selection from scene
  • Slider, Color Picker, Dropdown Combo via ImGui
  • Works using InteractiveScene class
  • Mouse scroll fix for ImGui usability

🔧 Requirements

Component Version / Info
Python 3.12.7 ✅ Required
🚫 Not compatible with Python 3.13
Windows 10 SDK ✅ Required for ImGui C++ build (imgui.core)
ManimGL Latest from 3Blue1Brown fork
PyImGui Use imgui or latest pip version

Fix moderngl_window mouse scroll event


Before

def mouse_scroll_event(self, x_offset, y_offset):
    self.io.mouse_wheel_h = x_offset # remove _h
    self.io.mouse_wheel = y_offset

After

def mouse_scroll_event(self, x_offset, y_offset):
    self.io.mouse_wheel = x_offset
    self.io.mouse_wheel = y_offset

⚙️ Setup Instructions

🐍 Python Environment

Make sure you're using Python 3.12.7.

python --version
# Should output: Python 3.12.7

Example

from manimlib import *

class TestMG(InteractiveScene):
    imgui = True
    def setup(self):
        super().setup()
        # initial state
        self.text_color = [1.0, 1.0, 1.0]
        self.opacity = 0.0
        self.selected_index = 0

    def construct(self):
        # Cube
        sq = Square()
        self.play(
            ShowCreation(sq),
            run_time=1,
        )
        self.play(
            sq.animate.to_edge(RIGHT)
        )

    def construct_imgui_window(self):
        imgui.new_frame()
        imgui.begin("Control Panel")
        imgui.text("Adjust the opacity")
        ochanged, self.opacity = imgui.slider_float("Opacity", self.opacity, 0.0, 1.0)
        wchanged, self.text_color = imgui.color_edit3("Text Color", *self.text_color)
        names = [str(mob) for mob in self.mobjects]
        changed, self.selected_index = imgui.combo(
            "Select Mobject",
            self.selected_index,
            names
        )
        selected_mob = self.mobjects[self.selected_index]
        if wchanged:
            selected_mob.set_fill(rgb_to_color(self.text_color[:3]))
        if ochanged:
            selected_mob.set_opacity(self.opacity)
        imgui.end()

📽️ Demo

TestMG_8.mp4
2025-07-18.23-31-16.mp4

A screen recording is included, showing how ImGui can interact with the square's color and opacity during rendering.


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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant