From b8afbb4c43fda536536f9ebe0933a1fc8a49ea0f Mon Sep 17 00:00:00 2001 From: Steve Ruiz Date: Mon, 29 Apr 2024 21:43:16 +0100 Subject: [PATCH] Improve pressure-detection logic in drawing (#3639) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR improves handling of pressure in the draw tool. While we differentiate between pen and not-pen in the pointer type, there are not-pen type inputs like styluses that present as "mouse" inputs. This PR makes the freehand options for these inputs more pen-like so that they benefit from the dialing-in of options for pressure-using devices. ### Change Type - [x] `sdk` — Changes the tldraw SDK - [x] `improvement` — Improving existing features ### Test Plan 1. Use pen inputs 2. Use mouse inputs 3. Use stylus inputs - [x] Unit Tests ### Release Notes - Improves handling of mouse-type devices that support pressure, e.g. wacom tablets. They now use the same freehand options as true pen-type inputs. --- .../getting-started/releases-versioning.mdx | 21 ++++++++++++++ .../src/lib/shapes/draw/toolStates/Drawing.ts | 24 +++++++++------ .../src/lib/shapes/shared/polygon-helpers.ts | 29 +------------------ 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/apps/docs/content/getting-started/releases-versioning.mdx b/apps/docs/content/getting-started/releases-versioning.mdx index 49edd0777..c4fde73b4 100644 --- a/apps/docs/content/getting-started/releases-versioning.mdx +++ b/apps/docs/content/getting-started/releases-versioning.mdx @@ -17,6 +17,27 @@ order: 3 {/* START AUTO-GENERATED CHANGELOG */} +### [v2.1.4](/releases/v2.1.4) + +### Release Notes + +#### textfields: fix up flakiness in text selection and for unfilled geo shapes fix edit->edit (#3577) ([#3643](https://github.com/tldraw/tldraw/pull/3643)) + +- Text labels: fix up regression to selection when clicking into a text shape. (was causing flaky selections) +- Text labels: fix edit→edit not working as expected when unfilled geo shapes are on 'top' of other shapes. + +--- + +#### 🐛 Bug Fix + +- `@tldraw/editor`, `tldraw` + - textfields: fix up flakiness in text selection (#3578) + - textfields: for unfilled geo shapes fix edit->edit (#3577) [#3643](https://github.com/tldraw/tldraw/pull/3643) ([@mimecuvalo](https://github.com/mimecuvalo)) + +#### Authors: 1 + +- Mime Čuvalo ([@mimecuvalo](https://github.com/mimecuvalo)) + ### [v2.1.3](/releases/v2.1.3) #### Expose migrations, validators, and versions from tlschema ([#3613](https://github.com/tldraw/tldraw/pull/3613)) diff --git a/packages/tldraw/src/lib/shapes/draw/toolStates/Drawing.ts b/packages/tldraw/src/lib/shapes/draw/toolStates/Drawing.ts index 2b049c675..0361e076e 100644 --- a/packages/tldraw/src/lib/shapes/draw/toolStates/Drawing.ts +++ b/packages/tldraw/src/lib/shapes/draw/toolStates/Drawing.ts @@ -34,6 +34,7 @@ export class Drawing extends StateNode { util = this.editor.getShapeUtil(this.shapeType) isPen = false + isPenOrStylus = false segmentMode = 'free' as 'free' | 'straight' | 'starting_straight' | 'starting_free' @@ -64,7 +65,7 @@ export class Drawing extends StateNode { override onPointerMove: TLEventHandlers['onPointerMove'] = () => { const { inputs } = this.editor - if (this.isPen !== inputs.isPen) { + if (this.isPen && !inputs.isPen) { // The user made a palm gesture before starting a pen gesture; // ideally we'd start the new shape here but we could also just bail // as the next interaction will work correctly @@ -82,7 +83,7 @@ export class Drawing extends StateNode { } if (this.canDraw) { - if (inputs.isPen) { + if (this.isPenOrStylus) { // Don't update the shape if we haven't moved far enough from the last time we recorded a point if ( Vec.Dist(inputs.currentPagePoint, this.lastRecordedPoint) >= @@ -172,9 +173,16 @@ export class Drawing extends StateNode { this.markId = 'draw start ' + uniqueId() this.editor.mark(this.markId) + // If the pressure is weird, then it's probably a stylus reporting as a mouse + // We treat pen/stylus inputs differently in the drawing tool, so we need to + // have our own value for this. The inputs.isPen is only if the input is a regular + // pen, like an iPad pen, which needs to trigger "pen mode" in order to avoid + // accidental palm touches. We don't have to worry about that with styluses though. + const z = this.info.point.z === undefined ? 0.5 : this.info.point.z this.isPen = isPen + this.isPenOrStylus = isPen || (z > 0 && z < 0.5) || (z > 0.5 && z < 1) - const pressure = this.isPen ? this.info.point.z! * 1.25 : 0.5 + const pressure = this.isPenOrStylus ? z * 1.25 : 0.5 this.segmentMode = this.editor.inputs.shiftKey ? 'straight' : 'free' @@ -197,8 +205,6 @@ export class Drawing extends StateNode { const { x, y } = this.editor.getPointInShapeSpace(shape, originPagePoint).toFixed() - const pressure = this.isPen ? this.info.point.z! * 1.25 : 0.5 - const newSegment: TLDrawShapeSegment = { type: this.segmentMode, points: [ @@ -261,7 +267,7 @@ export class Drawing extends StateNode { x: originPagePoint.x, y: originPagePoint.y, props: { - isPen: this.isPen, + isPen: this.isPenOrStylus, segments: [ { type: this.segmentMode, @@ -300,7 +306,7 @@ export class Drawing extends StateNode { const { x, y, z } = this.editor.getPointInShapeSpace(shape, inputs.currentPagePoint).toFixed() - const newPoint = { x, y, z: this.isPen ? +(z! * 1.25).toFixed(2) : 0.5 } + const newPoint = { x, y, z: this.isPenOrStylus ? +(z! * 1.25).toFixed(2) : 0.5 } switch (this.segmentMode) { case 'starting_straight': { @@ -634,11 +640,11 @@ export class Drawing extends StateNode { x: toFixed(inputs.currentPagePoint.x), y: toFixed(inputs.currentPagePoint.y), props: { - isPen: this.isPen, + isPen: this.isPenOrStylus, segments: [ { type: 'free', - points: [{ x: 0, y: 0, z: this.isPen ? +(z! * 1.25).toFixed() : 0.5 }], + points: [{ x: 0, y: 0, z: this.isPenOrStylus ? +(z! * 1.25).toFixed() : 0.5 }], }, ], }, diff --git a/packages/tldraw/src/lib/shapes/shared/polygon-helpers.ts b/packages/tldraw/src/lib/shapes/shared/polygon-helpers.ts index a28c782c6..66aba67fe 100644 --- a/packages/tldraw/src/lib/shapes/shared/polygon-helpers.ts +++ b/packages/tldraw/src/lib/shapes/shared/polygon-helpers.ts @@ -1,31 +1,4 @@ -import { Vec, VecLike, toDomPrecision } from '@tldraw/editor' - -function precise(A: VecLike) { - return `${toDomPrecision(A.x)},${toDomPrecision(A.y)} ` -} - -function rng(seed = '') { - let x = 0 - let y = 0 - let z = 0 - let w = 0 - - function next() { - const t = x ^ (x << 11) - x = y - y = z - z = w - w ^= ((w >>> 19) ^ t ^ (t >>> 8)) >>> 0 - return (w / 0x100000000) * 2 - } - - for (let k = 0; k < seed.length + 64; k++) { - x ^= seed.charCodeAt(k) | 0 - next() - } - - return next -} +import { Vec, VecLike, precise, rng } from '@tldraw/editor' /** @public */ export function getRoundedInkyPolygonPath(points: VecLike[]) {