fix: Crystal ball example dragging no longer causes camera to jump#3925
Merged
Conversation
The center-tap handler was converting canvas coordinates with CameraComponent.globalToLocal and using the resulting viewport Y (0-1600 range) directly as a world Y. Since the ball can be at world Y far from zero after bouncing, this caused a large camera jump on every click. Removed the broken center-tap camera movement and added DragCallbacks so clicking and dragging now smoothly pans the camera target via localDelta.
Directly modifying cameraTarget.position during drag was being overwritten each frame by the running MoveCameraTarget effect (e.g. the bounce animation), causing jank. Add CameraTarget.nudge() which shifts both _from and _to of the animation path alongside the position, so any active animation is preserved but offset by the drag delta instead of fighting it.
…ra move Only the left/right tap areas control the ball. The center-tap camera movement used viewport coordinates as world coordinates, causing large jumps, so it has been removed.
event.localPosition is in the InputHandler's local space (0 to size.x = 900), but the thresholds were comparing against game.size.x (the actual canvas width). On desktop this could exceed 900, making the right tap region unreachable and all taps fall in the dead center zone.
…ad zone The original third-based split left a center region that did nothing useful for ball control. Split at the midpoint so every tap moves the ball.
wolfenrain
approved these changes
May 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
The center-tap handler in
InputHandlerwas usingCameraComponent.globalToLocal(event.canvasPosition)to obtain a Y coordinate, then passing it directly as a world-space target tocameraTarget.go(). However,globalToLocalreturns viewport-space coordinates (0-1600 range for a 900x1600 camera), not world-space coordinates. Since the ball can be at world Y far from zero after bouncing up, this caused a large camera jump every time the user clicked anywhere in the center area.The fix removes the broken center-tap camera movement and adds
DragCallbacksso that clicking and dragging smoothly pans the camera target usingevent.localDelta, which is already in world-space units.Checklist
docsand added dartdoc comments with///.examplesordocs.Breaking Change?
Testing instructions
cd examples/games/crystal_ball && flutter runRelated Issues