Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit dee42b4

Browse files
authored
implement radial gradient in canvaskit backend (#13796)
1 parent db23a6c commit dee42b4

File tree

2 files changed

+50
-19
lines changed

2 files changed

+50
-19
lines changed

lib/web_ui/lib/src/engine/compositor/util.dart

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,28 @@ js.JsArray<double> makeSkMatrix(Float64List matrix4) {
193193
return skMatrix;
194194
}
195195

196+
/// Color stops used when the framework specifies `null`.
197+
final js.JsArray<double> _kDefaultColorStops = () {
198+
final js.JsArray<double> jsColorStops = js.JsArray<double>();
199+
jsColorStops.length = 2;
200+
jsColorStops[0] = 0;
201+
jsColorStops[1] = 1;
202+
return jsColorStops;
203+
}();
204+
205+
/// Converts a list of color stops into a Skia-compatible JS array or color stops.
206+
///
207+
/// In Flutter `null` means two color stops `[0, 1]` that in Skia must be specified explicitly.
208+
js.JsArray<double> makeSkiaColorStops(List<double> colorStops) {
209+
if (colorStops == null) {
210+
return _kDefaultColorStops;
211+
}
212+
213+
final js.JsArray<double> jsColorStops = js.JsArray<double>.from(colorStops);
214+
jsColorStops.length = colorStops.length;
215+
return jsColorStops;
216+
}
217+
196218
// These must be kept in sync with `flow/layers/physical_shape_layer.cc`.
197219
const double kLightHeight = 600.0;
198220
const double kLightRadius = 800.0;

lib/web_ui/lib/src/engine/shader.dart

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -142,21 +142,11 @@ class GradientLinear extends EngineGradient {
142142
jsColors[i] = colors[i].value;
143143
}
144144

145-
js.JsArray<double> jsColorStops;
146-
if (colorStops == null) {
147-
jsColorStops = js.JsArray<double>();
148-
jsColorStops.length = 2;
149-
jsColorStops[0] = 0;
150-
jsColorStops[1] = 1;
151-
} else {
152-
jsColorStops = js.JsArray<double>.from(colorStops);
153-
jsColorStops.length = colorStops.length;
154-
}
155145
return canvasKit.callMethod('MakeLinearGradientShader', <dynamic>[
156146
makeSkPoint(from),
157147
makeSkPoint(to),
158148
jsColors,
159-
jsColorStops,
149+
makeSkiaColorStops(colorStops),
160150
tileMode.index,
161151
]);
162152
}
@@ -178,13 +168,16 @@ class GradientRadial extends EngineGradient {
178168

179169
@override
180170
Object createPaintStyle(html.CanvasRenderingContext2D ctx) {
181-
if (matrix4 != null && !Matrix4.fromFloat64List(matrix4).isIdentity()) {
182-
throw UnimplementedError(
183-
'matrix4 not supported in GradientRadial shader');
184-
}
185-
if (tileMode != ui.TileMode.clamp) {
186-
throw UnimplementedError(
187-
'TileMode not supported in GradientRadial shader');
171+
if (!experimentalUseSkia) {
172+
// The DOM backend does not (yet) support all parameters.
173+
if (matrix4 != null && !Matrix4.fromFloat64List(matrix4).isIdentity()) {
174+
throw UnimplementedError(
175+
'matrix4 not supported in GradientRadial shader');
176+
}
177+
if (tileMode != ui.TileMode.clamp) {
178+
throw UnimplementedError(
179+
'TileMode not supported in GradientRadial shader');
180+
}
188181
}
189182
final html.CanvasGradient gradient = ctx.createRadialGradient(
190183
center.dx, center.dy, 0, center.dx, center.dy, radius);
@@ -203,7 +196,23 @@ class GradientRadial extends EngineGradient {
203196

204197
@override
205198
js.JsObject createSkiaShader() {
206-
throw UnimplementedError();
199+
assert(experimentalUseSkia);
200+
201+
final js.JsArray<num> jsColors = js.JsArray<num>();
202+
jsColors.length = colors.length;
203+
for (int i = 0; i < colors.length; i++) {
204+
jsColors[i] = colors[i].value;
205+
}
206+
207+
return canvasKit.callMethod('MakeRadialGradientShader', <dynamic>[
208+
makeSkPoint(center),
209+
radius,
210+
jsColors,
211+
makeSkiaColorStops(colorStops),
212+
tileMode.index,
213+
matrix4 != null ? makeSkMatrix(matrix4) : null,
214+
0,
215+
]);
207216
}
208217
}
209218

0 commit comments

Comments
 (0)