Skip to content

Commit

Permalink
Merge pull request #9 from Rahiche/ft-add-tint-color
Browse files Browse the repository at this point in the history
Add tint color support
  • Loading branch information
Rahiche authored Sep 17, 2024
2 parents 1fa71cd + fb19fbc commit 2502bb6
Show file tree
Hide file tree
Showing 8 changed files with 520 additions and 277 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.1.1
* Breaking change: EdgeBlur control now requires the use of named parameters
* Added support for tint color
* New Airbnb Card example

## 0.1.0
* Multiple edges can now be applied simultaneously
* re-implemented using a new technique using a single gradient mask and blur operation
Expand Down
45 changes: 18 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[![pub package](https://img.shields.io/pub/v/soft_edge_blur.svg)](https://pub.dev/packages/soft_edge_blur)


A Flutter package that provides a customizable soft edge blur effect for widgets.
A Flutter package that provides a customizable soft progressive blur effect for widgets.

<img width="547" alt="Map blurred" src="https://i.imgur.com/7DcixDz.png">

Expand Down Expand Up @@ -34,20 +34,26 @@ import 'package:soft_edge_blur/soft_edge_blur.dart';
Wrap any widget with `SoftEdgeBlur` to apply the blur effect:

```dart
SoftEdgeBlur(
return SoftEdgeBlur(
edges: [
EdgeBlur(
EdgeType.topEdge,
100.0, // Edge Size
20.0, // Blur Sigma
type: EdgeType.topEdge,
size: 1000,
sigma: 30,
controlPoints: [
ControlPoint(position: 0.5, type: ControlPointType.visible),
ControlPoint(position: 1.0, type: ControlPointType.transparent),
ControlPoint(
position: 0.5,
type: ControlPointType.visible,
),
ControlPoint(
position: 1,
type: ControlPointType.transparent,
)
],
),
)
],
child: YourWidget(),
)
);
```

## Customization
Expand All @@ -66,35 +72,20 @@ Specify which edges to apply the blur effect:
You can apply blur to multiple edges simultaneously.

### Edge Size

Set the size of the blurred area. This determines how far the blur effect extends from the edge of the widget.

### Blur Sigma

Adjust the intensity of the blur effect.

### Control Points
### Tint Color
Apply a tint color on top of the blurred area.

### Control Points
Define points to control the blur gradient along the edge. Each control point has two properties:

- `position`: A value between 0.0 and 1.0, representing the position along the edge.
- `type`: Either `ControlPointType.visible` or `ControlPointType.transparent`.


### Example Configuration

```dart
EdgeBlur(
EdgeType.topEdge,
100.0, // Edge Size
20.0, // Blur Sigma
controlPoints: [
ControlPoint(position: 0.5, type: ControlPointType.visible),
ControlPoint(position: 1.0, type: ControlPointType.transparent),
],
),
```

### Try it live here

https://soft_edge_blur.codemagic.app/
277 changes: 29 additions & 248 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,275 +1,56 @@
import 'package:flutter/material.dart';
import 'package:soft_edge_blur/soft_edge_blur.dart';
import 'package:latlong2/latlong.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:example/samples/airbnb.dart';
import 'package:example/samples/map.dart';

void main() {
runApp(const MyApp());
runApp(const AppChooser());
}

class MyApp extends StatelessWidget {
const MyApp({super.key});
class AppChooser extends StatelessWidget {
const AppChooser({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'SoftEdgeBlur Demo',
title: 'SoftEdgeBlur Demos',
theme: ThemeData.dark(),
home: const HomePage(),
home: const AppChooserHome(),
);
}
}

class HomePage extends StatefulWidget {
const HomePage({super.key});

@override
State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
final Set<EdgeType> _selectedEdges = {EdgeType.topEdge};
double _edgeSize = 100.0;
double _blurSigma = 20.0;

final List<ControlPoint> _controlPoints = [
ControlPoint(position: 0.0, type: ControlPointType.visible),
ControlPoint(position: 1.0, type: ControlPointType.transparent),
];
class AppChooserHome extends StatelessWidget {
const AppChooserHome({super.key});

@override
Widget build(BuildContext context) {
// Adjust control points for Right and Bottom edges
Map<EdgeType, List<ControlPoint>> controlPointsPerEdge = {};

for (var edge in _selectedEdges) {
controlPointsPerEdge[edge] = _controlPoints;
}

return Scaffold(
body: Row(
children: [
Expanded(
child: SoftEdgeBlur(
edges: _selectedEdges.map((edge) {
return EdgeBlur(
type: edge,
size: _edgeSize,
sigma: _blurSigma,
controlPoints: controlPointsPerEdge[edge]!,
);
}).toList(),
child: _buildMap(),
),
),
Expanded(child: _buildControls()),
],
appBar: AppBar(
title: const Text('Choose an App'),
),
);
}

FlutterMap _buildMap() {
return FlutterMap(
options: MapOptions(
initialCenter: const LatLng(51.5, -0.09),
initialZoom: 18,
cameraConstraint: CameraConstraint.contain(
bounds: LatLngBounds(
const LatLng(-90, -180),
const LatLng(90, 180),
),
),
),
children: [
TileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
userAgentPackageName: 'dev.fleaflet.flutter_map.example',
tileBuilder: darkModeTileBuilder,
),
RichAttributionWidget(
popupInitialDisplayDuration: const Duration(seconds: 5),
animationConfig: const ScaleRAWA(),
showFlutterMapAttribution: false,
attributions: [
TextSourceAttribution(
'OpenStreetMap contributors',
onTap: () {},
),
const TextSourceAttribution(
'This attribution is the same throughout this app, except '
'where otherwise specified',
prependCopyright: false,
),
],
),
],
);
}

Widget _buildControlPointControl(int index, ControlPoint cp) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Control Point ${index + 1}'),
Row(
children: [
Expanded(
child: Slider(
value: cp.position,
min: 0.0,
max: 1.0,
divisions: 100,
label: cp.position.toStringAsFixed(2),
onChanged: (double value) {
setState(() {
cp.position = value;
});
},
),
),
DropdownButton<ControlPointType>(
value: cp.type,
items: ControlPointType.values.map((ControlPointType type) {
return DropdownMenuItem<ControlPointType>(
value: type,
child: Text(type == ControlPointType.visible
? 'Visible'
: 'Transparent'),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const AirbnbCardApp()),
);
}).toList(),
onChanged: (ControlPointType? newValue) {
setState(() {
cp.type = newValue!;
});
},
child: const Text('Airbnb Card App'),
),
IconButton(
icon: const Icon(Icons.delete),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
setState(() {
_controlPoints.removeAt(index);
});
},
),
],
),
],
);
}

