Skip to content

Commit 1784188

Browse files
committed
fix(Canvas): Only apply text/font properties to canvas to improve performance
1 parent 1ef1c08 commit 1784188

2 files changed

Lines changed: 35 additions & 21 deletions

File tree

.changeset/curly-lies-write.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'layerchart': patch
3+
---
4+
5+
fix(Canvas): Only apply text/font properties to canvas to improve performance

packages/layerchart/src/lib/utils/canvas.ts

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ export type ComputedStylesOptions = {
2222

2323
const supportedStyles = [
2424
'fill',
25-
'stroke',
26-
'opacity',
2725
'fillOpacity',
26+
'stroke',
2827
'strokeWidth',
28+
'opacity',
2929
'fontWeight',
3030
'fontSize',
3131
'fontFamily',
@@ -109,7 +109,12 @@ function render(
109109
stroke: (ctx: CanvasRenderingContext2D) => void;
110110
fill: (ctx: CanvasRenderingContext2D) => void;
111111
},
112-
styleOptions: ComputedStylesOptions = {}
112+
styleOptions: ComputedStylesOptions = {},
113+
{
114+
applyText,
115+
}: {
116+
applyText?: boolean;
117+
} = {}
113118
) {
114119
// console.count('render');
115120

@@ -155,26 +160,29 @@ function render(
155160
ctx.globalAlpha = Number(resolvedStyles?.opacity);
156161
}
157162

158-
// Text properties
159-
ctx.font = `${resolvedStyles.fontWeight} ${resolvedStyles.fontSize} ${resolvedStyles.fontFamily}`; // build string instead of using `computedStyles.font` to fix/workaround `tabular-nums` returning `null`
163+
// font/text properties can be expensive to set (not sure why), so only apply if needed (renderText())
164+
if (applyText) {
165+
// Text properties
166+
ctx.font = `${resolvedStyles.fontWeight} ${resolvedStyles.fontSize} ${resolvedStyles.fontFamily}`; // build string instead of using `computedStyles.font` to fix/workaround `tabular-nums` returning `null`
167+
168+
// TODO: Hack to handle `textAnchor` with canvas. Try to find a better approach
169+
if (resolvedStyles.textAnchor === 'middle') {
170+
ctx.textAlign = 'center';
171+
} else if (resolvedStyles.textAnchor === 'end') {
172+
ctx.textAlign = 'right';
173+
} else {
174+
ctx.textAlign = resolvedStyles.textAlign as CanvasTextAlign; // TODO: Handle/map `justify` and `match-parent`?
175+
}
160176

161-
// TODO: Hack to handle `textAnchor` with canvas. Try to find a better approach
162-
if (resolvedStyles.textAnchor === 'middle') {
163-
ctx.textAlign = 'center';
164-
} else if (resolvedStyles.textAnchor === 'end') {
165-
ctx.textAlign = 'right';
166-
} else {
167-
ctx.textAlign = resolvedStyles.textAlign as CanvasTextAlign; // TODO: Handle/map `justify` and `match-parent`?
177+
// TODO: Handle `textBaseline` / `verticalAnchor` (Text)
178+
// ctx.textBaseline = 'top';
179+
// ctx.textBaseline = 'middle';
180+
// ctx.textBaseline = 'bottom';
181+
// ctx.textBaseline = 'alphabetic';
182+
// ctx.textBaseline = 'hanging';
183+
// ctx.textBaseline = 'ideographic';
168184
}
169185

170-
// TODO: Handle `textBaseline` / `verticalAnchor` (Text)
171-
// ctx.textBaseline = 'top';
172-
// ctx.textBaseline = 'middle';
173-
// ctx.textBaseline = 'bottom';
174-
// ctx.textBaseline = 'alphabetic';
175-
// ctx.textBaseline = 'hanging';
176-
// ctx.textBaseline = 'ideographic';
177-
178186
// Dashed lines
179187
if (resolvedStyles.strokeDasharray?.includes(',')) {
180188
const dashArray = resolvedStyles.strokeDasharray
@@ -258,7 +266,8 @@ export function renderText(
258266
fill: (ctx) => ctx.fillText(text.toString(), coords.x, coords.y),
259267
stroke: (ctx) => ctx.strokeText(text.toString(), coords.x, coords.y),
260268
},
261-
styleOptions
269+
styleOptions,
270+
{ applyText: true }
262271
);
263272
}
264273
}

0 commit comments

Comments
 (0)