Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[examples] Use logarithmic scaling for 2d examples with zoom functionality #3977

Merged
merged 1 commit into from
May 15, 2024

Conversation

myQwil
Copy link
Contributor

@myQwil myQwil commented May 12, 2024

Makes zoom increments feel more natural. Otherwise, increments can feel too small when zoomed in, or too big when zoomed out.

@raysan5 raysan5 changed the title Use logarithmic scaling for 2d examples with zoom functionality [examples] Use logarithmic scaling for 2d examples with zoom functionality May 12, 2024
@rmn20
Copy link
Contributor

rmn20 commented May 12, 2024

You can also implement something similar with powf, like here:

float scaleFactor = 1.125f;
// *= scaleFactor, if you scroll up
// /= scaleFactor, if you scroll down
// if you scroll multiple times in one frame, the zoom will be faster
camera.zoom *= powf(scaleFactor, GetMouseWheelMove());
// add clamping probably?

This way you also get natural feeling increments. This solution seems more straightforward to me, but maybe the expf solution has some advantages that I fail to see.

@raysan5
Copy link
Owner

raysan5 commented May 12, 2024

@rmn20 Personally I prefer this solution, it seems more simple to me. Also, I prefer to apply it to only one of the examples (core_2d_camera_mouse_zoom), just as an example, while keeping the others simpler.

@myQwil
Copy link
Contributor Author

myQwil commented May 13, 2024

maybe the expf solution has some advantages that I fail to see.

Basically, the pow(x, y) function is often implemented as exp(log(x) * y). So to make the code more efficient, we can store the log(x) part of that calculation in a variable instead of having to calculate it every time.

EDIT: Actually, we can avoid pow and exp entirely. Something like this should also work:

float scaleFactor = 1.0f + (0.25f * fabsf(wheel));
if (wheel < 0) scaleFactor = 1.0f / scaleFactor;
camera.zoom = Clamp(camera.zoom * scaleFactor, 0.125, 64);

@myQwil myQwil force-pushed the exp_zoom branch 2 times, most recently from a52a181 to e272cc6 Compare May 13, 2024 04:43
@myQwil
Copy link
Contributor Author

myQwil commented May 13, 2024

If it's just the one example that this change is being applied to, I'd also like to propose using a click-and-drag motion instead of the mouse wheel:

@@ -48,9 +48,8 @@ int main ()
             camera.target = Vector2Add(camera.target, delta);
         }
 
-        // Zoom based on mouse wheel
-        float wheel = GetMouseWheelMove();
-        if (wheel != 0)
+        // Zoom based on mouse left click
+        if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
         {
             // Get the world point that is under the mouse
             Vector2 mouseWorldPos = GetScreenToWorld2D(GetMousePosition(), camera);
@@ -61,10 +60,13 @@ int main ()
             // Set the target to match, so that the camera maps the world space point 
             // under the cursor to the screen space point under the cursor at any zoom
             camera.target = mouseWorldPos;
-
+        }
+        if (IsMouseButtonDown(MOUSE_BUTTON_LEFT))
+        {
             // Zoom increment
-            float scaleFactor = 1.0f + (0.25f * fabsf(wheel));
-            if (wheel < 0) scaleFactor = 1.0f / scaleFactor;
+            float deltaX = GetMouseDelta().x;
+            float scaleFactor = 1.0f + (0.01f * fabsf(deltaX));
+            if (deltaX < 0) scaleFactor = 1.0f / scaleFactor;
             camera.zoom = Clamp(camera.zoom * scaleFactor, 0.125, 64);
         }

@raysan5 raysan5 merged commit 46f9806 into raysan5:master May 15, 2024
@raysan5
Copy link
Owner

raysan5 commented May 15, 2024

@myQwil Actually examples are intended for users to learn so we can add several approaches to show users the different possibilities. I'm merging this PR and adding the proposed alternative.

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.

None yet

3 participants