ticketcher 0.3.0
ticketcher: ^0.3.0 copied to clipboard
A Flutter package for creating beautiful ticket-style cards with customizable borders, dividers, and patterns. Perfect for event tickets, boarding passes, and coupons.
Ticketcher #
Ticketcher is a powerful Flutter package for creating beautiful, highly customizable ticket-style cards and widgets. Effortlessly design event tickets, boarding passes, coupons, and more with support for unique border patterns, gradient backgrounds, custom notches, and flexible section layouts. Ticketcher makes it easy to add professional, interactive ticket designs to your Flutter apps with just a few lines of code.
Concert Wave Divider |
Flight Dashed Divider |
Gradient Background |
Train Solid Divider |
---|---|---|---|
Circle Pattern |
Wave Pattern |
Smooth Wave |
Multiple Sections |
Coffee Sales |
Stacked Layers |
Colored Sections |
Gradient Background |
Holographic Effects |
Table of Contents #
- Features
- Installation
- Usage
- Important Usage Notes
- Examples
- Contributing
- License
Features #
- Create both vertical and horizontal ticket layouts
- Interactive sections with individual tap callbacks
- Customizable border patterns (wave, arc, sharp)
- Multiple divider styles (solid, dashed, circles, wave, smooth wave, dotted, double line)
- Gradient backgrounds and gradient borders
- ✨ Watermarks: Text and widget watermarks with positioning, opacity, and rotation
- Custom border radius for any corner
- Shadow effects
- Section padding control
- Width and height control
- Notch radius customization
- Stacked effect for vertical tickets (creates a layered appearance in the last section)
- Individual background colors for each section
Installation #
Add this to your package's pubspec.yaml
file:
dependencies:
ticketcher: ^0.2.0
Usage #
Basic Usage #
The default mode is vertical. Here's a basic example:
Ticketcher(
sections: [
Section(
child: Text('First Section'),
),
Section(
child: Text('Second Section'),
),
],
)
Horizontal Mode #
For horizontal layout, use the horizontal
constructor:
Ticketcher.horizontal(
height: 160,
sections: [
Section(
widthFactor: 1,
child: Text('Left Section'),
),
Section(
widthFactor: 2,
child: Text('Right Section'),
),
],
)
Vertical Mode #
For vertical layout, you can use either the default constructor or the explicit vertical
constructor:
Ticketcher.vertical(
sections: [
Section(
child: Text('Top Section'),
),
Section(
child: Text('Bottom Section'),
),
],
)
Interactive Sections #
Make your tickets interactive by adding tap callbacks to individual sections. Each section can have its own onTap
function that gets called when the user taps on that specific section.
Ticketcher(
sections: [
Section(
child: Text('Header Section'),
onTap: () {
print('Header tapped!');
// Handle header tap
},
),
Section(
child: Text('Content Section'),
onTap: () {
print('Content tapped!');
// Handle content tap
},
),
Section(
child: Container(
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(8),
),
child: Text(
'TAP TO CHECK-IN',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
onTap: () {
// Handle check-in action
_performCheckIn();
},
),
],
)
Interactive Examples
Flight Ticket with Check-in:
Ticketcher(
sections: [
Section(
child: FlightHeader(),
onTap: () => _showFlightDetails(),
),
Section(
child: FlightInfo(),
onTap: () => _showRouteMap(),
),
Section(
child: CheckInButton(),
onTap: () => _performCheckIn(),
),
],
)
Event Ticket with QR Code:
Ticketcher.horizontal(
height: 200,
sections: [
Section(
widthFactor: 2,
child: EventDetails(),
onTap: () => _showEventInfo(),
),
Section(
child: QRCodeWidget(),
onTap: () => _showQRCode(),
),
],
)
The onTap
callback is completely optional. Sections without an onTap
callback will not respond to taps, while sections with onTap
will show a subtle tap effect and call your function when pressed.
Border Patterns #
Add decorative patterns to the edges of your ticket.
Ticketcher(
decoration: TicketcherDecoration(
bottomBorderStyle: BorderPattern(
shape: BorderShape.wave, // or sharp, arc
height: 8.0,
width: 20.0,
),
),
)
Available patterns:
BorderShape.wave
: Creates a wavy patternBorderShape.sharp
: Creates a zigzag patternBorderShape.arc
: Creates a series of connected arcs
Dividers #
Add dividers between sections with various styles.
Available divider styles:
DividerStyle.solid
- A simple straight lineDividerStyle.dashed
- A line made of dashesDividerStyle.circles
- A series of circlesDividerStyle.wave
- A zigzag wave patternDividerStyle.smoothWave
- A smooth curved wave patternDividerStyle.dotted
- A series of evenly spaced dotsDividerStyle.doubleLine
- Two parallel lines
Ticketcher(
decoration: TicketcherDecoration(
divider: TicketDivider(
color: Colors.grey,
thickness: 1.0,
style: DividerStyle.solid, // or dashed, circles, wave, smoothWave, dotted, doubleLine
),
),
)
Solid Divider
Ticketcher(
decoration: TicketcherDecoration(
divider: TicketDivider.solid(
color: Colors.grey,
thickness: 1.0,
padding: 8.0, // Add padding on both sides
),
),
)
Dashed Divider
Ticketcher(
decoration: TicketcherDecoration(
divider: TicketDivider.dashed(
color: Colors.grey,
thickness: 1.0,
dashWidth: 10.0,
dashSpace: 7.0,
padding: 8.0, // Add padding on both sides
),
),
)
Circle Divider
Ticketcher(
decoration: TicketcherDecoration(
divider: TicketDivider.circles(
color: Colors.grey,
thickness: 2.0,
circleRadius: 4.0,
circleSpacing: 8.0,
padding: 8.0, // Add padding on both sides
),
),
)
Wave Divider
Ticketcher(
decoration: TicketcherDecoration(
divider: TicketDivider.wave(
color: Colors.grey,
thickness: 2.0,
waveHeight: 6.0,
waveWidth: 12.0,
padding: 8.0, // Add padding on both sides
),
),
)
Smooth Wave Divider
Ticketcher(
decoration: TicketcherDecoration(
divider: TicketDivider.smoothWave(
color: Colors.grey,
thickness: 2.0,
waveHeight: 6.0,
waveWidth: 12.0,
padding: 8.0, // Add padding on both sides
),
),
)
Dotted Divider
Ticketcher(
decoration: TicketcherDecoration(
divider: TicketDivider.dotted(
color: Colors.grey,
thickness: 2.0,
dotSize: 2.0,
dotSpacing: 8.0,
padding: 8.0, // Add padding on both sides
),
),
)
Double Line Divider
Ticketcher(
decoration: TicketcherDecoration(
divider: TicketDivider.doubleLine(
color: Colors.grey,
thickness: 1.5,
lineSpacing: 4.0,
padding: 8.0, // Add padding on both sides
),
),
)
The padding
property adds equal spacing on both sides of the divider. This is useful when you want to create some space between the divider and the edges of the ticket. The padding is applied symmetrically, meaning the same amount of space is added to both the left and right sides in vertical mode, or top and bottom sides in horizontal mode.
Background Styling #
Solid Color
Ticketcher(
decoration: TicketcherDecoration(
backgroundColor: Colors.white,
),
)
Gradient
Ticketcher(
decoration: TicketcherDecoration(
gradient: LinearGradient(
colors: [Colors.blue, Colors.purple],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
)
Colored Sections #
Customize the background color of individual sections. If a section color
is provided, it overrides the backgroundColor
and gradient
from TicketcherDecoration
for that specific section. This allows for creating tickets with multi-colored parts.
Ticketcher(
sections: [
Section(
color: Colors.blue.shade100,
child: Text('First Section'),
),
Section(
color: Colors.green.shade100,
child: Text('Second Section'),
),
],
)
Border #
Add a border around your ticket using either solid colors or gradients.
Solid Color Border
Ticketcher(
decoration: TicketcherDecoration(
border: Border.all(
color: Colors.grey,
width: 1.0,
),
),
)
Gradient Border (New!)
Create stunning visual effects with gradient borders using any Flutter gradient type.
// Linear gradient border
Ticketcher(
decoration: TicketcherDecoration(
borderGradient: LinearGradient(
colors: [Colors.red, Colors.orange, Colors.yellow, Colors.green, Colors.blue],
),
borderWidth: 3.0,
),
)
// Radial gradient border
Ticketcher(
decoration: TicketcherDecoration(
borderGradient: RadialGradient(
colors: [Colors.purple, Colors.pink, Colors.orange],
),
borderWidth: 2.5,
),
)
// Sweep gradient for rainbow effects
Ticketcher(
decoration: TicketcherDecoration(
borderGradient: SweepGradient(
colors: [
Colors.red, Colors.orange, Colors.yellow, Colors.green,
Colors.blue, Colors.indigo, Colors.purple, Colors.red,
],
),
borderWidth: 2.0,
),
)
Note: When both border
and borderGradient
are specified, the gradient border takes precedence. Use borderWidth
to control the thickness of gradient borders.
Watermarks (New!) #
Add text or widget watermarks to your tickets for branding, security, or decorative purposes. Watermarks support positioning, opacity, rotation, and custom styling.
Text Watermarks #
Create text-based watermarks with custom styling and effects.
Ticketcher(
decoration: TicketcherDecoration(
watermark: TicketWatermark.text(
text: 'CONFIDENTIAL',
opacity: 0.3,
alignment: WatermarkAlignment.center,
rotation: 45, // Rotate 45 degrees
style: TextStyle(
fontSize: 32,
fontWeight: FontWeight.bold,
color: Colors.red,
),
),
),
)
Widget Watermarks #
Use any Flutter widget as a watermark, including icons, containers, or custom layouts.
Note: Widget watermarks do not support repeat functionality for performance reasons. If you need repeating patterns, use text watermarks instead.
// Icon watermark
Ticketcher(
decoration: TicketcherDecoration(
watermark: TicketWatermark.widget(
widget: Icon(
Icons.verified,
size: 80,
color: Colors.blue,
),
opacity: 0.2,
alignment: WatermarkAlignment.center,
rotation: 15,
),
),
)
// Custom widget watermark
Ticketcher(
decoration: TicketcherDecoration(
watermark: TicketWatermark.widget(
widget: Container(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),
decoration: BoxDecoration(
color: Colors.amber.withOpacity(0.2),
borderRadius: BorderRadius.circular(20),
border: Border.all(color: Colors.amber, width: 2),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.star, color: Colors.amber, size: 16),
SizedBox(width: 4),
Text(
'PREMIUM',
style: TextStyle(
color: Colors.amber,
fontWeight: FontWeight.bold,
fontSize: 12,
),
),
],
),
),
opacity: 0.7,
alignment: WatermarkAlignment.topRight,
offset: Offset(-10, 10), // Custom positioning
),
),
)
Watermark Positioning #
Control where your watermark appears with precise positioning options:
// Available alignment options
WatermarkAlignment.topLeft
WatermarkAlignment.topCenter
WatermarkAlignment.topRight
WatermarkAlignment.centerLeft
WatermarkAlignment.center
WatermarkAlignment.centerRight
WatermarkAlignment.bottomLeft
WatermarkAlignment.bottomCenter
WatermarkAlignment.bottomRight
// Example with custom offset
TicketWatermark.text(
text: 'SAMPLE',
alignment: WatermarkAlignment.bottomRight,
offset: Offset(-20, -20), // 20 pixels from bottom and right edges
)
Watermark Styling #
Customize appearance with opacity, rotation, and size controls:
TicketWatermark.text(
text: 'DRAFT',
opacity: 0.15, // Very subtle
rotation: 30, // Rotate 30 degrees
alignment: WatermarkAlignment.center,
style: TextStyle(
fontSize: 64,
fontWeight: FontWeight.w900,
color: Colors.grey,
),
)
// Repeated text watermarks across the ticket (only available for text watermarks)
TicketWatermark.text(
text: 'COPY',
repeat: true, // Repeat across ticket
repeatSpacing: 50, // Space between repetitions
opacity: 0.1,
rotation: 15,
)
// Note: Widget watermarks do not support repeat functionality for performance reasons.
// If you need repeated patterns, use text watermarks instead.
Note: Watermarks are rendered above the ticket content but below any interactive elements. For best results, use semi-transparent opacity values (0.1 - 0.3) to maintain content readability.
Shadow #
Add a shadow effect to your ticket.
Ticketcher(
decoration: TicketcherDecoration(
shadow: BoxShadow(
color: Colors.black.withOpacity(0.2),
blurRadius: 4.0,
offset: Offset(0, 2),
),
),
)
Stacked Effect #
Add a stacked effect to your vertical ticket's last section. This creates a layered appearance that adds depth to your ticket design.
Ticketcher(
decoration: TicketcherDecoration(
stackEffect: StackEffect(
count: 2, // Number of stacked layers
offset: 8.0, // Vertical offset between layers
widthStep: 4.0, // Width reduction for each layer
color: Colors.grey.withOpacity(0.2), // Color of the stacked layers
),
),
)
The stacked effect is only supported in vertical tickets and will be applied to the last section. You can customize:
count
: Number of stacked layers (1-3)offset
: Vertical offset between each layerwidthStep
: How much each layer is reduced in widthcolor
: Color of the stacked layers (defaults to a light grey if not specified)
Example with a more pronounced effect:
Ticketcher(
decoration: TicketcherDecoration(
stackEffect: StackEffect(
count: 3,
offset: 12.0,
widthStep: 8.0,
color: Colors.blue.withOpacity(0.1),
),
),
)
Note: The stacked effect is only available in vertical tickets and will be ignored in horizontal tickets.
Section Padding #
Customize the padding for each section.
Ticketcher(
sections: [
Section(
child: Text('First Section'),
padding: EdgeInsets.all(16.0),
),
Section(
child: Text('Second Section'),
padding: EdgeInsets.all(16.0),
),
],
)
Width Control #
Set a specific width for your ticket.
Ticketcher(
width: 300.0,
// ... other properties
)
Notch Radius #
Customize the radius of the notches that connect the sections.
Ticketcher(
notchRadius: 12.0,
// ... other properties
)
Important Usage Notes #
Assertions #
The package includes several assertions to prevent invalid configurations:
-
Minimum Sections
- Both vertical and horizontal tickets must have at least 2 sections
- Error message: "Vertical/Horizontal Ticketcher must have at least 2 sections"
-
Border Style and Radius Conflicts
- In vertical mode, you cannot use
bottomBorderStyle
when there's a bottom border radius - Error message: "Cannot use bottomBorderStyle when there is a bottom border radius"
- This applies to any bottom corner radius (bottom, bottomLeft, bottomRight, or all corners)
- In vertical mode, you cannot use
Best Practices #
-
Section Width Factors
- In horizontal mode, use
widthFactor
to control section widths - The total of all width factors determines the relative sizes
- Example:
widthFactor: 1
andwidthFactor: 2
creates a 1:2 ratio
- In horizontal mode, use
-
Border Patterns
- Border patterns work best with straight edges
- Avoid using border patterns on edges with rounded corners
- For best results, use patterns on edges without radius
-
Dividers
- Choose divider styles that complement your border patterns
- Consider using matching colors for borders and dividers
- Adjust thickness and spacing for better visual balance
-
Performance
- Use
width
andheight
properties when you know the exact dimensions - This helps avoid unnecessary layout calculations
- For dynamic content, let the widget calculate its own size
- Use
Examples #
Gradient Border Showcase #
Here are some popular gradient border combinations:
// Neon cyber border
Ticketcher(
decoration: TicketcherDecoration(
backgroundColor: Colors.black,
borderGradient: LinearGradient(
colors: [Color(0xFF00FFFF), Color(0xFF0080FF), Color(0xFF8000FF), Color(0xFFFF00FF)],
),
borderWidth: 2.5,
shadow: BoxShadow(
color: Colors.cyan.withOpacity(0.5),
blurRadius: 15,
spreadRadius: 2,
),
),
)
// Sunset gradient border
Ticketcher(
decoration: TicketcherDecoration(
backgroundColor: Colors.white,
borderGradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [Color(0xFFFFD89B), Color(0xFFFF8A56), Color(0xFFFF6B6B)],
),
borderWidth: 2.0,
),
)
// Metallic gold border
Ticketcher(
decoration: TicketcherDecoration(
backgroundColor: Colors.white,
borderGradient: LinearGradient(
colors: [Color(0xFFFFD700), Color(0xFFFFA500), Color(0xFFFFD700), Color(0xFFB8860B)],
),
borderWidth: 3.0,
shadow: BoxShadow(
color: Colors.amber.withOpacity(0.3),
blurRadius: 8,
),
),
)
Check out the example directory for more detailed examples of different ticket styles and configurations, including the new gradient border showcase.
Contributing #
Contributions are welcome! Please feel free to submit a Pull Request.
License #
This project is licensed under the MIT License - see the LICENSE file for details.