Skip to content

Commit 96f18a6

Browse files
authored
refactor(editor): split text outline update into its own reactor (tldraw#8833)
In order to keep the camera position reactor focused on positioning the HTML layer, this PR moves the text outline / LOD logic into a dedicated `set text outline` quick reactor. The new reactor reads `editor.getEfficientZoomLevel()` and only updates the `--tl-text-outline` CSS custom property when the LOD bucket changes, instead of recomputing the check on every camera tick alongside the layer transform. The `allowTextOutline` ref is renamed to `canUpdateTextOutline` to better describe what the flag does — it gates future updates after Safari's one-shot opt-out. ### Change type - [x] `improvement` ### Test plan 1. Open the examples app and pan/zoom the canvas; text shapes should still toggle outlines when crossing the `textShadowLod` threshold. 2. Open the examples app in Safari and verify that text outlines remain disabled. - [ ] Unit tests - [ ] End to end tests ### Release notes - Internal refactor: split text outline updates into their own reactor on the canvas. ### Code changes | Section | LOC change | | --------- | ---------- | | Core code | +34 / -26 |
1 parent 8dccc2a commit 96f18a6

1 file changed

Lines changed: 34 additions & 26 deletions

File tree

packages/editor/src/lib/components/default-components/DefaultCanvas.tsx

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -63,44 +63,52 @@ export function DefaultCanvas({ className }: TLCanvasComponentProps) {
6363
[editor]
6464
)
6565

66-
const rMemoizedStuff = useRef({ lodDisableTextOutline: false, allowTextOutline: true })
66+
const rMemoizedStuff = useRef({ lodDisableTextOutline: false, canUpdateTextOutline: true })
67+
68+
useQuickReactor(
69+
'set text outline',
70+
function setTextOutline() {
71+
if (rMemoizedStuff.current.canUpdateTextOutline) {
72+
if (tlenv.isSafari) {
73+
// We don't allow text outlines on safari for performance reasons
74+
container.style.setProperty('--tl-text-outline', 'none')
75+
rMemoizedStuff.current.canUpdateTextOutline = false // will prevent this check in the future
76+
} else {
77+
const efficientZoom = editor.getEfficientZoomLevel()
78+
// If we're zoomed way out, and have this option enabled, then we hide text outline
79+
const lodDisableTextOutline = efficientZoom < editor.options.textShadowLod
80+
// Skip the style update if the property is the same as it was before
81+
if (lodDisableTextOutline !== rMemoizedStuff.current.lodDisableTextOutline) {
82+
container.style.setProperty(
83+
'--tl-text-outline',
84+
lodDisableTextOutline ? 'none' : `var(--tl-text-outline-reference)`
85+
)
86+
}
87+
rMemoizedStuff.current.lodDisableTextOutline = lodDisableTextOutline
88+
}
89+
}
90+
},
91+
[editor, container]
92+
)
6793

6894
useQuickReactor(
6995
'position layers',
7096
function positionLayersWhenCameraMoves() {
7197
const { x, y, z } = editor.getCamera()
7298

73-
// This should only run once on first load
74-
if (rMemoizedStuff.current.allowTextOutline && tlenv.isSafari) {
75-
container.style.setProperty('--tl-text-outline', 'none')
76-
rMemoizedStuff.current.allowTextOutline = false
77-
}
78-
79-
// And this should only run if we're not in Safari;
80-
// If we're below the lod distance for text shadows, turn them off
81-
if (
82-
rMemoizedStuff.current.allowTextOutline &&
83-
z < editor.options.textShadowLod !== rMemoizedStuff.current.lodDisableTextOutline
84-
) {
85-
const lodDisableTextOutline = z < editor.options.textShadowLod
86-
container.style.setProperty(
87-
'--tl-text-outline',
88-
lodDisableTextOutline ? 'none' : `var(--tl-text-outline-reference)`
89-
)
90-
rMemoizedStuff.current.lodDisableTextOutline = lodDisableTextOutline
91-
}
92-
9399
// Because the html container has a width/height of 1px, we
94100
// need to create a small offset when zoomed to ensure that
95101
// the html container and svg container are lined up exactly.
96102
const offset =
97103
z >= 1 ? modulate(z, [1, 8], [0.125, 0.5], true) : modulate(z, [0.1, 1], [-2, 0.125], true)
98104

99-
const transform = `scale(${toDomPrecision(z)}) translate(${toDomPrecision(
100-
x + offset
101-
)}px,${toDomPrecision(y + offset)}px)`
102-
103-
setStyleProperty(rHtmlLayer.current, 'transform', transform)
105+
setStyleProperty(
106+
rHtmlLayer.current,
107+
'transform',
108+
`scale(${toDomPrecision(z)}) translate(${toDomPrecision(
109+
x + offset
110+
)}px,${toDomPrecision(y + offset)}px)`
111+
)
104112
},
105113
[editor, container]
106114
)

0 commit comments

Comments
 (0)