@tldraw/editor 5.2.0-canary.ff23978d50f6 → 5.2.0-next.355d68cf24e8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
1
- const version = "5.2.0-canary.ff23978d50f6";
1
+ const version = "5.2.0-next.355d68cf24e8";
2
2
  const publishDates = {
3
3
  major: "2026-05-06T16:28:18.473Z",
4
- minor: "2026-06-05T12:02:54.232Z",
5
- patch: "2026-06-05T12:02:54.232Z"
4
+ minor: "2026-06-05T16:25:52.737Z",
5
+ patch: "2026-06-05T16:25:52.737Z"
6
6
  };
7
7
  export {
8
8
  publishDates,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/version.ts"],
4
- "sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '5.2.0-canary.ff23978d50f6'\nexport const publishDates = {\n\tmajor: '2026-05-06T16:28:18.473Z',\n\tminor: '2026-06-05T12:02:54.232Z',\n\tpatch: '2026-06-05T12:02:54.232Z',\n}\n"],
4
+ "sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '5.2.0-next.355d68cf24e8'\nexport const publishDates = {\n\tmajor: '2026-05-06T16:28:18.473Z',\n\tminor: '2026-06-05T16:25:52.737Z',\n\tpatch: '2026-06-05T16:25:52.737Z',\n}\n"],
5
5
  "mappings": "AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tldraw/editor",
3
3
  "description": "tldraw infinite canvas SDK (editor).",
4
- "version": "5.2.0-canary.ff23978d50f6",
4
+ "version": "5.2.0-next.355d68cf24e8",
5
5
  "author": {
6
6
  "name": "tldraw Inc.",
7
7
  "email": "hello@tldraw.com"
@@ -49,12 +49,12 @@
49
49
  "@tiptap/core": "^3.12.1",
50
50
  "@tiptap/pm": "^3.12.1",
51
51
  "@tiptap/react": "^3.12.1",
52
- "@tldraw/state": "5.2.0-canary.ff23978d50f6",
53
- "@tldraw/state-react": "5.2.0-canary.ff23978d50f6",
54
- "@tldraw/store": "5.2.0-canary.ff23978d50f6",
55
- "@tldraw/tlschema": "5.2.0-canary.ff23978d50f6",
56
- "@tldraw/utils": "5.2.0-canary.ff23978d50f6",
57
- "@tldraw/validate": "5.2.0-canary.ff23978d50f6",
52
+ "@tldraw/state": "5.2.0-next.355d68cf24e8",
53
+ "@tldraw/state-react": "5.2.0-next.355d68cf24e8",
54
+ "@tldraw/store": "5.2.0-next.355d68cf24e8",
55
+ "@tldraw/tlschema": "5.2.0-next.355d68cf24e8",
56
+ "@tldraw/utils": "5.2.0-next.355d68cf24e8",
57
+ "@tldraw/validate": "5.2.0-next.355d68cf24e8",
58
58
  "classnames": "^2.5.1",
59
59
  "eventemitter3": "^4.0.7",
60
60
  "idb": "^7.1.1",
@@ -3336,6 +3336,15 @@ export class Editor extends EventEmitter<TLEventMap> {
3336
3336
 
3337
3337
  let { x, y, z = currentCamera.z } = point
3338
3338
 
3339
+ // `requested` kept the caller's focal point (e.g. the cursor) fixed at
3340
+ // zoom `rz`. When `rz` gets clamped, keep that same focal point fixed at
3341
+ // the clamped zoom `z` rather than snapping to the viewport center.
3342
+ const preserveFocalPoint = (current: number, requested: number, rz: number, z: number) => {
3343
+ const cz = currentCamera.z
3344
+ if (rz === cz) return current
3345
+ return current + ((requested - current) * (1 / z - 1 / cz)) / (1 / rz - 1 / cz)
3346
+ }
3347
+
3339
3348
  // If force is true, then we'll set the camera to the point regardless of
3340
3349
  // the camera options, so that we can handle gestures that permit elasticity
3341
3350
  // or decay, or animations that occur while the camera is locked.
@@ -3378,17 +3387,14 @@ export class Editor extends EventEmitter<TLEventMap> {
3378
3387
  }
3379
3388
 
3380
3389
  if (z < minZ || z > maxZ) {
3381
- // We're trying to zoom out past the minimum zoom level,
3382
- // or in past the maximum zoom level, so stop the camera
3383
- // but keep the current center
3384
- const { x: cx, y: cy, z: cz } = currentCamera
3385
- const cxA = -cx + vsb.w / cz / 2
3386
- const cyA = -cy + vsb.h / cz / 2
3390
+ // We're trying to zoom out past the minimum zoom level, or in
3391
+ // past the maximum zoom level, so clamp the zoom while keeping
3392
+ // the caller's focal point fixed. Axis constraints below still
3393
+ // apply on top of this.
3394
+ const rz = z
3387
3395
  z = clamp(z, minZ, maxZ)
3388
- const cxB = -cx + vsb.w / z / 2
3389
- const cyB = -cy + vsb.h / z / 2
3390
- x = cx + cxB - cxA
3391
- y = cy + cyB - cyA
3396
+ x = preserveFocalPoint(currentCamera.x, x, rz, z)
3397
+ y = preserveFocalPoint(currentCamera.y, y, rz, z)
3392
3398
  }
3393
3399
 
3394
3400
  // Calculate available space
@@ -3477,12 +3483,12 @@ export class Editor extends EventEmitter<TLEventMap> {
3477
3483
  }
3478
3484
  }
3479
3485
  } else {
3480
- // constrain the zoom, preserving the center
3486
+ // constrain the zoom, keeping the caller's focal point fixed
3481
3487
  if (z > zoomMax || z < zoomMin) {
3482
- const { x: cx, y: cy, z: cz } = currentCamera
3488
+ const rz = z
3483
3489
  z = clamp(z, zoomMin, zoomMax)
3484
- x = cx + (-cx + vsb.w / z / 2) - (-cx + vsb.w / cz / 2)
3485
- y = cy + (-cy + vsb.h / z / 2) - (-cy + vsb.h / cz / 2)
3490
+ x = preserveFocalPoint(currentCamera.x, x, rz, z)
3491
+ y = preserveFocalPoint(currentCamera.y, y, rz, z)
3486
3492
  }
3487
3493
  }
3488
3494
  }
package/src/version.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  // This file is automatically generated by internal/scripts/refresh-assets.ts.
2
2
  // Do not edit manually. Or do, I'm a comment, not a cop.
3
3
 
4
- export const version = '5.2.0-canary.ff23978d50f6'
4
+ export const version = '5.2.0-next.355d68cf24e8'
5
5
  export const publishDates = {
6
6
  major: '2026-05-06T16:28:18.473Z',
7
- minor: '2026-06-05T12:02:54.232Z',
8
- patch: '2026-06-05T12:02:54.232Z',
7
+ minor: '2026-06-05T16:25:52.737Z',
8
+ patch: '2026-06-05T16:25:52.737Z',
9
9
  }