Widget _buildControls() {
return Container(
padding: const EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: Column(
children: [
Row(
children: [
Checkbox(
value: _selectedEdges.contains(EdgeType.topEdge),
onChanged: (bool? value) {
setState(() {
if (value == true) {
_selectedEdges.add(EdgeType.topEdge);
} else {
_selectedEdges.remove(EdgeType.topEdge);
}
});
},
),
const Text('Top'),
Checkbox(
value: _selectedEdges.contains(EdgeType.bottomEdge),
onChanged: (bool? value) {
setState(() {
if (value == true) {
_selectedEdges.add(EdgeType.bottomEdge);
} else {
_selectedEdges.remove(EdgeType.bottomEdge);
}
});
},
),
const Text('Bottom'),
Checkbox(
value: _selectedEdges.contains(EdgeType.leftEdge),
onChanged: (bool? value) {
setState(() {
if (value == true) {
_selectedEdges.add(EdgeType.leftEdge);
} else {
_selectedEdges.remove(EdgeType.leftEdge);
}
});
},
),
const Text('Left'),
Checkbox(
value: _selectedEdges.contains(EdgeType.rightEdge),
onChanged: (bool? value) {
setState(() {
if (value == true) {
_selectedEdges.add(EdgeType.rightEdge);
} else {
_selectedEdges.remove(EdgeType.rightEdge);
}
});
},
),
const Text('Right'),
],
),
Text('Edge Size: ${_edgeSize.round()}'),
Slider(
value: _edgeSize,
min: 0,
max: 200,
divisions: 20,
label: _edgeSize.round().toString(),
onChanged: (double value) {
setState(() {
_edgeSize = value;
});
},
),
Text('Blur Sigma: ${_blurSigma.toStringAsFixed(1)}'),
Slider(
value: _blurSigma,
min: 0,
max: 40,
divisions: 40,
label: _blurSigma.toStringAsFixed(1),
onChanged: (double value) {
setState(() {
_blurSigma = value;
});
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const MapApp()),
);
},
),
const SizedBox(height: 16),
const Text('Control Points:'),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
...List.generate(_controlPoints.length, (index) {
return _buildControlPointControl(
index, _controlPoints[index]);
}),
ElevatedButton(
onPressed: () {
setState(() {
_controlPoints.add(
ControlPoint(
position: 0.5,
type: ControlPointType.visible,
),
);
_controlPoints
.sort((a, b) => a.position.compareTo(b.position));
});
},
child: const Text('Add Control Point'),
),
],
child: const Text('Map App'),
),
],
),
Expand Down
Loading

0 comments on commit 2502bb6

Please sign in to comment.