@@ -17,30 +17,46 @@ public _ColorsAndStops(List<Color> colors, List<float> stops) {
17
17
public readonly List < Color > colors ;
18
18
public readonly List < float > stops ;
19
19
20
- public static _ColorsAndStops _interpolateColorsAndStops (
21
- List < Color > aColors , List < float > aStops , List < Color > bColors , List < float > bStops , float t ) {
22
- D . assert ( aColors . Count == bColors . Count ,
23
- ( ) => "Cannot interpolate between two gradients with a different number of colors." ) ;
24
- D . assert ( ( aStops == null && aColors . Count == 2 ) || ( aStops != null && aStops . Count == aColors . Count ) ) ;
25
- D . assert ( ( bStops == null && bColors . Count == 2 ) || ( bStops != null && bStops . Count == bColors . Count ) ) ;
26
- List < Color > interpolatedColors = new List < Color > ( ) ;
20
+ static Color _sample ( List < Color > colors , List < float > stops , float t ) {
21
+ D . assert ( colors != null ) ;
22
+ D . assert ( colors . isNotEmpty ) ;
23
+ D . assert ( stops != null ) ;
24
+ D . assert ( stops . isNotEmpty ) ;
27
25
28
- for ( int i = 0 ; i < aColors . Count ; i += 1 ) {
29
- interpolatedColors . Add ( Color . lerp ( aColors [ i ] , bColors [ i ] , t ) ) ;
26
+ if ( t < stops . first ( ) ) {
27
+ return colors . first ( ) ;
30
28
}
31
29
32
- List < float > interpolatedStops = null ;
33
- if ( aStops != null || bStops != null ) {
34
- aStops = aStops ?? new List < float > { 0.0f , 1.0f } ;
35
- bStops = bStops ?? new List < float > { 0.0f , 1.0f } ;
36
-
37
- D . assert ( aStops . Count == bStops . Count ) ;
38
- interpolatedStops = new List < float > ( ) ;
39
- for ( int i = 0 ; i < aStops . Count ; i += 1 ) {
40
- interpolatedStops . Add ( MathUtils . lerpFloat ( aStops [ i ] , bStops [ i ] , t ) . clamp ( 0.0f , 1.0f ) ) ;
41
- }
30
+ if ( t < stops . last ( ) ) {
31
+ return colors . last ( ) ;
42
32
}
43
33
34
+ int index = stops . FindLastIndex ( ( float s ) => { return s <= t ; } ) ;
35
+ D . assert ( index != - 1 ) ;
36
+ return Color . lerp ( colors [ index ] , colors [ index + 1 ] ,
37
+ ( t - stops [ index ] ) / ( stops [ index + 1 ] - stops [ index ] ) ) ;
38
+ }
39
+
40
+ internal static _ColorsAndStops _interpolateColorsAndStops (
41
+ List < Color > aColors ,
42
+ List < float > aStops ,
43
+ List < Color > bColors ,
44
+ List < float > bStops ,
45
+ float t ) {
46
+ D . assert ( aColors . Count >= 2 ) ;
47
+ D . assert ( bColors . Count >= 2 ) ;
48
+ D . assert ( aStops . Count == aColors . Count ) ;
49
+ D . assert ( bStops . Count == bColors . Count ) ;
50
+
51
+ SplayTree < float , bool > stops = new SplayTree < float , bool > ( ) ;
52
+ stops . AddAll ( aStops ) ;
53
+ stops . AddAll ( bStops ) ;
54
+
55
+ List < float > interpolatedStops = stops . Keys . ToList ( ) ;
56
+ List < Color > interpolatedColors = interpolatedStops . Select < float , Color > ( ( float stop ) => {
57
+ return Color . lerp ( _sample ( aColors , aStops , stop ) , _sample ( bColors , bStops , stop ) , t ) ;
58
+ } ) . ToList ( ) ;
59
+
44
60
return new _ColorsAndStops ( interpolatedColors , interpolatedStops ) ;
45
61
}
46
62
}
@@ -65,10 +81,6 @@ protected List<float> _impliedStops() {
65
81
return this . stops ;
66
82
}
67
83
68
- if ( this . colors . Count == 2 ) {
69
- return null ;
70
- }
71
-
72
84
D . assert ( this . colors . Count >= 2 , ( ) => "colors list must have at least two colors" ) ;
73
85
float separation = 1.0f / ( this . colors . Count - 1 ) ;
74
86
@@ -159,16 +171,16 @@ public override Gradient scale(float factor) {
159
171
}
160
172
161
173
protected override Gradient lerpFrom ( Gradient a , float t ) {
162
- if ( a == null || ( a is LinearGradient && a . colors . Count == this . colors . Count ) ) {
163
- return LinearGradient . lerp ( ( LinearGradient ) a , this , t ) ;
174
+ if ( a == null || ( a is LinearGradient ) ) {
175
+ return lerp ( ( LinearGradient ) a , this , t ) ;
164
176
}
165
177
166
178
return base . lerpFrom ( a , t ) ;
167
179
}
168
180
169
181
protected override Gradient lerpTo ( Gradient b , float t ) {
170
- if ( b == null || ( b is LinearGradient && b . colors . Count == this . colors . Count ) ) {
171
- return LinearGradient . lerp ( this , ( LinearGradient ) b , t ) ;
182
+ if ( b == null || ( b is LinearGradient ) ) {
183
+ return lerp ( this , ( LinearGradient ) b , t ) ;
172
184
}
173
185
174
186
return base . lerpTo ( b , t ) ;
@@ -187,8 +199,12 @@ public static LinearGradient lerp(LinearGradient a, LinearGradient b, float t) {
187
199
return ( LinearGradient ) a . scale ( 1.0f - t ) ;
188
200
}
189
201
190
- _ColorsAndStops interpolated =
191
- _ColorsAndStops . _interpolateColorsAndStops ( a . colors , a . stops , b . colors , b . stops , t ) ;
202
+ _ColorsAndStops interpolated = _ColorsAndStops . _interpolateColorsAndStops (
203
+ a . colors ,
204
+ a . _impliedStops ( ) ,
205
+ b . colors ,
206
+ b . _impliedStops ( ) ,
207
+ t ) ;
192
208
return new LinearGradient (
193
209
begin : Alignment . lerp ( a . begin , b . begin , t ) ,
194
210
end : Alignment . lerp ( a . end , b . end , t ) ,
@@ -250,7 +266,7 @@ public override int GetHashCode() {
250
266
return ! Equals ( left , right ) ;
251
267
}
252
268
253
- public override String ToString ( ) {
269
+ public override string ToString ( ) {
254
270
return $ "{ this . GetType ( ) } ({ this . begin } , { this . end } ," +
255
271
$ "{ this . colors . toStringList ( ) } , { this . stops . toStringList ( ) } , { this . tileMode } )";
256
272
}
@@ -296,16 +312,16 @@ public override Gradient scale(float factor) {
296
312
}
297
313
298
314
protected override Gradient lerpFrom ( Gradient a , float t ) {
299
- if ( a == null || ( a is RadialGradient && a . colors . Count == this . colors . Count ) ) {
300
- return RadialGradient . lerp ( ( RadialGradient ) a , this , t ) ;
315
+ if ( a == null || ( a is RadialGradient ) ) {
316
+ return lerp ( ( RadialGradient ) a , this , t ) ;
301
317
}
302
318
303
319
return base . lerpFrom ( a , t ) ;
304
320
}
305
321
306
322
protected override Gradient lerpTo ( Gradient b , float t ) {
307
- if ( b == null || ( b is RadialGradient && b . colors . Count == this . colors . Count ) ) {
308
- return RadialGradient . lerp ( this , ( RadialGradient ) b , t ) ;
323
+ if ( b == null || ( b is RadialGradient ) ) {
324
+ return lerp ( this , ( RadialGradient ) b , t ) ;
309
325
}
310
326
311
327
return base . lerpTo ( b , t ) ;
@@ -324,8 +340,12 @@ public static RadialGradient lerp(RadialGradient a, RadialGradient b, float t) {
324
340
return ( RadialGradient ) a . scale ( 1.0f - t ) ;
325
341
}
326
342
327
- _ColorsAndStops interpolated =
328
- _ColorsAndStops . _interpolateColorsAndStops ( a . colors , a . stops , b . colors , b . stops , t ) ;
343
+ _ColorsAndStops interpolated = _ColorsAndStops . _interpolateColorsAndStops (
344
+ a . colors ,
345
+ a . _impliedStops ( ) ,
346
+ b . colors ,
347
+ b . _impliedStops ( ) ,
348
+ t ) ;
329
349
return new RadialGradient (
330
350
center : Alignment . lerp ( a . center , b . center , t ) ,
331
351
radius : Mathf . Max ( 0.0f , MathUtils . lerpFloat ( a . radius , b . radius , t ) ) ,
@@ -387,7 +407,7 @@ public override int GetHashCode() {
387
407
return ! Equals ( left , right ) ;
388
408
}
389
409
390
- public override String ToString ( ) {
410
+ public override string ToString ( ) {
391
411
return $ "{ this . GetType ( ) } ({ this . center } , { this . radius } ," +
392
412
$ "{ this . colors . toStringList ( ) } , { this . stops . toStringList ( ) } , { this . tileMode } )";
393
413
}
@@ -439,7 +459,7 @@ public override Gradient scale(float factor) {
439
459
440
460
protected override Gradient lerpFrom ( Gradient a , float t ) {
441
461
if ( a == null || ( a is SweepGradient && a . colors . Count == this . colors . Count ) ) {
442
- return SweepGradient . lerp ( ( SweepGradient ) a , this , t ) ;
462
+ return lerp ( ( SweepGradient ) a , this , t ) ;
443
463
}
444
464
445
465
return base . lerpFrom ( a , t ) ;
@@ -532,7 +552,7 @@ public override int GetHashCode() {
532
552
return ! Equals ( left , right ) ;
533
553
}
534
554
535
- public override String ToString ( ) {
555
+ public override string ToString ( ) {
536
556
return $ "{ this . GetType ( ) } ({ this . center } , { this . startAngle } , { this . endAngle } , " +
537
557
$ "{ this . colors . toStringList ( ) } , { this . stops . toStringList ( ) } , { this . tileMode } )";
538
558
}
0 commit comments