Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
61a2492a
Commit
61a2492a
authored
Sep 20, 2017
by
Ian Hickson
Committed by
GitHub
Sep 20, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Factor out LinearGradient and RadialGradient (#12155)
parent
8e5ec0b1
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
422 additions
and
412 deletions
+422
-412
painting.dart
packages/flutter/lib/painting.dart
+1
-0
border.dart
packages/flutter/lib/src/painting/border.dart
+0
-3
box_painter.dart
packages/flutter/lib/src/painting/box_painter.dart
+2
-406
decoration.dart
packages/flutter/lib/src/painting/decoration.dart
+0
-3
flutter_logo.dart
packages/flutter/lib/src/painting/flutter_logo.dart
+1
-0
gradient.dart
packages/flutter/lib/src/painting/gradient.dart
+418
-0
No files found.
packages/flutter/lib/painting.dart
View file @
61a2492a
...
...
@@ -27,6 +27,7 @@ export 'src/painting/decoration.dart';
export
'src/painting/edge_insets.dart'
;
export
'src/painting/flutter_logo.dart'
;
export
'src/painting/fractional_offset.dart'
;
export
'src/painting/gradient.dart'
;
export
'src/painting/text_painter.dart'
;
export
'src/painting/text_span.dart'
;
export
'src/painting/text_style.dart'
;
...
...
packages/flutter/lib/src/painting/border.dart
View file @
61a2492a
...
...
@@ -8,11 +8,8 @@ import 'package:flutter/foundation.dart';
import
'basic_types.dart'
;
import
'border_radius.dart'
;
import
'decoration.dart'
;
import
'edge_insets.dart'
;
export
'edge_insets.dart'
show
EdgeInsets
;
/// The shape to use when rendering a [Border] or [BoxDecoration].
enum
BoxShape
{
/// An axis-aligned, 2D rectangle. May have rounded corners (described by a
...
...
packages/flutter/lib/src/painting/box_painter.dart
View file @
61a2492a
...
...
@@ -3,7 +3,7 @@
// found in the LICENSE file.
import
'dart:math'
as
math
;
import
'dart:ui'
as
ui
show
Image
,
Gradient
,
lerpDouble
;
import
'dart:ui'
as
ui
show
Image
,
lerpDouble
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/services.dart'
;
...
...
@@ -15,8 +15,7 @@ import 'box_fit.dart';
import
'decoration.dart'
;
import
'edge_insets.dart'
;
import
'fractional_offset.dart'
;
export
'edge_insets.dart'
show
EdgeInsets
;
import
'gradient.dart'
;
/// A shadow cast by a box.
///
...
...
@@ -133,409 +132,6 @@ class BoxShadow {
String
toString
()
=>
'BoxShadow(
$color
,
$offset
,
$blurRadius
,
$spreadRadius
)'
;
}
/// A 2D gradient.
///
/// This is an interface that allows [LinearGradient] and [RadialGradient]
/// classes to be used interchangeably in [BoxDecoration]s.
@immutable
abstract
class
Gradient
{
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const
Gradient
();
/// Creates a [Shader] for this gradient to fill the given rect.
Shader
createShader
(
Rect
rect
);
}
/// 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.
///
/// 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
/// expressed in fractions, so that the same gradient can be reused with varying
/// sized boxes without changing the parameters. (This contrasts with [new
/// ui.Gradient.linear], whose arguments are expressed in logical pixels.)
///
/// The [colors] are described by a list of [Color] objects. There must be at
/// least two colors. If there are more than two, a [stops] list must be
/// provided. It must have the same length as [colors], and specifies the
/// position of each color stop between 0.0 and 1.0.
///
/// The region of the canvas before [begin] and after [end] is colored according
/// to [tileMode].
///
/// Typically this class is used with [BoxDecoration], which does the painting.
/// To use a [LinearGradient] to paint on a canvas directly, see [createShader].
///
/// ## Sample code
///
/// This sample draws a picture that looks like vertical window shades by having
/// a [Container] display a [BoxDecoration] with a [LinearGradient].
///
/// ```dart
/// new Container(
/// decoration: new BoxDecoration(
/// gradient: new LinearGradient(
/// begin: FractionalOffset.topLeft,
/// end: new FractionalOffset(0.1, 0.0), // 10% of the width, so there are ten blinds.
/// colors: [const Color(0xFFFFFFEE), const Color(0xFF999999)], // whitish to gray
/// tileMode: TileMode.repeated, // repeats the gradient over the canvas
/// ),
/// ),
/// )
/// ```
///
/// See also:
///
/// * [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 [LinearGradient] in its
/// [BoxDecoration.gradient] property.
class
LinearGradient
extends
Gradient
{
/// Creates a linear graident.
///
/// The [colors] argument must not be null. If [stops] is non-null, it must
/// have the same length as [colors].
const
LinearGradient
({
this
.
begin
:
FractionalOffset
.
centerLeft
,
this
.
end
:
FractionalOffset
.
centerRight
,
@required
this
.
colors
,
this
.
stops
,
this
.
tileMode
:
TileMode
.
clamp
,
})
:
assert
(
begin
!=
null
),
assert
(
end
!=
null
),
assert
(
colors
!=
null
),
assert
(
tileMode
!=
null
);
/// The offset from coordinate (0.0,0.0) at which stop 0.0 of the
/// gradient is placed, in a coordinate space that maps the top left
/// of the paint box at (0.0,0.0) and the bottom right at (1.0,1.0).
///
/// For example, a begin offset of (0.0,0.5) is half way down the
/// left side of the box.
final
FractionalOffset
begin
;
/// The offset from coordinate (0.0,0.0) at which stop 1.0 of the
/// gradient is placed, in a coordinate space that maps the top left
/// of the paint box at (0.0,0.0) and the bottom right at (1.0,1.0).
///
/// For example, an end offset of (1.0,0.5) is half way down the
/// right side of the box.
final
FractionalOffset
end
;
/// The colors the gradient should obtain at each of the stops.
///
/// If [stops] is non-null, this list must have the same length as [stops]. If
/// [colors] has more than two colors, [stops] must be non-null.
///
/// This list must have at least two colors in it (otherwise, it's not a
/// gradient!).
final
List
<
Color
>
colors
;
/// A list of values from 0.0 to 1.0 that denote fractions of the vector from
/// start to end.
///
/// If non-null, this list must have the same length as [colors]. If
/// [colors] has more than two colors, [stops] must be non-null.
///
/// If the first value is not 0.0, then a stop with position 0.0 and a color
/// equal to the first color in [colors] is implied.
///
/// If the last value is not 1.0, then a stop with position 1.0 and a color
/// equal to the last color in [colors] is implied.
///
/// The values in the [stops] list must be in ascending order. If a value in
/// the [stops] list is less than an earlier value in the list, then its value
/// is assumed to equal the previous value.
final
List
<
double
>
stops
;
/// How this gradient should tile the plane beyond in the region before
/// [begin] and after [end].
///
/// For details, see [TileMode].
///
/// 
/// 
/// 
final
TileMode
tileMode
;
@override
Shader
createShader
(
Rect
rect
)
{
return
new
ui
.
Gradient
.
linear
(
begin
.
withinRect
(
rect
),
end
.
withinRect
(
rect
),
colors
,
stops
,
tileMode
,
);
}
/// Returns a new [LinearGradient] with its properties scaled by the given
/// factor.
LinearGradient
scale
(
double
factor
)
{
return
new
LinearGradient
(
begin:
begin
,
end:
end
,
colors:
colors
.
map
<
Color
>((
Color
color
)
=>
Color
.
lerp
(
null
,
color
,
factor
)).
toList
(),
stops:
stops
,
tileMode:
tileMode
,
);
}
/// Linearly interpolate between two [LinearGradient]s.
///
/// If either gradient is null, this function linearly interpolates from a
/// a gradient that matches the other gradient in [begin], [end], [stops] and
/// [tileMode] and with the same [colors] but transparent.
///
/// If neither gradient is null, they must have the same number of [colors].
static
LinearGradient
lerp
(
LinearGradient
a
,
LinearGradient
b
,
double
t
)
{
if
(
a
==
null
&&
b
==
null
)
return
null
;
if
(
a
==
null
)
return
b
.
scale
(
t
);
if
(
b
==
null
)
return
a
.
scale
(
1.0
-
t
);
// Interpolation is only possible when the lengths of colors and stops are
// the same or stops is null for one.
// TODO(xster): lerp unsimilar LinearGradients in the future by scaling
// lists of LinearGradients.
assert
(
a
.
colors
.
length
==
b
.
colors
.
length
);
assert
(
a
.
stops
==
null
||
b
.
stops
==
null
||
a
.
stops
.
length
==
b
.
stops
.
length
);
final
List
<
Color
>
interpolatedColors
=
<
Color
>[];
for
(
int
i
=
0
;
i
<
a
.
colors
.
length
;
i
+=
1
)
interpolatedColors
.
add
(
Color
.
lerp
(
a
.
colors
[
i
],
b
.
colors
[
i
],
t
));
List
<
double
>
interpolatedStops
;
if
(
a
.
stops
!=
null
&&
b
.
stops
!=
null
)
{
for
(
int
i
=
0
;
i
<
a
.
stops
.
length
;
i
+=
1
)
interpolatedStops
.
add
(
ui
.
lerpDouble
(
a
.
stops
[
i
],
b
.
stops
[
i
],
t
));
}
else
{
interpolatedStops
=
a
.
stops
??
b
.
stops
;
}
return
new
LinearGradient
(
begin:
FractionalOffset
.
lerp
(
a
.
begin
,
b
.
begin
,
t
),
end:
FractionalOffset
.
lerp
(
a
.
end
,
b
.
end
,
t
),
colors:
interpolatedColors
,
stops:
interpolatedStops
,
tileMode:
t
<
0.5
?
a
.
tileMode
:
b
.
tileMode
,
);
}
@override
bool
operator
==(
dynamic
other
)
{
if
(
identical
(
this
,
other
))
return
true
;
if
(
runtimeType
!=
other
.
runtimeType
)
return
false
;
final
LinearGradient
typedOther
=
other
;
if
(
begin
!=
typedOther
.
begin
||
end
!=
typedOther
.
end
||
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
(
begin
,
end
,
tileMode
,
hashList
(
colors
),
hashList
(
stops
));
@override
String
toString
()
{
return
'LinearGradient(
$begin
,
$end
,
$colors
,
$stops
,
$tileMode
)'
;
}
}
/// 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.
///
/// 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
/// lengths are expressed in fractions, so that the same gradient can be reused
/// with varying sized boxes without changing the parameters. (This contrasts
/// with [new ui.Gradient.radial], whose arguments are expressed in logical
/// pixels.)
///
/// The [colors] are described by a list of [Color] objects. There must be at
/// least two colors. If there are more than two, a [stops] list must be
/// provided. It must have the same length as [colors], and specifies the
/// position of each color stop between 0.0 and 1.0.
///
/// The region of the canvas beyond [radius] from the [center] is colored
/// according to [tileMode].
///
/// Typically this class is used with [BoxDecoration], which does the painting.
/// To use a [RadialGradient] to paint on a canvas directly, see [createShader].
///
/// ## Sample code
///
/// This function draws a gradient that looks like a sun in a blue sky.
///
/// ```dart
/// void paintSky(Canvas canvas, Rect rect) {
/// var gradient = new RadialGradient(
/// center: const FractionalOffset(0.7, 0.2), // near the top right
/// radius: 0.2,
/// colors: [
/// const Color(0xFFFFFF00), // yellow sun
/// const Color(0xFF0099FF), // blue sky
/// ],
/// stops: [0.4, 1.0],
/// );
/// // rect is the area we are painting over
/// var paint = new Paint()
/// ..shader = gradient.createShader(rect);
/// canvas.drawRect(rect, paint);
/// }
/// ```
///
/// See also:
///
/// * [LinearGradient], which displays a gradient in parallel lines, and has an
/// example which shows a different way to use [Gradient] objects.
/// * [BoxDecoration], which can take a [RadialGradient] in its
/// [BoxDecoration.gradient] property.
/// * [CustomPainter], which shows how to use the above sample code in a custom
/// painter.
class
RadialGradient
extends
Gradient
{
/// Creates a radial gradient.
///
/// The [colors] argument must not be null. If [stops] is non-null, it must
/// have the same length as [colors].
const
RadialGradient
({
this
.
center
:
FractionalOffset
.
center
,
this
.
radius
:
0.5
,
@required
this
.
colors
,
this
.
stops
,
this
.
tileMode
:
TileMode
.
clamp
,
})
:
assert
(
center
!=
null
),
assert
(
radius
!=
null
),
assert
(
colors
!=
null
),
assert
(
tileMode
!=
null
);
/// The center of the gradient, as an offset into the unit square
/// describing the gradient which will be mapped onto the paint box.
///
/// For example, an offset of (0.5,0.5) will place the radial
/// gradient in the center of the box.
final
FractionalOffset
center
;
/// The radius of the gradient, as a fraction of the shortest side
/// of the paint box.
///
/// For example, if a radial gradient is painted on a box that is
/// 100.0 pixels wide and 200.0 pixels tall, then a radius of 1.0
/// will place the 1.0 stop at 100.0 pixels from the [center].
final
double
radius
;
/// The colors the gradient should obtain at each of the stops.
///
/// If [stops] is non-null, this list must have the same length as [stops]. If
/// [colors] has more than two colors, [stops] must be non-null.
///
/// This list must have at least two colors in it (otherwise, it's not a
/// gradient!).
final
List
<
Color
>
colors
;
/// A list of values from 0.0 to 1.0 that denote concentric rings.
///
/// The rings are centered at [center] and have a radius equal to the value of
/// the stop times [radius].
///
/// If non-null, this list must have the same length as [colors]. If
/// [colors] has more than two colors, [stops] must be non-null.
///
/// If the first value is not 0.0, then a stop with position 0.0 and a color
/// equal to the first color in [colors] is implied.
///
/// If the last value is not 1.0, then a stop with position 1.0 and a color
/// equal to the last color in [colors] is implied.
///
/// The values in the [stops] list must be in ascending order. If a value in
/// the [stops] list is less than an earlier value in the list, then its value
/// is assumed to equal the previous value.
final
List
<
double
>
stops
;
/// How this gradient should tile the plane beyond the outer ring at [radius]
/// pixels from the [center].
///
/// For details, see [TileMode].
///
/// 
/// 
/// 
final
TileMode
tileMode
;
@override
Shader
createShader
(
Rect
rect
)
{
return
new
ui
.
Gradient
.
radial
(
center
.
withinRect
(
rect
),
radius
*
rect
.
shortestSide
,
colors
,
stops
,
tileMode
);
}
@override
bool
operator
==(
dynamic
other
)
{
if
(
identical
(
this
,
other
))
return
true
;
if
(
runtimeType
!=
other
.
runtimeType
)
return
false
;
final
RadialGradient
typedOther
=
other
;
if
(
center
!=
typedOther
.
center
||
radius
!=
typedOther
.
radius
||
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
,
radius
,
tileMode
,
hashList
(
colors
),
hashList
(
stops
));
@override
String
toString
()
{
return
'RadialGradient(
$center
,
$radius
,
$colors
,
$stops
,
$tileMode
)'
;
}
}
/// How to paint any portions of a box not covered by an image.
enum
ImageRepeat
{
/// Repeat the image in both the x and y directions until the box is filled.
...
...
packages/flutter/lib/src/painting/decoration.dart
View file @
61a2492a
...
...
@@ -10,9 +10,6 @@ import 'edge_insets.dart';
export
'package:flutter/services.dart'
show
ImageConfiguration
;
export
'basic_types.dart'
show
Offset
,
Size
;
export
'edge_insets.dart'
show
EdgeInsets
;
// This group of classes is intended for painting in cartesian coordinates.
/// A description of a box decoration (a decoration applied to a [Rect]).
...
...
packages/flutter/lib/src/painting/flutter_logo.dart
View file @
61a2492a
...
...
@@ -12,6 +12,7 @@ import 'package:flutter/foundation.dart';
import
'basic_types.dart'
;
import
'box_fit.dart'
;
import
'decoration.dart'
;
import
'edge_insets.dart'
;
import
'fractional_offset.dart'
;
import
'text_painter.dart'
;
import
'text_span.dart'
;
...
...
packages/flutter/lib/src/painting/gradient.dart
0 → 100644
View file @
61a2492a
// Copyright 2015 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:ui'
as
ui
show
Gradient
,
lerpDouble
;
import
'package:flutter/foundation.dart'
;
import
'basic_types.dart'
;
import
'fractional_offset.dart'
;
/// A 2D gradient.
///
/// This is an interface that allows [LinearGradient] and [RadialGradient]
/// classes to be used interchangeably in [BoxDecoration]s.
///
/// See also:
///
/// * [dart:ui.Gradient], the class in the [dart:ui] library that is
/// encapsulated by this class and its subclasses.
@immutable
abstract
class
Gradient
{
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const
Gradient
();
/// Creates a [Shader] for this gradient to fill the given rect.
Shader
createShader
(
Rect
rect
);
}
/// 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.
///
/// 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
/// expressed in fractions, so that the same gradient can be reused with varying
/// sized boxes without changing the parameters. (This contrasts with [new
/// ui.Gradient.linear], whose arguments are expressed in logical pixels.)
///
/// The [colors] are described by a list of [Color] objects. There must be at
/// least two colors. If there are more than two, a [stops] list must be
/// provided. It must have the same length as [colors], and specifies the
/// position of each color stop between 0.0 and 1.0.
///
/// The region of the canvas before [begin] and after [end] is colored according
/// to [tileMode].
///
/// Typically this class is used with [BoxDecoration], which does the painting.
/// To use a [LinearGradient] to paint on a canvas directly, see [createShader].
///
/// ## Sample code
///
/// This sample draws a picture that looks like vertical window shades by having
/// a [Container] display a [BoxDecoration] with a [LinearGradient].
///
/// ```dart
/// new Container(
/// decoration: new BoxDecoration(
/// gradient: new LinearGradient(
/// begin: FractionalOffset.topLeft,
/// end: new FractionalOffset(0.1, 0.0), // 10% of the width, so there are ten blinds.
/// colors: [const Color(0xFFFFFFEE), const Color(0xFF999999)], // whitish to gray
/// tileMode: TileMode.repeated, // repeats the gradient over the canvas
/// ),
/// ),
/// )
/// ```
///
/// See also:
///
/// * [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 [LinearGradient] in its
/// [BoxDecoration.gradient] property.
class
LinearGradient
extends
Gradient
{
/// Creates a linear graident.
///
/// The [colors] argument must not be null. If [stops] is non-null, it must
/// have the same length as [colors].
const
LinearGradient
({
this
.
begin
:
FractionalOffset
.
centerLeft
,
this
.
end
:
FractionalOffset
.
centerRight
,
@required
this
.
colors
,
this
.
stops
,
this
.
tileMode
:
TileMode
.
clamp
,
})
:
assert
(
begin
!=
null
),
assert
(
end
!=
null
),
assert
(
colors
!=
null
),
assert
(
tileMode
!=
null
);
/// The offset from coordinate (0.0,0.0) at which stop 0.0 of the
/// gradient is placed, in a coordinate space that maps the top left
/// of the paint box at (0.0,0.0) and the bottom right at (1.0,1.0).
///
/// For example, a begin offset of (0.0,0.5) is half way down the
/// left side of the box.
final
FractionalOffset
begin
;
/// The offset from coordinate (0.0,0.0) at which stop 1.0 of the
/// gradient is placed, in a coordinate space that maps the top left
/// of the paint box at (0.0,0.0) and the bottom right at (1.0,1.0).
///
/// For example, an end offset of (1.0,0.5) is half way down the
/// right side of the box.
final
FractionalOffset
end
;
/// The colors the gradient should obtain at each of the stops.
///
/// If [stops] is non-null, this list must have the same length as [stops]. If
/// [colors] has more than two colors, [stops] must be non-null.
///
/// This list must have at least two colors in it (otherwise, it's not a
/// gradient!).
final
List
<
Color
>
colors
;
/// A list of values from 0.0 to 1.0 that denote fractions of the vector from
/// start to end.
///
/// If non-null, this list must have the same length as [colors]. If
/// [colors] has more than two colors, [stops] must be non-null.
///
/// If the first value is not 0.0, then a stop with position 0.0 and a color
/// equal to the first color in [colors] is implied.
///
/// If the last value is not 1.0, then a stop with position 1.0 and a color
/// equal to the last color in [colors] is implied.
///
/// The values in the [stops] list must be in ascending order. If a value in
/// the [stops] list is less than an earlier value in the list, then its value
/// is assumed to equal the previous value.
final
List
<
double
>
stops
;
/// How this gradient should tile the plane beyond in the region before
/// [begin] and after [end].
///
/// For details, see [TileMode].
///
/// 
/// 
/// 
final
TileMode
tileMode
;
@override
Shader
createShader
(
Rect
rect
)
{
return
new
ui
.
Gradient
.
linear
(
begin
.
withinRect
(
rect
),
end
.
withinRect
(
rect
),
colors
,
stops
,
tileMode
,
);
}
/// Returns a new [LinearGradient] with its properties scaled by the given
/// factor.
LinearGradient
scale
(
double
factor
)
{
return
new
LinearGradient
(
begin:
begin
,
end:
end
,
colors:
colors
.
map
<
Color
>((
Color
color
)
=>
Color
.
lerp
(
null
,
color
,
factor
)).
toList
(),
stops:
stops
,
tileMode:
tileMode
,
);
}
/// Linearly interpolate between two [LinearGradient]s.
///
/// If either gradient is null, this function linearly interpolates from a
/// a gradient that matches the other gradient in [begin], [end], [stops] and
/// [tileMode] and with the same [colors] but transparent.
///
/// If neither gradient is null, they must have the same number of [colors].
static
LinearGradient
lerp
(
LinearGradient
a
,
LinearGradient
b
,
double
t
)
{
if
(
a
==
null
&&
b
==
null
)
return
null
;
if
(
a
==
null
)
return
b
.
scale
(
t
);
if
(
b
==
null
)
return
a
.
scale
(
1.0
-
t
);
// Interpolation is only possible when the lengths of colors and stops are
// the same or stops is null for one.
// TODO(xster): lerp unsimilar LinearGradients in the future by scaling
// lists of LinearGradients.
assert
(
a
.
colors
.
length
==
b
.
colors
.
length
);
assert
(
a
.
stops
==
null
||
b
.
stops
==
null
||
a
.
stops
.
length
==
b
.
stops
.
length
);
final
List
<
Color
>
interpolatedColors
=
<
Color
>[];
for
(
int
i
=
0
;
i
<
a
.
colors
.
length
;
i
+=
1
)
interpolatedColors
.
add
(
Color
.
lerp
(
a
.
colors
[
i
],
b
.
colors
[
i
],
t
));
List
<
double
>
interpolatedStops
;
if
(
a
.
stops
!=
null
&&
b
.
stops
!=
null
)
{
for
(
int
i
=
0
;
i
<
a
.
stops
.
length
;
i
+=
1
)
interpolatedStops
.
add
(
ui
.
lerpDouble
(
a
.
stops
[
i
],
b
.
stops
[
i
],
t
));
}
else
{
interpolatedStops
=
a
.
stops
??
b
.
stops
;
}
return
new
LinearGradient
(
begin:
FractionalOffset
.
lerp
(
a
.
begin
,
b
.
begin
,
t
),
end:
FractionalOffset
.
lerp
(
a
.
end
,
b
.
end
,
t
),
colors:
interpolatedColors
,
stops:
interpolatedStops
,
tileMode:
t
<
0.5
?
a
.
tileMode
:
b
.
tileMode
,
);
}
@override
bool
operator
==(
dynamic
other
)
{
if
(
identical
(
this
,
other
))
return
true
;
if
(
runtimeType
!=
other
.
runtimeType
)
return
false
;
final
LinearGradient
typedOther
=
other
;
if
(
begin
!=
typedOther
.
begin
||
end
!=
typedOther
.
end
||
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
(
begin
,
end
,
tileMode
,
hashList
(
colors
),
hashList
(
stops
));
@override
String
toString
()
{
return
'LinearGradient(
$begin
,
$end
,
$colors
,
$stops
,
$tileMode
)'
;
}
}
/// 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.
///
/// 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
/// lengths are expressed in fractions, so that the same gradient can be reused
/// with varying sized boxes without changing the parameters. (This contrasts
/// with [new ui.Gradient.radial], whose arguments are expressed in logical
/// pixels.)
///
/// The [colors] are described by a list of [Color] objects. There must be at
/// least two colors. If there are more than two, a [stops] list must be
/// provided. It must have the same length as [colors], and specifies the
/// position of each color stop between 0.0 and 1.0.
///
/// The region of the canvas beyond [radius] from the [center] is colored
/// according to [tileMode].
///
/// Typically this class is used with [BoxDecoration], which does the painting.
/// To use a [RadialGradient] to paint on a canvas directly, see [createShader].
///
/// ## Sample code
///
/// This function draws a gradient that looks like a sun in a blue sky.
///
/// ```dart
/// void paintSky(Canvas canvas, Rect rect) {
/// var gradient = new RadialGradient(
/// center: const FractionalOffset(0.7, 0.2), // near the top right
/// radius: 0.2,
/// colors: [
/// const Color(0xFFFFFF00), // yellow sun
/// const Color(0xFF0099FF), // blue sky
/// ],
/// stops: [0.4, 1.0],
/// );
/// // rect is the area we are painting over
/// var paint = new Paint()
/// ..shader = gradient.createShader(rect);
/// canvas.drawRect(rect, paint);
/// }
/// ```
///
/// See also:
///
/// * [LinearGradient], which displays a gradient in parallel lines, and has an
/// example which shows a different way to use [Gradient] objects.
/// * [BoxDecoration], which can take a [RadialGradient] in its
/// [BoxDecoration.gradient] property.
/// * [CustomPainter], which shows how to use the above sample code in a custom
/// painter.
class
RadialGradient
extends
Gradient
{
/// Creates a radial gradient.
///
/// The [colors] argument must not be null. If [stops] is non-null, it must
/// have the same length as [colors].
const
RadialGradient
({
this
.
center
:
FractionalOffset
.
center
,
this
.
radius
:
0.5
,
@required
this
.
colors
,
this
.
stops
,
this
.
tileMode
:
TileMode
.
clamp
,
})
:
assert
(
center
!=
null
),
assert
(
radius
!=
null
),
assert
(
colors
!=
null
),
assert
(
tileMode
!=
null
);
/// The center of the gradient, as an offset into the unit square
/// describing the gradient which will be mapped onto the paint box.
///
/// For example, an offset of (0.5,0.5) will place the radial
/// gradient in the center of the box.
final
FractionalOffset
center
;
/// The radius of the gradient, as a fraction of the shortest side
/// of the paint box.
///
/// For example, if a radial gradient is painted on a box that is
/// 100.0 pixels wide and 200.0 pixels tall, then a radius of 1.0
/// will place the 1.0 stop at 100.0 pixels from the [center].
final
double
radius
;
/// The colors the gradient should obtain at each of the stops.
///
/// If [stops] is non-null, this list must have the same length as [stops]. If
/// [colors] has more than two colors, [stops] must be non-null.
///
/// This list must have at least two colors in it (otherwise, it's not a
/// gradient!).
final
List
<
Color
>
colors
;
/// A list of values from 0.0 to 1.0 that denote concentric rings.
///
/// The rings are centered at [center] and have a radius equal to the value of
/// the stop times [radius].
///
/// If non-null, this list must have the same length as [colors]. If
/// [colors] has more than two colors, [stops] must be non-null.
///
/// If the first value is not 0.0, then a stop with position 0.0 and a color
/// equal to the first color in [colors] is implied.
///
/// If the last value is not 1.0, then a stop with position 1.0 and a color
/// equal to the last color in [colors] is implied.
///
/// The values in the [stops] list must be in ascending order. If a value in
/// the [stops] list is less than an earlier value in the list, then its value
/// is assumed to equal the previous value.
final
List
<
double
>
stops
;
/// How this gradient should tile the plane beyond the outer ring at [radius]
/// pixels from the [center].
///
/// For details, see [TileMode].
///
/// 
/// 
/// 
final
TileMode
tileMode
;
@override
Shader
createShader
(
Rect
rect
)
{
return
new
ui
.
Gradient
.
radial
(
center
.
withinRect
(
rect
),
radius
*
rect
.
shortestSide
,
colors
,
stops
,
tileMode
);
}
@override
bool
operator
==(
dynamic
other
)
{
if
(
identical
(
this
,
other
))
return
true
;
if
(
runtimeType
!=
other
.
runtimeType
)
return
false
;
final
RadialGradient
typedOther
=
other
;
if
(
center
!=
typedOther
.
center
||
radius
!=
typedOther
.
radius
||
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
,
radius
,
tileMode
,
hashList
(
colors
),
hashList
(
stops
));
@override
String
toString
()
{
return
'RadialGradient(
$center
,
$radius
,
$colors
,
$stops
,
$tileMode
)'
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment