I basically want to scale a widget that’s inside of another widget. I have many many buttons on a complex layout and I want users to be able to zoom in to select the specific button as well as zoom out to see the big picture. Basically, think of UE4’s blueprint window. I want it exactly like that. Mouse wheel zooms in until a specific zoom zooms out with a specific zoom. But it only affects that window. I always want to be able to pan like the blueprint window as well.
I tried render scale of the widget but that causes a lot of problems. I’m guessing the panner would be done with a drag and drop function? I’ve googled this quite a bit and can’t seem to find a good way to do this. Thanks.
Update: So I figured out how to constrain the image when zoomed. I had to put it within a canvas and learned the word “clipping.” So I used clipping via the documentation to keep it within that box when zooming in.
I still don’t know how to “move” the widget. The obvious choice would be draganddrop operation, but I don’t want to destroy/create a new copy of the widget if that makes sense. If it doesn’t make sense, maybe I don’t quite understand how drag and drop works. I just want to “pan” like in the blueprint editor.
Have a widget with Parent Canvas and a Panning Canvas nested inside:
- set Parent Canvas to Visible
- set Panning Canvas to Self Hit Test Invisible
- make the Panning Canvas significantly larger than the Parent Canvas
- place widgets in the Panning Canvas
We’ll be shifting the Panning Canvas inside the Parent Canvas.
- have a bool canPan controlled by the overridden onMouseDown/Up
- override onMouseMove branched by the above bool and do the following while True:
- Panning Canvas as Canvas Slot.Get Position + Get Cursor Delta → Set Panning Canvas Position
For Mouse Zoom:
- override onMouseWheel
- add Wheel Delta to Panning Canvas’ Render Transform Scale
- clamp min result to something above 0 (widgets flip if scaled below 0) and max to your desired max zoom
Set Render Scale of the Panning Canvas with the result of the above
That should be it. You will need to work in handled / unhandled returns into the overridden functions if you want to be able to tunnel through correctly to other widgets - may not be necessary, depending on how complex this is going to be.
edit: forgot to add one thing about zooming, you will need to shift the canvas while zooming to emulate zooming into the cursor position - the above setup would only zoom in to the screen centre.
I wasn’t expecting such a detailed reply. This worked perfectly! I haven’t gotten to the zoom part because I have a semi functioning one that I will replace shortly. The Panning was excellent. I can’t believe I had such difficultly with this.
Again, thank you. I saw some posts asking a similar question so I hope your answer can help them too.
Hi, this setup worked perfectly for me as well, however, is there any chance you could expand on how to shift the canvas position while zooming in/out in the position of the cursor. I can’t seem to figure that part out.
So what’s the end goal here? You want to zoom in on the cursor position? Or how is this supposed to work?
I know this was like 2 years ago, but was anyone able to figure out what he means by “shift the canvas while zooming”? I’ve been going at it for a day now and I can’t figure it out. And there are no tutorials about it I can find. I’m hoping to not have to spend $30 on the marketplace for a world map asset just to figure this out.
Well it’s like you mentioned, “emulate zooming into the cursor position.” It’s basically like the graph editor in blueprints. Wherever your mouse cursor is, that’s where it zooms into. The idea is, if you have a map onscreen, and someone wants to zoom into something like down at the bottom right of the map, they move their cursor there and start scrolling in so they can see that one part better/larger, without having to zoom in and then panning over to that part of the map to see it.
BTW thanks for the detailed info you provided above, I learned a lot following your instructions and got the panning and basic zoom to work.
And a project link because who wants to punch in all of this manually…
It’s somewhat similar to google maps, the mouse up / down are pretty standard:
Dragging the image in the canvas:
Clamping the edges:
And we can’t drag the map when the cursor goes beyond the widget:
The widget itself:
And the zooming onto the cursor:
Seems to work OK for what it is, but there might be some kinks.
Holy Wow! This is amazing! And thank you for the project too. I put it on one monitor and went through every part of it, building it in my project on my other monitor, and it works! I’ll be studying it for a while to learn. It looks like a number of people on various sites have asked about this kind of thing over the years. You could polish it up and probably sell it on the marketplace for $5 or $10.
Perhaps I should’ve included a general overview of how it’s supposed to work so it’s easier to iron out / refactor the bits that are far from perfect.
- the zooming is based on the number of steps controlled by the mouse wheel
Current Zoom Step /
Min Zoom /
Max Zoom control the zooming process
- Min of -3 and Max of +3 would produce 5 steps: [-2,-1,0,1,2]
- Min of -2 and Max of +8 would allow you to zoom out once but zoom in a lot!
Zoom Factor is the magnitude of a step where 0.4 = 60% or 0.9 =10% of the current widget scale (kind of)
- it’s ‘kind of’ because of how scaling works, in order to be consistent both ways and account for the current scale, we need to use the inverse of 1 here; otherwise we will not return to where we started
- if you zoom in by 20%, you’re at 1.20 scale but if you zoom out of that 1.20 by 20%… that’s actually 24% of the scale instead since we’re using a greater base
- also, the
Zoom Factorshould not exceed 1 or it would reverse the process. Low values, below 0.5% should be, ideally, avoided as it might look too jarring (unless we work in interpolation). But should still work OK and might be even necessary for huge maps - like a star map!
As for the whole process: we scale the image up and down and shift it in such a way, that the pixel under the cursor remains in the same position after the Scale & Translate have taken place. As demonstrated by the navy-blue spaghetti.
There are areas for improvement here, that’s for sure - the way zooming out combines with clamping would benefit from a minor overhaul.
When working with the above setup one should aim to produce a zoomed out effect where the image remains equal to or larger than the canvas. This is not a scenario you want to end up with, for example:
This can be fixed in an elegant way, I’m almost sure. Adding interpolation would definitely help here, too, especially for larger steps.
That was a pretty cool exercise that somehow took longer than the intended coffee break!
Once again, Amazing! A true pro. If you make a marketplace asset from this I’d buy it. It could be useful in a few different areas, including at least world maps and skill/tech trees.
I’m new to UE4 and i’m trying to do this exercise to learn some more abou it, but i’m having trouble to locate the CLAMPS that connects My Geometry with the Set Render Location nodes on the On Mouse Move and Mouse Wheel overrides, tried to download the project to investigate on my own but i’m getting an error when i try to open it, i’m using UE4 4.23.1.
Can you guide me how to get that CLAMPS node?
It’s custom function, you can see it above. It’s called Clamp Sides. It’s a compacted node:
That’s why it looks funky.
i’m getting an error when i try to
open it, i’m using UE4 4.23.1.
@Meeeehh It’s compiled for 4.25 so you’ll need minimum that version.
I was able to get it working, thank you so much for the help!!