Commit b314a7d9 authored by Viktor Lidholt's avatar Viktor Lidholt

Adds NineSliceSprite and optimizes gallery front page (#3485)

* Adds NineSliceSprite and optimizes gallery front page
parent 03f92106
...@@ -6,7 +6,7 @@ dependencies: ...@@ -6,7 +6,7 @@ dependencies:
path: ../../../packages/flutter path: ../../../packages/flutter
flutter_driver: flutter_driver:
path: ../../../packages/flutter_driver path: ../../../packages/flutter_driver
flutter_gallery_assets: '0.0.15' flutter_gallery_assets: '0.0.16'
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
......
...@@ -37,4 +37,5 @@ assets: ...@@ -37,4 +37,5 @@ assets:
- packages/flutter_gallery_assets/landscape_9.jpg - packages/flutter_gallery_assets/landscape_9.jpg
- packages/flutter_gallery_assets/landscape_10.jpg - packages/flutter_gallery_assets/landscape_10.jpg
- packages/flutter_gallery_assets/landscape_11.jpg - packages/flutter_gallery_assets/landscape_11.jpg
- packages/flutter_gallery_assets/shadow.png
- lib/gallery/example_code.dart - lib/gallery/example_code.dart
...@@ -22,6 +22,7 @@ class _GalleryHeaderState extends State<GalleryHeader> { ...@@ -22,6 +22,7 @@ class _GalleryHeaderState extends State<GalleryHeader> {
_images = new ImageMap(bundle); _images = new ImageMap(bundle);
await _images.load(<String>[ await _images.load(<String>[
'packages/flutter_gallery_assets/grain.png', 'packages/flutter_gallery_assets/grain.png',
'packages/flutter_gallery_assets/shadow.png',
]); ]);
} }
...@@ -52,6 +53,7 @@ class _FlutterHeaderNode extends NodeWithSize { ...@@ -52,6 +53,7 @@ class _FlutterHeaderNode extends NodeWithSize {
clippingLayer.addChild(new _BackgroundBox()); clippingLayer.addChild(new _BackgroundBox());
paperAnimation = new _PaperAnimation(_images);
paperAnimation.position = _kCenterPoint; paperAnimation.position = _kCenterPoint;
clippingLayer.addChild(paperAnimation); clippingLayer.addChild(paperAnimation);
...@@ -64,7 +66,7 @@ class _FlutterHeaderNode extends NodeWithSize { ...@@ -64,7 +66,7 @@ class _FlutterHeaderNode extends NodeWithSize {
final ImageMap _images; final ImageMap _images;
final Layer clippingLayer = new Layer(); final Layer clippingLayer = new Layer();
final _PaperAnimation paperAnimation = new _PaperAnimation(); _PaperAnimation paperAnimation;
@override @override
void spriteBoxPerformedLayout() { void spriteBoxPerformedLayout() {
...@@ -108,11 +110,11 @@ final List<_PaperConfig> _kPaperConfigs = <_PaperConfig>[ ...@@ -108,11 +110,11 @@ final List<_PaperConfig> _kPaperConfigs = <_PaperConfig>[
]; ];
class _PaperAnimation extends Node { class _PaperAnimation extends Node {
_PaperAnimation() { _PaperAnimation(ImageMap images) {
for (_PaperConfig config in _kPaperConfigs) { for (_PaperConfig config in _kPaperConfigs) {
final _PaperSheet sheet = new _PaperSheet(config); final _PaperSheet sheet = new _PaperSheet(config);
final _PaperSheetShadow shadow = new _PaperSheetShadow(config); final _PaperSheetShadow shadow = new _PaperSheetShadow(config, images);
addChild(shadow); addChild(shadow);
addChild(sheet); addChild(sheet);
...@@ -120,7 +122,7 @@ class _PaperAnimation extends Node { ...@@ -120,7 +122,7 @@ class _PaperAnimation extends Node {
shadow.constraints = <Constraint>[ shadow.constraints = <Constraint>[
new ConstraintRotationToNodeRotation(sheet), new ConstraintRotationToNodeRotation(sheet),
new ConstraintPositionToNode(sheet, offset: const Offset(0.0, 10.0)) new ConstraintPositionToNode(sheet, offset: const Offset(0.0, 8.0))
]; ];
} }
} }
...@@ -169,18 +171,21 @@ class _PaperSheet extends Node { ...@@ -169,18 +171,21 @@ class _PaperSheet extends Node {
} }
class _PaperSheetShadow extends Node { class _PaperSheetShadow extends Node {
_PaperSheetShadow(this._config) { _PaperSheetShadow(this._config, ImageMap images) {
_paperPaint.color = Colors.black45; NineSliceSprite shadow = new NineSliceSprite.fromImage(
_paperPaint.maskFilter = new MaskFilter.blur(BlurStyle.normal, 10.0); images['packages/flutter_gallery_assets/shadow.png'],
new Size(
_config.rect.size.width + 32.0,
_config.rect.size.height + 32.0
),
const EdgeInsets.all(0.375)
);
shadow.drawCenterPart = false;
shadow.opacity = 0.5;
addChild(shadow);
} }
final _PaperConfig _config; final _PaperConfig _config;
final Paint _paperPaint = new Paint();
@override
void paint(Canvas canvas) {
canvas.drawRect(_config.rect, _paperPaint);
}
} }
class _BackgroundBox extends Node { class _BackgroundBox extends Node {
......
...@@ -10,7 +10,7 @@ dependencies: ...@@ -10,7 +10,7 @@ dependencies:
path: ../../packages/flutter_sprites path: ../../packages/flutter_sprites
flutter_markdown: flutter_markdown:
path: ../../packages/flutter_markdown path: ../../packages/flutter_markdown
flutter_gallery_assets: '0.0.15' flutter_gallery_assets: '0.0.16'
dev_dependencies: dev_dependencies:
test: any # flutter_test provides the version constraints test: any # flutter_test provides the version constraints
......
...@@ -30,6 +30,7 @@ part 'src/effect_line.dart'; ...@@ -30,6 +30,7 @@ part 'src/effect_line.dart';
part 'src/image_map.dart'; part 'src/image_map.dart';
part 'src/label.dart'; part 'src/label.dart';
part 'src/layer.dart'; part 'src/layer.dart';
part 'src/nine_slice_sprite.dart';
part 'src/node.dart'; part 'src/node.dart';
part 'src/node3d.dart'; part 'src/node3d.dart';
part 'src/node_with_size.dart'; part 'src/node_with_size.dart';
......
part of flutter_sprites;
/// A NineSliceSprite is similar to a [Sprite], but it it can strech its
/// inner area to fit the size of the [Node]. This is ideal for fast drawing
/// of things like buttons.
class NineSliceSprite extends NodeWithSize with SpritePaint {
/// Creates a new NineSliceSprite from the privided [texture], [size], and
/// texture [insets].
NineSliceSprite(Texture texture, Size size, EdgeInsets insets) : super(size) {
assert(texture != null && !texture.rotated);
assert(size != null);
assert(insets != null);
pivot = const Point(0.5, 0.5);
this.texture = texture;
this.insets = insets;
}
/// Creates a new NineSliceSprite from the provided [image], [size], and
/// texture [insets].
NineSliceSprite.fromImage(ui.Image image, Size size, EdgeInsets insets)
: this(new Texture(image), size, insets);
/// The texture that the sprite will render to screen. Cannot be null.
///
/// my9Sprite.texture = myTexture;
Texture get texture => _texture;
Texture _texture;
void set texture(Texture texture) {
_texture = texture;
_isDirty = true;
if (texture == null) {
_cachedPaint = new Paint();
} else {
Matrix4 matrix = new Matrix4.identity();
ImageShader shader = new ImageShader(texture.image,
TileMode.repeated, TileMode.repeated, matrix.storage);
_cachedPaint = new Paint()
..shader = shader;
}
}
/// The insets of the texture as normalized values. The insets define the
/// areas of the texture that will not be deformed as the sprite stretches.
EdgeInsets get insets => _insets;
EdgeInsets _insets;
void set insets(EdgeInsets insets) {
assert(insets != null);
_insets = insets;
_isDirty = true;
}
/// If true, the center part of the sprite will be drawn, this is the default
/// behavior.
bool get drawCenterPart => _drawCenterPart;
bool _drawCenterPart = true;
void set drawCenterPart(bool drawCenterPart) {
_drawCenterPart = drawCenterPart;
_isDirty = true;
}
@override
void set size(Size size) {
super.size = size;
_isDirty = true;
}
Paint _cachedPaint = new Paint()
..filterQuality = FilterQuality.low
..isAntiAlias = false;
// Cached values.
bool _isDirty = true;
List<Point> _vertices;
List<Point> _textureCoordinates;
List<Color> _colors;
List<int> _indicies;
@override
void paint(Canvas canvas) {
applyTransformForPivot(canvas);
// Setup paint object for opacity and transfer mode.
_updatePaint(_cachedPaint);
if (_isDirty) {
// Calcuate vertices and indices.
_vertices = [
Point.origin,
];
// Texture width and height.
double tw = texture.frame.width;
double th = texture.frame.height;
_textureCoordinates = <Point>[];
_vertices = <Point>[];
_colors = <Color>[];
for (int y = 0; y < 4; y += 1) {
double vy;
double ty;
switch(y) {
case 0:
vy = 0.0;
ty = texture.frame.top;
break;
case 1:
vy = insets.top * th;
ty = texture.frame.top + insets.top * th;
break;
case 2:
vy = size.height - insets.bottom * th;
ty = texture.frame.bottom - insets.bottom * th;
break;
case 3:
vy = size.height;
ty = texture.frame.bottom;
break;
}
for (int x = 0; x < 4; x += 1) {
double vx;
double tx;
switch(x) {
case 0:
vx = 0.0;
tx = texture.frame.left;
break;
case 1:
vx = insets.left * tw;
tx = texture.frame.left + insets.left * tw;
break;
case 2:
vx = size.width - insets.right * tw;
tx = texture.frame.right - insets.right * tw;
break;
case 3:
vx = size.width;
tx = texture.frame.right;
break;
}
_vertices.add(new Point(vx, vy));
_textureCoordinates.add(new Point(tx, ty));
_colors.add(const Color(0xffffffff));
}
}
// Build indices.
_indicies = <int>[];
for (int y = 0; y < 3; y += 1) {
for (int x = 0; x < 3; x += 1) {
// Check if we should skip the middle rectangle.
if (!drawCenterPart && x == 1 && y == 1)
continue;
// Add a rectangle (two triangles).
int index = y * 4 + x;
_indicies.add(index);
_indicies.add(index + 1);
_indicies.add(index + 4);
_indicies.add(index + 1);
_indicies.add(index + 5);
_indicies.add(index + 4);
}
}
}
canvas.drawVertices(
VertexMode.triangles,
_vertices,
_textureCoordinates,
_colors,
TransferMode.modulate,
_indicies,
_cachedPaint
);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment