Commit 5884580
authored
fix(editor): keep focal point fixed when clamping zoom to min/max (tldraw#8957)
Thinks this works better than preserving the center, wdyt @steveruizok?
In order to stop the viewport from shifting when a zoom gesture
overshoots the zoom limits, this PR makes `getConstrainedCamera`
preserve the caller's focal point (e.g. the cursor) when it clamps the
zoom, instead of snapping back to the viewport center. Closes tldraw#8942.
When you wheel/pinch zoom out past the minimum (or in past the maximum),
the gesture computes a camera that keeps the point under the cursor
fixed at the *requested* zoom. The old code then clamped the zoom and
re-derived `x`/`y` to keep the viewport *center* fixed, discarding the
cursor anchor — so the canvas visibly jumped. Now the clamped camera
keeps the same focal point fixed. When that focal point happens to be
the viewport center (e.g. the zoom-out button), the math reduces to the
previous center-preserving behaviour, so nothing else changes.
`zoomIn`/`zoomOut` are unaffected because they snap exactly onto zoom
steps and never overshoot.
### Before
https://github.com/user-attachments/assets/0cc13c03-2ea5-4642-bcf4-2c5f62e57e4d
### After
https://github.com/user-attachments/assets/b800a301-b101-4e98-8303-3e5801b7bbeb
### Change type
- [x] `bugfix`
### Test plan
1. Open the editor at any zoom level with the pointer away from the
screen center.
2. Wheel- or pinch-zoom out until the zoom clamps at the minimum.
3. The point under the cursor should stay put as the zoom hits the
limit; further zoom-out gestures should not move the canvas.
4. Repeat zooming in past the maximum.
- [x] Unit tests
### Release notes
- Fix the viewport shifting slightly when zooming past the minimum or
maximum zoom level.
### Code changes
| Section | LOC change |
| --------- | ---------- |
| Core code | +20 / -14 |
| Tests | +97 / -1 |1 parent 5974f76 commit 5884580
2 files changed
Lines changed: 117 additions & 15 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3336 | 3336 | | |
3337 | 3337 | | |
3338 | 3338 | | |
| 3339 | + | |
| 3340 | + | |
| 3341 | + | |
| 3342 | + | |
| 3343 | + | |
| 3344 | + | |
| 3345 | + | |
| 3346 | + | |
| 3347 | + | |
3339 | 3348 | | |
3340 | 3349 | | |
3341 | 3350 | | |
| |||
3378 | 3387 | | |
3379 | 3388 | | |
3380 | 3389 | | |
3381 | | - | |
3382 | | - | |
3383 | | - | |
3384 | | - | |
3385 | | - | |
3386 | | - | |
| 3390 | + | |
| 3391 | + | |
| 3392 | + | |
| 3393 | + | |
| 3394 | + | |
3387 | 3395 | | |
3388 | | - | |
3389 | | - | |
3390 | | - | |
3391 | | - | |
| 3396 | + | |
| 3397 | + | |
3392 | 3398 | | |
3393 | 3399 | | |
3394 | 3400 | | |
| |||
3477 | 3483 | | |
3478 | 3484 | | |
3479 | 3485 | | |
3480 | | - | |
| 3486 | + | |
3481 | 3487 | | |
3482 | | - | |
| 3488 | + | |
3483 | 3489 | | |
3484 | | - | |
3485 | | - | |
| 3490 | + | |
| 3491 | + | |
3486 | 3492 | | |
3487 | 3493 | | |
3488 | 3494 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| |||
141 | 141 | | |
142 | 142 | | |
143 | 143 | | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
144 | 240 | | |
145 | 241 | | |
146 | 242 | | |
| |||
0 commit comments