Created
November 6, 2021 21:42
-
-
Save chonghorizons/f61dde406ad3e346fcf244c7efd9f7ed to your computer and use it in GitHub Desktop.
Flutter, Star Path for clipping, N-pointed star clipper for Flutter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Based on the blog article by "The Plumber" https://www.kindacode.com/article/flutter-drawing-an-n-pointed-star-with-customclipper/ | |
// main.dart | |
import 'package:flutter/material.dart'; | |
import 'dart:math' as math; | |
// This custom clipper help us achieve n-pointed star shape | |
class StarClipper extends CustomClipper<Path> { | |
/// The number of points of the star | |
final int points; | |
StarClipper(this.points); | |
// Degrees to radians conversion | |
double _degreeToRadian(double deg) => deg * (math.pi / 180.0); | |
@override | |
Path getClip(Size size) { | |
Path path = Path(); | |
double max = 2 * math.pi; | |
double width = size.width; | |
double halfWidth = width / 2; | |
double wingRadius = halfWidth; | |
double radius = halfWidth / 2; | |
double degreesPerStep = _degreeToRadian(360 / points); | |
double halfDegreesPerStep = degreesPerStep / 2; | |
path.moveTo(width, halfWidth); | |
for (double step = 0; step < max; step += degreesPerStep) { | |
path.lineTo(halfWidth + wingRadius * math.cos(step), | |
halfWidth + wingRadius * math.sin(step)); | |
path.lineTo(halfWidth + radius * math.cos(step + halfDegreesPerStep), | |
halfWidth + radius * math.sin(step + halfDegreesPerStep)); | |
} | |
path.close(); | |
return path; | |
} | |
// If the new instance represents different information than the old instance, this method will return true, otherwise it should return false. | |
@override | |
bool shouldReclip(CustomClipper<Path> oldClipper) { | |
StarClipper starClipper = oldClipper as StarClipper; | |
return points != starClipper.points; | |
} | |
} | |
void main() { | |
runApp(const MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
const MyApp({Key? key}) : super(key: key); | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
debugShowCheckedModeBanner: false, | |
title: 'KindaCode.com', | |
theme: ThemeData( | |
primarySwatch: Colors.indigo, | |
), | |
home: const MyHomePage(), | |
); | |
} | |
} | |
class MyHomePage extends StatefulWidget { | |
const MyHomePage({Key? key}) : super(key: key); | |
@override | |
_MyHomePageState createState() => _MyHomePageState(); | |
} | |
class _MyHomePageState extends State<MyHomePage> { | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: const Text('Kindacode.com'), | |
), | |
body: ListView( | |
// child: Center( | |
// child: Column( | |
children: [ | |
// 5-pointed star | |
Column(children: [ | |
SizedBox( | |
height: 180, | |
width: 180, | |
child: ClipPath( | |
clipper: StarClipper(5), | |
child: Container( | |
height: 20, | |
color: Colors.green, | |
), | |
), | |
), | |
]), | |
// 5-pointed star Image | |
Column(children: [ | |
SizedBox( | |
height: 180, | |
width: 180, | |
child: ClipPath( | |
clipper: StarClipper(5), | |
child: const Image( | |
image: NetworkImage( | |
'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl.jpg'), | |
)), | |
), | |
]), | |
// 6-pointed star | |
Column(children: [ | |
SizedBox( | |
height: 180, | |
width: 180, | |
child: ClipPath( | |
clipper: StarClipper(6), | |
child: Container( | |
height: 300, | |
color: Colors.amber, | |
), | |
), | |
), | |
]), | |
// 10-pointed star | |
Column(children: [ | |
SizedBox( | |
height: 180, | |
width: 180, | |
child: ClipPath( | |
clipper: StarClipper(10), | |
child: Container( | |
height: 150, | |
color: Colors.indigo, | |
), | |
), | |
), | |
]), | |
// 20-pointed star | |
Column(children: [ | |
SizedBox( | |
height: 180, | |
width: 180, | |
child: ClipPath( | |
clipper: StarClipper(20), | |
child: Container( | |
height: 150, | |
color: Colors.cyan, | |
), | |
), | |
), | |
]), | |
//red box, for comparison | |
Column(children: [ | |
SizedBox( | |
height: 180, | |
width: 180, | |
child: Container( | |
height: 300, | |
color: Colors.red, | |
), | |
) | |
]), | |
// Comparison image, copied from https://api.flutter.dev/flutter/painting/BoxDecoration-class.html NOV 2021 | |
Column(children: [ | |
SizedBox( | |
height: 180, | |
width: 180, | |
child: Container( | |
decoration: BoxDecoration( | |
color: const Color(0xff7c94b6), | |
image: const DecorationImage( | |
image: NetworkImage( | |
'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl-2.jpg'), | |
fit: BoxFit.cover, | |
), | |
border: Border.all( | |
color: Colors.black, | |
width: 8, | |
), | |
borderRadius: BorderRadius.circular(12), | |
), | |
), | |
), | |
]), | |
], | |
), | |
// ), | |
//), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment