mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Convert LinearGradient and RadialGradient to fractional units
Makes it easier to use without a SizeObserver
This commit is contained in:
parent
f7a9fc11a1
commit
cb5017d17d
@ -29,12 +29,16 @@ class _GesturePainter extends CustomPainter {
|
|||||||
Point center = (size.center(Point.origin).toOffset() * zoom + offset).toPoint();
|
Point center = (size.center(Point.origin).toOffset() * zoom + offset).toPoint();
|
||||||
double radius = size.width / 2.0 * zoom;
|
double radius = size.width / 2.0 * zoom;
|
||||||
Gradient gradient = new RadialGradient(
|
Gradient gradient = new RadialGradient(
|
||||||
center: center, radius: radius,
|
|
||||||
colors: forward ? <Color>[swatch[50], swatch[900]]
|
colors: forward ? <Color>[swatch[50], swatch[900]]
|
||||||
: <Color>[swatch[900], swatch[50]]
|
: <Color>[swatch[900], swatch[50]]
|
||||||
);
|
);
|
||||||
Paint paint = new Paint()
|
Paint paint = new Paint()
|
||||||
..shader = gradient.createShader();
|
..shader = gradient.createShader(new Rect.fromLTWH(
|
||||||
|
center.x - radius,
|
||||||
|
center.y - radius,
|
||||||
|
radius * 2.0,
|
||||||
|
radius * 2.0
|
||||||
|
));
|
||||||
canvas.drawCircle(center, radius, paint);
|
canvas.drawCircle(center, radius, paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,14 +276,15 @@ class GradientNode extends NodeWithSize {
|
|||||||
void paint(Canvas canvas) {
|
void paint(Canvas canvas) {
|
||||||
applyTransformForPivot(canvas);
|
applyTransformForPivot(canvas);
|
||||||
|
|
||||||
|
Rect rect = Point.origin & size;
|
||||||
Paint gradientPaint = new Paint()..shader = new LinearGradient(
|
Paint gradientPaint = new Paint()..shader = new LinearGradient(
|
||||||
begin: Point.origin,
|
begin: const Offset(0.0, 0.0),
|
||||||
end: new Point(0.0, size.height),
|
end: const Offset(0.0, 1.0),
|
||||||
colors: <Color>[colorTop, colorBottom],
|
colors: <Color>[colorTop, colorBottom],
|
||||||
stops: <double>[0.0, 1.0]
|
stops: <double>[0.0, 1.0]
|
||||||
).createShader();
|
).createShader(rect);
|
||||||
|
|
||||||
canvas.drawRect(new Rect.fromLTWH(0.0, 0.0, size.width, size.height), gradientPaint);
|
canvas.drawRect(rect, gradientPaint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,27 +235,43 @@ class BoxShadow {
|
|||||||
String toString() => 'BoxShadow($color, $offset, $blurRadius, $spreadRadius)';
|
String toString() => 'BoxShadow($color, $offset, $blurRadius, $spreadRadius)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(ianh): We should probably expose something that does this on Rect.
|
||||||
|
// https://github.com/flutter/flutter/issues/2318
|
||||||
|
Point _offsetToPoint(Offset offset, Rect rect) {
|
||||||
|
return new Point(rect.left + offset.dx * rect.width, rect.top + offset.dy * rect.height);
|
||||||
|
}
|
||||||
|
|
||||||
/// A 2D gradient.
|
/// A 2D gradient.
|
||||||
abstract class Gradient {
|
abstract class Gradient {
|
||||||
const Gradient();
|
const Gradient();
|
||||||
Shader createShader();
|
Shader createShader(Rect rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A 2D linear gradient.
|
/// A 2D linear gradient.
|
||||||
class LinearGradient extends Gradient {
|
class LinearGradient extends Gradient {
|
||||||
const LinearGradient({
|
const LinearGradient({
|
||||||
this.begin,
|
this.begin: const Offset(0.0, 0.5),
|
||||||
this.end,
|
this.end: const Offset(1.0, 0.5),
|
||||||
this.colors,
|
this.colors,
|
||||||
this.stops,
|
this.stops,
|
||||||
this.tileMode: TileMode.clamp
|
this.tileMode: TileMode.clamp
|
||||||
});
|
});
|
||||||
|
|
||||||
/// The point at which stop 0.0 of the gradient is placed.
|
/// The offset from coordinate (0.0,0.0) at which stop 0.0 of the
|
||||||
final Point begin;
|
/// 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 Offset begin;
|
||||||
|
|
||||||
/// The point at which stop 1.0 of the gradient is placed.
|
/// The offset from coordinate (0.0,0.0) at which stop 1.0 of the
|
||||||
final Point end;
|
/// 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 Offset end;
|
||||||
|
|
||||||
/// The colors the gradient should obtain at each of the stops.
|
/// The colors the gradient should obtain at each of the stops.
|
||||||
///
|
///
|
||||||
@ -271,8 +287,11 @@ class LinearGradient extends Gradient {
|
|||||||
/// How this gradient should tile the plane.
|
/// How this gradient should tile the plane.
|
||||||
final TileMode tileMode;
|
final TileMode tileMode;
|
||||||
|
|
||||||
Shader createShader() {
|
Shader createShader(Rect rect) {
|
||||||
return new ui.Gradient.linear(<Point>[begin, end], this.colors, this.stops, this.tileMode);
|
return new ui.Gradient.linear(
|
||||||
|
<Point>[_offsetToPoint(begin, rect), _offsetToPoint(end, rect)],
|
||||||
|
colors, stops, tileMode
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator ==(dynamic other) {
|
bool operator ==(dynamic other) {
|
||||||
@ -316,17 +335,26 @@ class LinearGradient extends Gradient {
|
|||||||
/// A 2D radial gradient.
|
/// A 2D radial gradient.
|
||||||
class RadialGradient extends Gradient {
|
class RadialGradient extends Gradient {
|
||||||
const RadialGradient({
|
const RadialGradient({
|
||||||
this.center,
|
this.center: const Offset(0.5, 0.5),
|
||||||
this.radius,
|
this.radius: 0.5,
|
||||||
this.colors,
|
this.colors,
|
||||||
this.stops,
|
this.stops,
|
||||||
this.tileMode: TileMode.clamp
|
this.tileMode: TileMode.clamp
|
||||||
});
|
});
|
||||||
|
|
||||||
/// The center of the gradient.
|
/// The center of the gradient, as an offset into the unit square
|
||||||
final Point center;
|
/// 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 Offset center;
|
||||||
|
|
||||||
/// The radius at which stop 1.0 is placed.
|
/// 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;
|
final double radius;
|
||||||
|
|
||||||
/// The colors the gradient should obtain at each of the stops.
|
/// The colors the gradient should obtain at each of the stops.
|
||||||
@ -345,8 +373,12 @@ class RadialGradient extends Gradient {
|
|||||||
/// How this gradient should tile the plane.
|
/// How this gradient should tile the plane.
|
||||||
final TileMode tileMode;
|
final TileMode tileMode;
|
||||||
|
|
||||||
Shader createShader() {
|
Shader createShader(Rect rect) {
|
||||||
return new ui.Gradient.radial(center, radius, colors, stops, tileMode);
|
return new ui.Gradient.radial(
|
||||||
|
_offsetToPoint(center, rect),
|
||||||
|
radius * rect.shortestSide,
|
||||||
|
colors, stops, tileMode
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator ==(dynamic other) {
|
bool operator ==(dynamic other) {
|
||||||
@ -903,15 +935,23 @@ class _BoxDecorationPainter extends BoxPainter {
|
|||||||
final BoxDecoration _decoration;
|
final BoxDecoration _decoration;
|
||||||
|
|
||||||
Paint _cachedBackgroundPaint;
|
Paint _cachedBackgroundPaint;
|
||||||
Paint get _backgroundPaint {
|
Rect _rectForCachedBackgroundPaint;
|
||||||
if (_cachedBackgroundPaint == null) {
|
Paint _getBackgroundPaint(Rect rect) {
|
||||||
|
assert(rect != null);
|
||||||
|
if (_cachedBackgroundPaint == null ||
|
||||||
|
(_decoration.gradient == null && _rectForCachedBackgroundPaint != null) ||
|
||||||
|
(_decoration.gradient != null && _rectForCachedBackgroundPaint != rect)) {
|
||||||
Paint paint = new Paint();
|
Paint paint = new Paint();
|
||||||
|
|
||||||
if (_decoration.backgroundColor != null)
|
if (_decoration.backgroundColor != null)
|
||||||
paint.color = _decoration.backgroundColor;
|
paint.color = _decoration.backgroundColor;
|
||||||
|
|
||||||
if (_decoration.gradient != null)
|
if (_decoration.gradient != null) {
|
||||||
paint.shader = _decoration.gradient.createShader();
|
paint.shader = _decoration.gradient.createShader(rect);
|
||||||
|
_rectForCachedBackgroundPaint = rect;
|
||||||
|
} else {
|
||||||
|
_rectForCachedBackgroundPaint = null;
|
||||||
|
}
|
||||||
|
|
||||||
_cachedBackgroundPaint = paint;
|
_cachedBackgroundPaint = paint;
|
||||||
}
|
}
|
||||||
@ -971,7 +1011,7 @@ class _BoxDecorationPainter extends BoxPainter {
|
|||||||
|
|
||||||
void _paintBackgroundColor(Canvas canvas, Rect rect) {
|
void _paintBackgroundColor(Canvas canvas, Rect rect) {
|
||||||
if (_decoration.backgroundColor != null || _decoration.gradient != null)
|
if (_decoration.backgroundColor != null || _decoration.gradient != null)
|
||||||
_paintBox(canvas, rect, _backgroundPaint);
|
_paintBox(canvas, rect, _getBackgroundPaint(rect));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _paintBackgroundImage(Canvas canvas, Rect rect) {
|
void _paintBackgroundImage(Canvas canvas, Rect rect) {
|
||||||
|
@ -14,7 +14,7 @@ void main() {
|
|||||||
decoration: new BoxDecoration(
|
decoration: new BoxDecoration(
|
||||||
backgroundColor: const Color(0xFF00FF00),
|
backgroundColor: const Color(0xFF00FF00),
|
||||||
gradient: new RadialGradient(
|
gradient: new RadialGradient(
|
||||||
center: Point.origin, radius: 500.0,
|
center: Offset.zero, radius: 1.8,
|
||||||
colors: <Color>[Colors.yellow[500], Colors.blue[500]]),
|
colors: <Color>[Colors.yellow[500], Colors.blue[500]]),
|
||||||
boxShadow: elevationToShadow[3])
|
boxShadow: elevationToShadow[3])
|
||||||
);
|
);
|
||||||
|
@ -10,12 +10,12 @@ import 'package:test/test.dart';
|
|||||||
|
|
||||||
Shader createShader(Rect bounds) {
|
Shader createShader(Rect bounds) {
|
||||||
return new LinearGradient(
|
return new LinearGradient(
|
||||||
begin: bounds.topLeft,
|
begin: const Offset(0.0, 0.0),
|
||||||
end: bounds.bottomLeft,
|
end: const Offset(0.0, 1.0),
|
||||||
colors: <Color>[const Color(0x00FFFFFF), const Color(0xFFFFFFFF)],
|
colors: <Color>[const Color(0x00FFFFFF), const Color(0xFFFFFFFF)],
|
||||||
stops: <double>[0.1, 0.35]
|
stops: <double>[0.1, 0.35]
|
||||||
)
|
)
|
||||||
.createShader();
|
.createShader(bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user