thedmd / imgui-node-editor

Node Editor built using Dear ImGui
MIT License
3.64k stars 537 forks source link

Attempting to add zoom around mouse cursor in canvas-example #270

Closed janicebeinrot closed 9 months ago

janicebeinrot commented 9 months ago

Hello,

I'm new to this stuff imgui and node-editor so please bear with me. I'm trying to add a simple zoom functionality to the canvas-example - As for now I would like to use the canvas itself but not the node functionality.

Specifically I've added some code here:

https://github.com/thedmd/imgui-node-editor/blob/master/examples/canvas-example/canvas-example.cpp#L176

if (canvas.Begin("##mycanvas", ImVec2(s_RightPaneSize, 0.0f)))
{
   const auto mouseWheel = context()->IO.MouseWheel;
   if (ImGui::IsItemHovered() && (mouseWheel != 0.0))
   {
       const auto mouseScreenCoords = canvas.ToLocal(context()->IO.MousePos);
       const auto viewCenter        = canvas.ViewRect().GetCenter();

       viewScale = std::clamp<float>(viewScale + (mouseWheel / 20.0), 0.1, 12.0);
       canvas.SetView(viewOrigin, viewScale);
       // canvas.CenterView(viewCenter);
   }

As it is now - it works. However the current solution doesn't translate the view so that the location the mouse cursor on the canvas prior to the zoom is still the location/point after the zoom.

The following is a video of what is happening now:

https://github.com/thedmd/imgui-node-editor/assets/153146019/e0027532-48f7-4b60-b173-825b68d0d438

I've tried to recreate the effect as best I can using Gimp:

https://github.com/thedmd/imgui-node-editor/assets/153146019/2c2709da-7514-4dad-b358-b8ce4014bc46

thedmd commented 9 months ago

Hello @janicebeinrot

Achieving zoom at fixed point is suprisingly tricky to do right, mainly because it is moving target. Changing zoom (scale) is easy enough. After doing that origin of the canvas need to be translated so local position under cursor does not change.

I did extract minimal example from NavigateAction and included it in the example on develop branch:

https://github.com/thedmd/imgui-node-editor/blob/97a5d9e03b73c3e7ff83a080bc255b9785e78264/examples/canvas-example/canvas-example.cpp#L194-L211

Code should work in on master too.

Note that value of io.MousePos is transformed to local position between Begin/End calls.

janicebeinrot commented 7 months ago

@thedmd thanks for make the change, I'll give it a go shortly 😺