flutter_parallax_scroll 0.1.0
flutter_parallax_scroll: ^0.1.0 copied to clipboard
A package for creating beautiful parallax scrolling effects with customizable speed and direction
import 'package:flutter/material.dart';
import 'package:flutter_parallax_scroll/flutter_parallax_scroll.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Parallax Scroll Example',
theme: ThemeData(
primarySwatch: Colors.blue,
useMaterial3: true,
),
home: const ParallaxExamplePage(),
);
}
}
class ParallaxExamplePage extends StatefulWidget {
const ParallaxExamplePage({super.key});
@override
State<ParallaxExamplePage> createState() => _ParallaxExamplePageState();
}
class _ParallaxExamplePageState extends State<ParallaxExamplePage> {
late ParallaxScrollController _controller;
double _backgroundSpeed = 0.3;
double _textSpeed = 0.1;
ParallaxDirection _direction = ParallaxDirection.vertical;
bool _reverse = false;
@override
void initState() {
super.initState();
_controller = ParallaxScrollController();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Parallax Scroll Controls'),
backgroundColor: Colors.blue.shade700,
foregroundColor: Colors.white,
),
body: Column(
children: [
// Control Panel
Container(
padding: const EdgeInsets.all(16),
color: Colors.grey.shade100,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Parallax Controls',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 12),
// Background Speed Slider
Text(
'Background Speed: ${_backgroundSpeed.toStringAsFixed(2)}'),
Slider(
value: _backgroundSpeed,
min: 0.0,
max: 2.0,
divisions: 40,
onChanged: (value) {
setState(() {
_backgroundSpeed = value;
});
},
),
const SizedBox(height: 8),
// Text Speed Slider
Text('Text Speed: ${_textSpeed.toStringAsFixed(2)}'),
Slider(
value: _textSpeed,
min: 0.0,
max: 2.0,
divisions: 40,
onChanged: (value) {
setState(() {
_textSpeed = value;
});
},
),
const SizedBox(height: 8),
// Direction Dropdown
const Text('Direction:'),
DropdownButton<ParallaxDirection>(
value: _direction,
isExpanded: true,
onChanged: (value) {
if (value != null) {
setState(() {
_direction = value;
});
}
},
items: ParallaxDirection.values.map((direction) {
return DropdownMenuItem(
value: direction,
child: Text(direction.name),
);
}).toList(),
),
const SizedBox(height: 8),
// Reverse Checkbox
Row(
children: [
Checkbox(
value: _reverse,
onChanged: (value) {
setState(() {
_reverse = value ?? false;
});
},
),
const Text('Reverse Direction'),
],
),
],
),
),
// Scrollable Content
Expanded(
child: ParallaxScrollView(
controller: _controller,
child: SingleChildScrollView(
child: Column(
children: [
// Hero Section with Parallax Background
SizedBox(
height: 400,
child: Stack(
children: [
// Parallax background
Positioned.fill(
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Colors.blue.shade400,
Colors.purple.shade400,
Colors.pink.shade400,
],
),
),
).asParallaxItem(
controller: _controller,
config: ParallaxConfig(
speed: _backgroundSpeed,
direction: _direction,
reverse: _reverse,
),
),
),
// Content
Positioned.fill(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'Parallax Scroll',
style: TextStyle(
fontSize: 48,
color: Colors.white,
fontWeight: FontWeight.bold,
shadows: [
Shadow(
offset: Offset(2, 2),
blurRadius: 4,
color: Colors.black26,
),
],
),
).asParallaxItem(
controller: _controller,
config: ParallaxConfig(
speed: _textSpeed,
direction: ParallaxDirection.vertical,
reverse: false,
),
),
const SizedBox(height: 20),
const Text(
'Scroll to see the parallax effect',
style: TextStyle(
fontSize: 18,
color: Colors.white,
shadows: [
Shadow(
offset: Offset(1, 1),
blurRadius: 2,
color: Colors.black26,
),
],
),
).asParallaxItem(
controller: _controller,
config: ParallaxConfig(
speed: _textSpeed * 2,
direction: ParallaxDirection.vertical,
reverse: false,
),
),
],
),
),
),
],
),
),
// Section 1: Parallax Background Section
Container(
margin: const EdgeInsets.only(top: 40, bottom: 20),
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Parallax Background Section',
style: TextStyle(
fontSize: 28,
fontWeight: FontWeight.bold,
color: Colors.grey.shade800,
),
),
const SizedBox(height: 10),
Text(
'These sections have parallax backgrounds that move at different speeds',
style: TextStyle(
fontSize: 16,
color: Colors.grey.shade600,
),
),
],
),
),
// Parallax Background Examples
...List.generate(3, (index) {
return Container(
height: 350,
margin: const EdgeInsets.symmetric(
horizontal: 20, vertical: 15),
child: Stack(
children: [
// Parallax Background
Positioned.fill(
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Colors
.primaries[
index % Colors.primaries.length]
.shade400,
Colors
.primaries[
index % Colors.primaries.length]
.shade600,
Colors
.primaries[
index % Colors.primaries.length]
.shade800,
],
),
borderRadius: BorderRadius.circular(20),
),
).asParallaxItem(
controller: _controller,
config: ParallaxConfig(
speed: 0.2 + (index * 0.2),
direction: _direction,
reverse: _reverse,
),
),
),
// Content Overlay
Positioned.fill(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.black.withValues(alpha: .3),
),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(
Icons.image,
size: 64,
color: Colors.white,
),
const SizedBox(height: 16),
Text(
'Parallax Background ${index + 1}',
style: const TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
const SizedBox(height: 8),
Text(
'Speed: ${(0.2 + (index * 0.2)).toStringAsFixed(1)}',
style: const TextStyle(
fontSize: 16,
color: Colors.white70,
),
),
],
),
),
),
),
],
),
);
}),
// Section 2: Content Section
Container(
margin: const EdgeInsets.only(top: 40, bottom: 20),
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Content Section',
style: TextStyle(
fontSize: 28,
fontWeight: FontWeight.bold,
color: Colors.grey.shade800,
),
),
const SizedBox(height: 10),
Text(
'Regular content sections with parallax effects on the content itself',
style: TextStyle(
fontSize: 16,
color: Colors.grey.shade600,
),
),
],
),
),
// Content Examples
...List.generate(4, (index) {
return Container(
height: 250,
margin: const EdgeInsets.symmetric(
horizontal: 20, vertical: 15),
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: .1),
blurRadius: 15,
offset: const Offset(0, 5),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 60,
height: 60,
decoration: BoxDecoration(
color: Colors
.primaries[index % Colors.primaries.length]
.shade100,
borderRadius: BorderRadius.circular(12),
),
child: Icon(
Icons.article,
color: Colors
.primaries[index % Colors.primaries.length]
.shade700,
size: 32,
),
).asParallaxItem(
controller: _controller,
config: ParallaxConfig(
speed: 0.15 + (index * 0.1),
direction: ParallaxDirection.vertical,
reverse: false,
),
),
const SizedBox(height: 16),
Text(
'Content Item ${index + 1}',
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
color: Colors.grey.shade800,
),
).asParallaxItem(
controller: _controller,
config: ParallaxConfig(
speed: 0.1 + (index * 0.08),
direction: ParallaxDirection.vertical,
reverse: false,
),
),
const SizedBox(height: 8),
Text(
'This is a content section with parallax effects applied to individual elements.',
style: TextStyle(
fontSize: 14,
color: Colors.grey.shade600,
height: 1.5,
),
).asParallaxItem(
controller: _controller,
config: ParallaxConfig(
speed: 0.05 + (index * 0.05),
direction: ParallaxDirection.vertical,
reverse: false,
),
),
],
),
);
}),
const SizedBox(height: 40),
],
),
),
),
),
],
),
);
}
}