pixel_ui 0.3.0
pixel_ui: ^0.3.0 copied to clipboard
Pixel-art design system for Flutter. Parametric shapes, interactive buttons, and bundled pixel font.
pixel_ui #
Pixel-art design system for Flutter β parametric shapes, interactive buttons, and a bundled pixel font.
π¨ Try the PixelShapeStyle tuner β
[pixel_ui hero β logo, corners, shadow, and texture primitives]
Features #
- Stair-pattern asymmetric corners (
PixelCornerswith.sharp/.xs/.sm/.md/.lg/.xlpresets, plus fully custom per-corner control) - Deterministic LCG texture overlays
- Pixel-aware drop shadows with
.sm/.md/.lgfactories - Press-stateβaware interactive pixel buttons (
PixelButton) - Bundled Mulmaru pixel font (SIL OFL 1.1) with a ready-made
TextStylefactory - Zero external dependencies beyond the Flutter SDK
Platforms #
| Platform | Status | Verification |
|---|---|---|
| Android | β | CI build (debug APK) |
| iOS | β | CI build (no-codesign) |
| Web | β | CI build + smoke-tested on Chrome |
| macOS | β | CI build + smoke-tested locally |
| Linux | β | CI build |
| Windows | β | CI build |
Web is smoke-tested on Chrome. Other browsers (Safari, Firefox) should work but are not part of release validation. Linux and Windows are validated by CI build only β please file an issue if you find rendering glitches on those platforms.
Install #
dependencies:
pixel_ui: ^0.2.0
Quick Start #
import 'package:flutter/widgets.dart';
import 'package:pixel_ui/pixel_ui.dart';
final style = PixelShapeStyle(
corners: PixelCorners.lg,
fillColor: const Color(0xFF5A8A3A),
borderColor: const Color(0xFF2A4820),
borderWidth: 1,
shadow: PixelShadow.sm(const Color(0xFF1A3010)),
);
PixelButton(
logicalWidth: 60,
logicalHeight: 18,
normalStyle: style,
onPressed: () {},
child: Text(
'START',
style: PixelText.mulmaru(fontSize: 18, color: const Color(0xFFFFFFFF)),
),
);
Sizing model #
logicalWidth and logicalHeight are integer pixel-art grid cells, not
screen pixels. When you don't pass width: / height:, the widget renders at
logical size Γ 4 screen pixels (so logicalWidth: 60, logicalHeight: 18
β 240Γ72 dp). Override either dimension to stretch the same logical grid to a
custom screen size β the painter still draws at the logical resolution so
pixels stay crisp. Aspect ratio is preserved if only one of width/height
is given.
The logical values also drive corner stair patterns, shadow offsets, and texture cell sizes, so think of them as the "pixel art canvas" the design is authored on.
Usage #
Corners #
PixelCorners describes an asymmetric per-corner stair pattern. Use the provided scale constants or compose your own:
const PixelCorners.all([3, 2, 1]) // symmetric medium
const PixelCorners.only(tl: [3, 2, 1], tr: [3, 2, 1]) // top tab
PixelCorners.sharp // all square
PixelCorners.xs // 1-pixel rounding
PixelCorners.md // 3-row stair
PixelCorners.lg // 4-row stair
Shadows #
PixelShadow.sm(Colors.black) // offset (1, 1)
PixelShadow.md(Colors.black) // offset (2, 2)
PixelShadow.lg(Colors.black) // offset (4, 4)
const PixelShadow(offset: Offset(3, 2), color: Colors.black) // custom
PixelButton #
PixelButton(
logicalWidth: 60,
logicalHeight: 18,
normalStyle: /* PixelShapeStyle */,
pressedStyle: /* optional, falls back to normalStyle */,
disabledStyle: /* optional, falls back to normalStyle at 50% opacity */,
pressChildOffset: const Offset(0, 1),
onPressed: () {},
semanticsLabel: 'Start',
child: /* your child widget */,
);
When onPressed is null the button is non-interactive. If you pass a
disabledStyle it renders at full opacity with that style; otherwise the
button falls back to normalStyle rendered at 50% opacity β a generic dim
that avoids a distracting visual when you don't need one.
Texture #
PixelShapeStyle(
corners: PixelCorners.md,
fillColor: const Color(0xFFFFD643),
texture: const PixelTexture(
color: Color(0xFFFFF7D0),
density: 0.15,
size: 1,
seed: 7,
),
);
Textures use a deterministic LCG so identical settings produce identical patterns across platforms and builds.
Typography #
The package bundles the Mulmaru proportional pixel font. Use the factory helper:
Text('λ¬λ €λΌ', style: PixelText.mulmaru(fontSize: 20, color: Colors.white));
Or compose a custom TextStyle using the exposed constants:
Text(
'hello',
style: TextStyle(
fontFamily: PixelText.mulmaruFontFamily,
package: PixelText.mulmaruPackage,
fontSize: 18,
),
);
Monospaced variant
For code, terminal-style UI, or fixed-width layouts, use PixelText.mulmaruMono:
Text(
'HP 042/100',
style: PixelText.mulmaruMono(fontSize: 12, color: Colors.white),
)
Gallery #
| Corners | Shadows |
|---|---|
| [Corner stair presets: sharp, xs, sm, md, lg, xl, and an asymmetric tab] | [Pixel drop shadows at sm, md, lg offsets] |
| Buttons | Texture |
|---|---|
| [PixelButton states: normal, pressed, disabled] | [Deterministic LCG texture overlay β plain vs textured] |
Example #
See example/lib/main.dart for a full showcase of every primitive. Run:
cd example
flutter run
Bundled Font #
This package bundles the Mulmaru pixel fonts (proportional + monospaced variants) by mushsooni, distributed under the SIL Open Font License 1.1.
See OFL.txt for the full font license. Apps using pixel_ui should include OFL attribution in their open-source license disclosures; Flutter's showLicensePage() handles this automatically when the bundling note (see LICENSE) is in place.
Contributing #
Issues and PRs are welcome at github.com/BottlePumpkin/pixel_ui/issues.
Internal quality improvement cycles use the dogfood label. To view only user-facing issues:
open issues excluding dogfood.
License #
MIT for code (see LICENSE). Bundled Mulmaru font is under SIL OFL 1.1 (see OFL.txt).