Add SweepGradient (#17368)
This PR adds a SweepGradient class, extending Gradient to expose the engine's ui.Gradient.sweep shader. Similar to LinearGradient and RadialGradient - SweepGradients can be used in a BoxDecoration or passed to a Paint's shader.
This commit is contained in:
parent
6fc7199dcc
commit
d57cc44f05
1
AUTHORS
1
AUTHORS
@ -23,3 +23,4 @@ Ali Bitek <alibitek@protonmail.ch>
|
||||
Tetsuhiro Ueda <najeira@gmail.com>
|
||||
Dan Field <dfield@gmail.com>
|
||||
Noah Groß <gross@ngsger.de>
|
||||
Victor Choueiri <victor@ctrlanddev.com>
|
||||
|
@ -37,8 +37,8 @@ _ColorsAndStops _interpolateColorsAndStops(List<Color> aColors, List<double> aSt
|
||||
|
||||
/// A 2D gradient.
|
||||
///
|
||||
/// This is an interface that allows [LinearGradient] and [RadialGradient]
|
||||
/// classes to be used interchangeably in [BoxDecoration]s.
|
||||
/// This is an interface that allows [LinearGradient], [RadialGradient], and
|
||||
/// [SweepGradient] classes to be used interchangeably in [BoxDecoration]s.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
@ -214,9 +214,9 @@ abstract class Gradient {
|
||||
|
||||
/// A 2D linear gradient.
|
||||
///
|
||||
/// This class is used by [BoxDecoration] to represent gradients. This abstracts
|
||||
/// out the arguments to the [new ui.Gradient.linear] constructor from the
|
||||
/// `dart:ui` library.
|
||||
/// This class is used by [BoxDecoration] to represent linear gradients. This
|
||||
/// abstracts out the arguments to the [new ui.Gradient.linear] constructor from
|
||||
/// the `dart:ui` library.
|
||||
///
|
||||
/// A gradient has two anchor points, [begin] and [end]. The [begin] point
|
||||
/// corresponds to 0.0, and the [end] point corresponds to 1.0. These points are
|
||||
@ -258,6 +258,8 @@ abstract class Gradient {
|
||||
///
|
||||
/// * [RadialGradient], which displays a gradient in concentric circles, and
|
||||
/// has an example which shows a different way to use [Gradient] objects.
|
||||
/// * [SweepGradient], which displays a gradient in a sweeping arc around a
|
||||
/// center point.
|
||||
/// * [BoxDecoration], which can take a [LinearGradient] in its
|
||||
/// [BoxDecoration.gradient] property.
|
||||
class LinearGradient extends Gradient {
|
||||
@ -278,14 +280,14 @@ class LinearGradient extends Gradient {
|
||||
|
||||
/// The offset at which stop 0.0 of the gradient is placed.
|
||||
///
|
||||
/// If this is a [Alignment], then it is expressed as a vector from
|
||||
/// If this is an [Alignment], then it is expressed as a vector from
|
||||
/// coordinate (0.0, 0.0), in a coordinate space that maps the center of the
|
||||
/// paint box at (0.0, 0.0) and the bottom right at (1.0, 1.0).
|
||||
///
|
||||
/// For example, a begin offset of (-1.0, 0.0) is half way down the
|
||||
/// left side of the box.
|
||||
///
|
||||
/// It can also be a [AlignmentDirectional], where the start is the
|
||||
/// It can also be an [AlignmentDirectional], where the start is the
|
||||
/// left in left-to-right contexts and the right in right-to-left contexts. If
|
||||
/// a text-direction-dependent value is provided here, then the [createShader]
|
||||
/// method will need to be given a [TextDirection].
|
||||
@ -293,14 +295,14 @@ class LinearGradient extends Gradient {
|
||||
|
||||
/// The offset at which stop 1.0 of the gradient is placed.
|
||||
///
|
||||
/// If this is a [Alignment], then it is expressed as a vector from
|
||||
/// If this is an [Alignment], then it is expressed as a vector from
|
||||
/// coordinate (0.0, 0.0), in a coordinate space that maps the center of the
|
||||
/// paint box at (0.0, 0.0) and the bottom right at (1.0, 1.0).
|
||||
///
|
||||
/// For example, a begin offset of (1.0, 0.0) is half way down the
|
||||
/// right side of the box.
|
||||
///
|
||||
/// It can also be a [AlignmentDirectional], where the start is the left in
|
||||
/// It can also be an [AlignmentDirectional], where the start is the left in
|
||||
/// left-to-right contexts and the right in right-to-left contexts. If a
|
||||
/// text-direction-dependent value is provided here, then the [createShader]
|
||||
/// method will need to be given a [TextDirection].
|
||||
@ -325,10 +327,10 @@ class LinearGradient extends Gradient {
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns a new [LinearGradient] with its properties (in particular the
|
||||
/// colors) scaled by the given factor.
|
||||
/// Returns a new [LinearGradient] with its colors scaled by the given factor.
|
||||
///
|
||||
/// If the factor is 0.0 or less, then the gradient is fully transparent.
|
||||
/// Since the alpha component of the Color is what is scaled, a factor
|
||||
/// of 0.0 or less results in a gradient that is fully transparent.
|
||||
@override
|
||||
LinearGradient scale(double factor) {
|
||||
return new LinearGradient(
|
||||
@ -362,7 +364,7 @@ class LinearGradient extends Gradient {
|
||||
///
|
||||
/// If neither gradient is null, they must have the same number of [colors].
|
||||
///
|
||||
/// The `t` argument represents position on the timeline, with 0.0 meaning
|
||||
/// The `t` argument represents a position on the timeline, with 0.0 meaning
|
||||
/// that the interpolation has not started, returning `a` (or something
|
||||
/// equivalent to `a`), 1.0 meaning that the interpolation has finished,
|
||||
/// returning `b` (or something equivalent to `b`), and values in between
|
||||
@ -434,9 +436,9 @@ class LinearGradient extends Gradient {
|
||||
|
||||
/// A 2D radial gradient.
|
||||
///
|
||||
/// This class is used by [BoxDecoration] to represent gradients. This abstracts
|
||||
/// out the arguments to the [new ui.Gradient.radial] constructor from the
|
||||
/// `dart:ui` library.
|
||||
/// This class is used by [BoxDecoration] to represent radial gradients. This
|
||||
/// abstracts out the arguments to the [new ui.Gradient.radial] constructor from
|
||||
/// the `dart:ui` library.
|
||||
///
|
||||
/// A gradient has a [center] and a [radius]. The [center] point corresponds to
|
||||
/// 0.0, and the ring at [radius] from the center corresponds to 1.0. These
|
||||
@ -483,6 +485,8 @@ class LinearGradient extends Gradient {
|
||||
///
|
||||
/// * [LinearGradient], which displays a gradient in parallel lines, and has an
|
||||
/// example which shows a different way to use [Gradient] objects.
|
||||
/// * [SweepGradient], which displays a gradient in a sweeping arc around a
|
||||
/// center point.
|
||||
/// * [BoxDecoration], which can take a [RadialGradient] in its
|
||||
/// [BoxDecoration.gradient] property.
|
||||
/// * [CustomPainter], which shows how to use the above sample code in a custom
|
||||
@ -509,11 +513,11 @@ class RadialGradient extends Gradient {
|
||||
/// For example, an alignment of (0.0, 0.0) will place the radial
|
||||
/// gradient in the center of the box.
|
||||
///
|
||||
/// If this is a [Alignment], then it is expressed as a vector from
|
||||
/// If this is an [Alignment], then it is expressed as a vector from
|
||||
/// coordinate (0.0, 0.0), in a coordinate space that maps the center of the
|
||||
/// paint box at (0.0, 0.0) and the bottom right at (1.0, 1.0).
|
||||
///
|
||||
/// It can also be a [AlignmentDirectional], where the start is the left in
|
||||
/// It can also be an [AlignmentDirectional], where the start is the left in
|
||||
/// left-to-right contexts and the right in right-to-left contexts. If a
|
||||
/// text-direction-dependent value is provided here, then the [createShader]
|
||||
/// method will need to be given a [TextDirection].
|
||||
@ -548,7 +552,8 @@ class RadialGradient extends Gradient {
|
||||
|
||||
/// Returns a new [RadialGradient] with its colors scaled by the given factor.
|
||||
///
|
||||
/// If the factor is 0.0 or less, then the gradient is fully transparent.
|
||||
/// Since the alpha component of the Color is what is scaled, a factor
|
||||
/// of 0.0 or less results in a gradient that is fully transparent.
|
||||
@override
|
||||
RadialGradient scale(double factor) {
|
||||
return new RadialGradient(
|
||||
@ -582,7 +587,7 @@ class RadialGradient extends Gradient {
|
||||
///
|
||||
/// If neither gradient is null, they must have the same number of [colors].
|
||||
///
|
||||
/// The `t` argument represents position on the timeline, with 0.0 meaning
|
||||
/// The `t` argument represents a position on the timeline, with 0.0 meaning
|
||||
/// that the interpolation has not started, returning `a` (or something
|
||||
/// equivalent to `a`), 1.0 meaning that the interpolation has finished,
|
||||
/// returning `b` (or something equivalent to `b`), and values in between
|
||||
@ -651,3 +656,230 @@ class RadialGradient extends Gradient {
|
||||
return '$runtimeType($center, $radius, $colors, $stops, $tileMode)';
|
||||
}
|
||||
}
|
||||
|
||||
/// A 2D sweep gradient.
|
||||
///
|
||||
/// This class is used by [BoxDecoration] to represent sweep gradients. This
|
||||
/// abstracts out the arguments to the [new ui.Gradient.sweep] constructor from
|
||||
/// the `dart:ui` library.
|
||||
///
|
||||
/// A gradient has a [center], a [startAngle], and an [endAngle]. The [startAngle]
|
||||
/// corresponds to 0.0, and the [endAngle] corresponds to 1.0. These angles are
|
||||
/// expressed in radians.
|
||||
///
|
||||
/// The [colors] are described by a list of [Color] objects. There must be at
|
||||
/// least two colors. The [stops] list, if specified, must have the same length
|
||||
/// as [colors]. It specifies fractions of the vector from start to end, between
|
||||
/// 0.0 and 1.0, for each color. If it is null, a uniform distribution is
|
||||
/// assumed.
|
||||
///
|
||||
/// The region of the canvas before [startAngle] and after [endAngle] is colored
|
||||
/// according to [tileMode].
|
||||
///
|
||||
/// Typically this class is used with [BoxDecoration], which does the painting.
|
||||
/// To use a [SweepGradient] to paint on a canvas directly, see [createShader].
|
||||
///
|
||||
/// ## Sample code
|
||||
///
|
||||
/// This sample draws a different color in each quadrant.
|
||||
///
|
||||
/// ```dart
|
||||
/// new Container(
|
||||
/// decoration: new BoxDecoration(
|
||||
/// gradient: new SweepGradient(
|
||||
/// center: FractionalOffset.center,
|
||||
/// startAngle: 0.0,
|
||||
/// endAngle: math.pi * 2,
|
||||
/// colors: const <Color>[
|
||||
/// const Color(0xFF4285F4), // blue
|
||||
/// const Color(0xFF34A853), // green
|
||||
/// const Color(0xFFFBBC05), // yellow
|
||||
/// const Color(0xFFEA4335), // red
|
||||
/// const Color(0xFF4285F4), // blue again to seamlessly transition to the start
|
||||
/// ],
|
||||
/// stops: const <double>[0.0, 0.25, 0.5, 0.75, 1.0],
|
||||
/// ),
|
||||
/// ),
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [LinearGradient], which displays a gradient in parallel lines, and has an
|
||||
/// example which shows a different way to use [Gradient] objects.
|
||||
/// * [RadialGradient], which displays a gradient in concentric circles, and
|
||||
/// has an example which shows a different way to use [Gradient] objects.
|
||||
/// * [BoxDecoration], which can take a [SweepGradient] in its
|
||||
/// [BoxDecoration.gradient] property.
|
||||
class SweepGradient extends Gradient {
|
||||
/// Creates a sweep gradient.
|
||||
///
|
||||
/// The [colors] argument must not be null. If [stops] is non-null, it must
|
||||
/// have the same length as [colors].
|
||||
const SweepGradient({
|
||||
this.center: Alignment.center,
|
||||
this.startAngle: 0.0,
|
||||
this.endAngle: math.pi * 2,
|
||||
@required List<Color> colors,
|
||||
List<double> stops,
|
||||
this.tileMode: TileMode.clamp,
|
||||
}) : assert(center != null),
|
||||
assert(startAngle != null),
|
||||
assert(endAngle != null),
|
||||
assert(tileMode != null),
|
||||
super(colors: colors, stops: stops);
|
||||
|
||||
/// The center of the gradient, as an offset into the (-1.0, -1.0) x (1.0, 1.0)
|
||||
/// square describing the gradient which will be mapped onto the paint box.
|
||||
///
|
||||
/// For example, an alignment of (0.0, 0.0) will place the sweep
|
||||
/// gradient in the center of the box.
|
||||
///
|
||||
/// If this is an [Alignment], then it is expressed as a vector from
|
||||
/// coordinate (0.0, 0.0), in a coordinate space that maps the center of the
|
||||
/// paint box at (0.0, 0.0) and the bottom right at (1.0, 1.0).
|
||||
///
|
||||
/// It can also be an [AlignmentDirectional], where the start is the left in
|
||||
/// left-to-right contexts and the right in right-to-left contexts. If a
|
||||
/// text-direction-dependent value is provided here, then the [createShader]
|
||||
/// method will need to be given a [TextDirection].
|
||||
final AlignmentGeometry center;
|
||||
|
||||
/// The angle in radians at which stop 0.0 of the gradient is placed.
|
||||
///
|
||||
/// Defaults to 0.0.
|
||||
final double startAngle;
|
||||
|
||||
/// The angle in radians at which stop 1.0 of the gradient is placed.
|
||||
///
|
||||
/// Defaults to math.pi * 2.
|
||||
final double endAngle;
|
||||
|
||||
/// How this gradient should tile the plane beyond in the region before
|
||||
/// [startAngle] and after [endAngle].
|
||||
///
|
||||
/// For details, see [TileMode].
|
||||
///
|
||||
/// 
|
||||
/// 
|
||||
/// 
|
||||
final TileMode tileMode;
|
||||
|
||||
@override
|
||||
Shader createShader(Rect rect, { TextDirection textDirection }) {
|
||||
return new ui.Gradient.sweep(
|
||||
center.resolve(textDirection).withinRect(rect),
|
||||
colors, _impliedStops(), tileMode,
|
||||
startAngle,
|
||||
endAngle,
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns a new [SweepGradient] with its colors scaled by the given factor.
|
||||
///
|
||||
/// Since the alpha component of the Color is what is scaled, a factor
|
||||
/// of 0.0 or less results in a gradient that is fully transparent.
|
||||
@override
|
||||
SweepGradient scale(double factor) {
|
||||
return new SweepGradient(
|
||||
center: center,
|
||||
startAngle: startAngle,
|
||||
endAngle: endAngle,
|
||||
colors: colors.map<Color>((Color color) => Color.lerp(null, color, factor)).toList(),
|
||||
stops: stops,
|
||||
tileMode: tileMode,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Gradient lerpFrom(Gradient a, double t) {
|
||||
if (a == null || (a is SweepGradient && a.colors.length == colors.length)) // TODO(ianh): remove limitation
|
||||
return SweepGradient.lerp(a, this, t);
|
||||
return super.lerpFrom(a, t);
|
||||
}
|
||||
|
||||
@override
|
||||
Gradient lerpTo(Gradient b, double t) {
|
||||
if (b == null || (b is SweepGradient && b.colors.length == colors.length)) // TODO(ianh): remove limitation
|
||||
return SweepGradient.lerp(this, b, t);
|
||||
return super.lerpTo(b, t);
|
||||
}
|
||||
|
||||
/// Linearly interpolate between two [SweepGradient]s.
|
||||
///
|
||||
/// If either gradient is null, then the non-null gradient is returned with
|
||||
/// its color scaled in the same way as the [scale] function.
|
||||
///
|
||||
/// If neither gradient is null, they must have the same number of [colors].
|
||||
///
|
||||
/// The `t` argument represents a position on the timeline, with 0.0 meaning
|
||||
/// that the interpolation has not started, returning `a` (or something
|
||||
/// equivalent to `a`), 1.0 meaning that the interpolation has finished,
|
||||
/// returning `b` (or something equivalent to `b`), and values in between
|
||||
/// meaning that the interpolation is at the relevant point on the timeline
|
||||
/// between `a` and `b`. The interpolation can be extrapolated beyond 0.0 and
|
||||
/// 1.0, so negative values and values greater than 1.0 are valid (and can
|
||||
/// easily be generated by curves such as [Curves.elasticInOut]).
|
||||
///
|
||||
/// Values for `t` are usually obtained from an [Animation<double>], such as
|
||||
/// an [AnimationController].
|
||||
static SweepGradient lerp(SweepGradient a, SweepGradient b, double t) {
|
||||
assert(t != null);
|
||||
if (a == null && b == null)
|
||||
return null;
|
||||
if (a == null)
|
||||
return b.scale(t);
|
||||
if (b == null)
|
||||
return a.scale(1.0 - t);
|
||||
final _ColorsAndStops interpolated = _interpolateColorsAndStops(a.colors, a.stops, b.colors, b.stops, t);
|
||||
return new SweepGradient(
|
||||
center: AlignmentGeometry.lerp(a.center, b.center, t),
|
||||
startAngle: math.max(0.0, ui.lerpDouble(a.startAngle, b.startAngle, t)),
|
||||
endAngle: math.max(0.0, ui.lerpDouble(a.endAngle, b.endAngle, t)),
|
||||
colors: interpolated.colors,
|
||||
stops: interpolated.stops,
|
||||
tileMode: t < 0.5 ? a.tileMode : b.tileMode, // TODO(ianh): interpolate tile mode
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(dynamic other) {
|
||||
if (identical(this, other))
|
||||
return true;
|
||||
if (runtimeType != other.runtimeType)
|
||||
return false;
|
||||
final SweepGradient typedOther = other;
|
||||
if (center != typedOther.center ||
|
||||
startAngle != typedOther.startAngle ||
|
||||
endAngle != typedOther.endAngle ||
|
||||
tileMode != typedOther.tileMode ||
|
||||
colors?.length != typedOther.colors?.length ||
|
||||
stops?.length != typedOther.stops?.length)
|
||||
return false;
|
||||
if (colors != null) {
|
||||
assert(typedOther.colors != null);
|
||||
assert(colors.length == typedOther.colors.length);
|
||||
for (int i = 0; i < colors.length; i += 1) {
|
||||
if (colors[i] != typedOther.colors[i])
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (stops != null) {
|
||||
assert(typedOther.stops != null);
|
||||
assert(stops.length == typedOther.stops.length);
|
||||
for (int i = 0; i < stops.length; i += 1) {
|
||||
if (stops[i] != typedOther.stops[i])
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => hashValues(center, startAngle, endAngle, tileMode, hashList(colors), hashList(stops));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return '$runtimeType($center, $startAngle, $endAngle, $colors, $stops, $tileMode)';
|
||||
}
|
||||
}
|
||||
|
@ -233,9 +233,9 @@ class ShaderMask extends SingleChildRenderObjectWidget {
|
||||
/// The shader callback is called with the current size of the child so that
|
||||
/// it can customize the shader to the size and location of the child.
|
||||
///
|
||||
/// Typically this will use a [LinearGradient] or [RadialGradient] to create
|
||||
/// the [dart:ui.Shader], though the [dart:ui.ImageShader] class could also be
|
||||
/// used.
|
||||
/// Typically this will use a [LinearGradient], [RadialGradient], or
|
||||
/// [SweepGradient] to create the [dart:ui.Shader], though the
|
||||
/// [dart:ui.ImageShader] class could also be used.
|
||||
final ShaderCallback shaderCallback;
|
||||
|
||||
/// The [BlendMode] to use when applying the shader to the child.
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter/painting.dart';
|
||||
@ -193,6 +194,45 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
test('SweepGradient with AlignmentDirectional', () {
|
||||
expect(
|
||||
() {
|
||||
return const SweepGradient(
|
||||
center: AlignmentDirectional.topStart,
|
||||
colors: const <Color>[ const Color(0xFFFFFFFF), const Color(0xFFFFFFFF) ]
|
||||
).createShader(new Rect.fromLTWH(0.0, 0.0, 100.0, 100.0));
|
||||
},
|
||||
throwsAssertionError,
|
||||
);
|
||||
expect(
|
||||
() {
|
||||
return const SweepGradient(
|
||||
center: AlignmentDirectional.topStart,
|
||||
colors: const <Color>[ const Color(0xFFFFFFFF), const Color(0xFFFFFFFF) ]
|
||||
).createShader(new Rect.fromLTWH(0.0, 0.0, 100.0, 100.0), textDirection: TextDirection.rtl);
|
||||
},
|
||||
returnsNormally,
|
||||
);
|
||||
expect(
|
||||
() {
|
||||
return const SweepGradient(
|
||||
center: AlignmentDirectional.topStart,
|
||||
colors: const <Color>[ const Color(0xFFFFFFFF), const Color(0xFFFFFFFF) ]
|
||||
).createShader(new Rect.fromLTWH(0.0, 0.0, 100.0, 100.0), textDirection: TextDirection.ltr);
|
||||
},
|
||||
returnsNormally,
|
||||
);
|
||||
expect(
|
||||
() {
|
||||
return const SweepGradient(
|
||||
center: Alignment.topLeft,
|
||||
colors: const <Color>[ const Color(0xFFFFFFFF), const Color(0xFFFFFFFF) ]
|
||||
).createShader(new Rect.fromLTWH(0.0, 0.0, 100.0, 100.0));
|
||||
},
|
||||
returnsNormally,
|
||||
);
|
||||
});
|
||||
|
||||
test('RadialGradient lerp test', () {
|
||||
const RadialGradient testGradient1 = const RadialGradient(
|
||||
center: Alignment.topLeft,
|
||||
@ -263,6 +303,106 @@ void main() {
|
||||
));
|
||||
});
|
||||
|
||||
test('SweepGradient lerp test', () {
|
||||
const SweepGradient testGradient1 = const SweepGradient(
|
||||
center: Alignment.topLeft,
|
||||
startAngle: 0.0,
|
||||
endAngle: math.pi / 2,
|
||||
colors: const <Color>[
|
||||
const Color(0x33333333),
|
||||
const Color(0x66666666),
|
||||
],
|
||||
);
|
||||
const SweepGradient testGradient2 = const SweepGradient(
|
||||
center: Alignment.topRight,
|
||||
startAngle: math.pi / 2,
|
||||
endAngle: math.pi,
|
||||
colors: const <Color>[
|
||||
const Color(0x44444444),
|
||||
const Color(0x88888888),
|
||||
],
|
||||
);
|
||||
|
||||
final SweepGradient actual = SweepGradient.lerp(testGradient1, testGradient2, 0.5);
|
||||
expect(actual, const SweepGradient(
|
||||
center: const Alignment(0.0, -1.0),
|
||||
startAngle: math.pi / 4,
|
||||
endAngle: math.pi * 3/4,
|
||||
colors: const <Color>[
|
||||
const Color(0x3B3B3B3B),
|
||||
const Color(0x77777777),
|
||||
],
|
||||
));
|
||||
});
|
||||
|
||||
test('SweepGradient lerp test with stops', () {
|
||||
const SweepGradient testGradient1 = const SweepGradient(
|
||||
center: Alignment.topLeft,
|
||||
startAngle: 0.0,
|
||||
endAngle: math.pi / 2,
|
||||
colors: const <Color>[
|
||||
const Color(0x33333333),
|
||||
const Color(0x66666666),
|
||||
],
|
||||
stops: const <double>[
|
||||
0.0,
|
||||
0.5,
|
||||
],
|
||||
);
|
||||
const SweepGradient testGradient2 = const SweepGradient(
|
||||
center: Alignment.topRight,
|
||||
startAngle: math.pi / 2,
|
||||
endAngle: math.pi,
|
||||
colors: const <Color>[
|
||||
const Color(0x44444444),
|
||||
const Color(0x88888888),
|
||||
],
|
||||
stops: const <double>[
|
||||
0.5,
|
||||
1.0,
|
||||
],
|
||||
);
|
||||
|
||||
final SweepGradient actual = SweepGradient.lerp(testGradient1, testGradient2, 0.5);
|
||||
expect(actual, const SweepGradient(
|
||||
center: const Alignment(0.0, -1.0),
|
||||
startAngle: math.pi / 4,
|
||||
endAngle: math.pi * 3/4,
|
||||
colors: const <Color>[
|
||||
const Color(0x3B3B3B3B),
|
||||
const Color(0x77777777),
|
||||
],
|
||||
stops: const <double>[
|
||||
0.25,
|
||||
0.75,
|
||||
],
|
||||
));
|
||||
});
|
||||
|
||||
test('SweepGradient scale test)', () {
|
||||
const SweepGradient testGradient = const SweepGradient(
|
||||
center: Alignment.topLeft,
|
||||
startAngle: 0.0,
|
||||
endAngle: math.pi / 2,
|
||||
colors: const <Color>[
|
||||
const Color(0xff333333),
|
||||
const Color(0xff666666),
|
||||
],
|
||||
);
|
||||
|
||||
final SweepGradient actual = testGradient.scale(0.5);
|
||||
|
||||
expect(actual, const SweepGradient(
|
||||
center: Alignment.topLeft,
|
||||
startAngle: 0.0,
|
||||
endAngle: math.pi / 2,
|
||||
colors: const <Color>[
|
||||
const Color(0x80333333),
|
||||
const Color(0x80666666),
|
||||
],
|
||||
));
|
||||
});
|
||||
|
||||
test('Gradient lerp test (with RadialGradient)', () {
|
||||
const RadialGradient testGradient1 = const RadialGradient(
|
||||
center: Alignment.topLeft,
|
||||
@ -357,4 +497,4 @@ void main() {
|
||||
expect(() { test2a.createShader(rect); }, throwsArgumentError);
|
||||
expect(() { test2b.createShader(rect); }, throwsArgumentError);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user