blob: d77681e0ca4716d277abc0acafafd1dfb1d04cb5 [file] [log] [blame]
part of sprites;
/// A Sprite is a [Node] that renders a bitmap image to the screen.
class Sprite extends NodeWithSize with SpritePaint {
/// The texture that the sprite will render to screen.
///
/// If the texture is null, the sprite will be rendered as a red square
/// marking the bounds of the sprite.
///
/// mySprite.texture = myTexture;
Texture texture;
/// If true, constrains the proportions of the image by scaling it down, if its proportions doesn't match the [size].
///
/// mySprite.constrainProportions = true;
bool constrainProportions = false;
Paint _cachedPaint = new Paint()
..setFilterQuality(FilterQuality.low)
..isAntiAlias = false;
/// Creates a new sprite from the provided [texture].
///
/// var mySprite = new Sprite(myTexture)
Sprite([this.texture]) : super(Size.zero) {
if (texture != null) {
size = texture.size;
pivot = texture.pivot;
} else {
pivot = new Point(0.5, 0.5);
}
}
/// Creates a new sprite from the provided [image].
///
/// var mySprite = new Sprite.fromImage(myImage);
Sprite.fromImage(Image image) : super(Size.zero) {
assert(image != null);
texture = new Texture(image);
size = texture.size;
pivot = new Point(0.5, 0.5);
}
void paint(PaintingCanvas canvas) {
// Account for pivot point
applyTransformForPivot(canvas);
if (texture != null) {
double w = texture.size.width;
double h = texture.size.height;
if (w <= 0 || h <= 0) return;
double scaleX = size.width / w;
double scaleY = size.height / h;
if (constrainProportions) {
// Constrain proportions, using the smallest scale and by centering the image
if (scaleX < scaleY) {
canvas.translate(0.0, (size.height - scaleX * h) / 2.0);
scaleY = scaleX;
} else {
canvas.translate((size.width - scaleY * w) / 2.0, 0.0);
scaleX = scaleY;
}
}
canvas.scale(scaleX, scaleY);
// Setup paint object for opacity and transfer mode
_updatePaint(_cachedPaint);
// Do actual drawing of the sprite
texture.drawTexture(canvas, Point.origin, _cachedPaint);
} else {
// Paint a red square for missing texture
canvas.drawRect(new Rect.fromLTRB(0.0, 0.0, size.width, size.height),
new Paint()..color = new Color.fromARGB(255, 255, 0, 0));
}
}
}
abstract class SpritePaint {
double _opacity = 1.0;
/// The opacity of the sprite in the range 0.0 to 1.0.
///
/// mySprite.opacity = 0.5;
double get opacity => _opacity;
void set opacity(double opacity) {
assert(opacity != null);
assert(opacity >= 0.0 && opacity <= 1.0);
_opacity = opacity;
}
/// The color to draw on top of the sprite, null if no color overlay is used.
///
/// // Color the sprite red
/// mySprite.colorOverlay = new Color(0x77ff0000);
Color colorOverlay;
/// The transfer mode used when drawing the sprite to screen.
///
/// // Add the colors of the sprite with the colors of the background
/// mySprite.transferMode = TransferMode.plusMode;
TransferMode transferMode;
void _updatePaint(Paint paint) {
paint.color = new Color.fromARGB((255.0*_opacity).toInt(), 255, 255, 255);
if (colorOverlay != null) {
paint.setColorFilter(new ColorFilter.mode(colorOverlay, TransferMode.srcATop));
}
if (transferMode != null) {
paint.setTransferMode(transferMode);
}
}
}