Skip to content

Commit 329d6e7

Browse files
authored
Merge pull request #6 from Zettersten/feature/blazorcanvas2d-gradient-error-3295
BlazorCanvas2d gradient error
2 parents 53ead5f + 13c27db commit 329d6e7

File tree

2 files changed

+59
-2
lines changed

2 files changed

+59
-2
lines changed

BlazorCanvas2d/wwwroot/blazorCanvas2d.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,26 @@ const DEFAULT_CANVAS_OPTIONS = {
66
};
77
const MARSHAL_REFERENCE_PROPERTIES = ['fillStyle', 'strokeStyle'];
88
const PRINTABLE_KEYS = ['Enter', 'Tab', 'Backspace', 'Delete'];
9+
const GRADIENT_METHODS = new Set(['createLinearGradient', 'createRadialGradient', 'createConicGradient']);
10+
const sanitizeNonFiniteNumbers = (args) => {
11+
let out = null;
12+
for (let i = 0; i < args.length; i++) {
13+
const v = args[i];
14+
if (typeof v === 'number' && !Number.isFinite(v)) {
15+
out ?? (out = Array.from(args));
16+
out[i] = 0;
17+
}
18+
}
19+
return out ?? args;
20+
};
21+
const sanitizeNonFiniteNumbersInPlace = (args) => {
22+
for (let i = 0; i < args.length; i++) {
23+
const v = args[i];
24+
if (typeof v === 'number' && !Number.isFinite(v)) {
25+
args[i] = 0;
26+
}
27+
}
28+
};
929
const createBlazorexAPIImpl = () => {
1030
const canvasContexts = new Map();
1131
const elementCache = new Map();
@@ -165,11 +185,17 @@ const createBlazorexAPIImpl = () => {
165185
}
166186
const firstParam = parameters[0];
167187
if (!isMarshalReference(firstParam)) {
168-
return typedContext[methodName](...parameters);
188+
const safeParams = GRADIENT_METHODS.has(methodName)
189+
? sanitizeNonFiniteNumbers(parameters)
190+
: parameters;
191+
return typedContext[methodName](...safeParams);
169192
}
170193
const marshalRef = firstParam;
171194
if (!marshalRef.isElementRef) {
172195
const args = parameters.slice(1);
196+
if (GRADIENT_METHODS.has(methodName)) {
197+
sanitizeNonFiniteNumbersInPlace(args);
198+
}
173199
const existingObject = marshalledObjects.get(marshalRef.id);
174200
if (existingObject?.[methodName]) {
175201
if (marshalRef.classInitializer) {

BlazorCanvas2d/wwwroot/blazorCanvas2d.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,31 @@ const DEFAULT_CANVAS_OPTIONS: CanvasContextOptions = {
3030
const MARSHAL_REFERENCE_PROPERTIES = ['fillStyle', 'strokeStyle'] as const;
3131
const PRINTABLE_KEYS = ['Enter', 'Tab', 'Backspace', 'Delete'];
3232

33+
const GRADIENT_METHODS = new Set(['createLinearGradient', 'createRadialGradient', 'createConicGradient']);
34+
35+
const sanitizeNonFiniteNumbers = (args: readonly unknown[]): unknown[] => {
36+
let out: unknown[] | null = null;
37+
38+
for (let i = 0; i < args.length; i++) {
39+
const v = args[i];
40+
if (typeof v === 'number' && !Number.isFinite(v)) {
41+
out ??= Array.from(args);
42+
out[i] = 0;
43+
}
44+
}
45+
46+
return out ?? (args as unknown[]);
47+
};
48+
49+
const sanitizeNonFiniteNumbersInPlace = (args: unknown[]): void => {
50+
for (let i = 0; i < args.length; i++) {
51+
const v = args[i];
52+
if (typeof v === 'number' && !Number.isFinite(v)) {
53+
args[i] = 0;
54+
}
55+
}
56+
};
57+
3358
/**
3459
* Creates a new BlazorCanvas2d API instance with isolated state
3560
* @returns A frozen BlazorexAPI instance
@@ -312,7 +337,10 @@ const createBlazorexAPIImpl = (): BlazorexAPI => {
312337

313338
// Hot path: no marshal reference => no need to copy/modify args
314339
if (!isMarshalReference(firstParam)) {
315-
return typedContext[methodName](...parameters);
340+
const safeParams = GRADIENT_METHODS.has(methodName)
341+
? sanitizeNonFiniteNumbers(parameters)
342+
: (parameters as unknown[]);
343+
return typedContext[methodName](...safeParams);
316344
}
317345

318346
// Handle C# MarshalReference objects
@@ -321,6 +349,9 @@ const createBlazorexAPIImpl = (): BlazorexAPI => {
321349
if (!marshalRef.isElementRef) {
322350
// This is a marshal object reference (gradient, pattern, etc.)
323351
const args = parameters.slice(1);
352+
if (GRADIENT_METHODS.has(methodName)) {
353+
sanitizeNonFiniteNumbersInPlace(args);
354+
}
324355
const existingObject = marshalledObjects.get(marshalRef.id) as
325356
| Record<string, Function>
326357
| undefined;

0 commit comments

Comments
 (0)