SFML community forums

General => SFML wiki => Topic started by: Hapax on January 27, 2015, 11:13:02 pm

Title: Zooming a view at a specified pixel
Post by: Hapax on January 27, 2015, 11:13:02 pm

A thread appeared on the forum that asked about zooming a view at the mouse's position when the mouse wheel was scrolled so I created a simple free function that zooms a view at any specified pixel (in relation to the window).

Here's the wiki page:

It includes an example that scrolls on mouse wheel usage as stated above.

I hope you find some use of it.


p.s. It's also my first SFML wiki page so I hope it follows all of the rules.
Title: Re: Zooming a view at a specified pixel
Post by: Paul on May 31, 2017, 12:21:42 pm
Nice code, but if I have next view for GUI and call window.setView(ViewGUI) it reset zoom. Is it possible to combine it?

Title: Re: Zooming a view at a specified pixel
Post by: Hapax on June 01, 2017, 05:21:14 pm
Unless I misunderstand what you are trying to achieve, you can, after running this function, store the current view over the previously stored view:
sf::View view;
zoomViewAt(pixelLocation, window, 1.1f);
view = window.getView();
Title: Re: Zooming a view at a specified pixel
Post by: Paul on June 02, 2017, 06:24:18 pm
I'm sorry, better description:

I'm using your code from wiki and what I want to achieve:
- draw scene with sprites (sun) etc. + move view + zoom view to pixel
- draw GUI over this scene (this black box with text), 1:1, without any transformations

Scene: https://imgur.com/a/IIdk3

1) Your code without changes, working - https://youtu.be/olxO6OAgbQU

2) When I call window.setView(ViewGUI) - https://youtu.be/i6VovaULCxM

In first seconds is your function, it doesn't work anymore, it reset View.
From cca 5 sec. there is my code based on your, it works +- but view follows mouse cursor

I made global variable Zoom (zoom = zoom + 0.01) and put zoomViewAt() into drawing function.
Probably I can fix this mouse following but I'm not sure if it's right way or not, these view seems little bit tricky. The solution could be simpler as your suggestion. But I do not know exactly where to use it.

My code (it's not C but commands have similar syntax):
Procedure SFML_DRAW;
  if ViewResized then begin // when is window resized
    sfRenderWindow_setSize(renderWindow, PanelSize_u );
    sfView_reset( View, ViewRect );
    sfView_reset( View_GUI, ViewRect_GUI );
    ViewResized := false;

  sfview_move( view, ViewPos );   // arrow keys = move view to sides

 // sfRenderWindow_setView( RenderWindow, View );
  zoomViewAt( mouse, RenderWindow, Zoom );   // Zoom
 // View := sfRenderWindow_getView( RenderWindow );

  // Draw sprites
  spr_Draw_I( renderWindow, tex_sun, sun_pos.x, sun_pos.y, 0, 0, 0 );
  spr_Draw_I( renderWindow, tex_sun, 200, 100, 0, 0, 0 );
  // Screen boundary
  Draw_Rect_Line( -1, -1, Form1.Panel1.width + 1, Form1.Panel1.height + 1, 180, sfGreen );

// GUI
  //sfView_reset( View, ViewRect );
  sfRenderWindow_setView( RenderWindow, View_GUI );

  Game.DrawInfo( Form1.Panel1.Width - 210, 0, 12 ); // Black box with text

    WM_MOUSEWHEEL : if Smallint(HiWord(wParam)) < 0 then begin
       //sfRenderWindow_setView( RenderWindow, View );
       zoomViewAt( Mouse, RenderWindow, 1.1 );
       //View := sfRenderWindow_getView( RenderWindow );
    end else begin
       // sfRenderWindow_setView( RenderWindow, View );
       zoomViewAt( Mouse, RenderWindow, (1 / 1.1) );
       //View := sfRenderWindow_getView( RenderWindow );

  if sfKeyboard_isKeyPressed(sfKeyU)  = 1 then
      Zoom := Zoom + 0.01;

    if sfKeyboard_isKeyPressed(sfKeyI)  = 1 then
      if zoom > 0.01 then Zoom := Zoom - 0.01;
Title: Re: Zooming a view at a specified pixel
Post by: Hapax on June 05, 2017, 04:53:46 pm
Did you try code that I posted above? If so, what was wrong with it?

Did you understand what it does or do I still misunderstand what exactly is going wrong.

It seems that you want the view to be persistent; that is, you store the view and the modified (zoomed) view should be the one that is stored as you recall that view each frame instead of just using one view. Is that right?