Hourglass
This commit is contained in:
122
lib/CustomWidgets.dart
Normal file
122
lib/CustomWidgets.dart
Normal file
@@ -0,0 +1,122 @@
|
||||
|
||||
import 'dart:math';
|
||||
import 'dart:ui' as ui;
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class HourglassPainter extends CustomPainter{
|
||||
double fillAmount =0;
|
||||
List<Color> colors = [Colors.black];
|
||||
List<double> colorStops = [1];
|
||||
HourglassPainter(this.fillAmount, this.colors, this.colorStops);
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
double hourglassCurve = size.height * 0.5;
|
||||
double hourglassInset = size.width / 10;
|
||||
double hourglassHalfHeight = (size.height / 2) - hourglassInset;
|
||||
// const LinearGradient gradient = LinearGradient(
|
||||
// tileMode: TileMode.clamp,
|
||||
// colors: <Color>[
|
||||
// Colors.blue,
|
||||
// Colors.green,
|
||||
// Colors.red// blue sky
|
||||
// ],
|
||||
// stops: <double>[0.2, 0.6,1],
|
||||
// );
|
||||
|
||||
final outlinePainter = Paint()
|
||||
..color=Colors.orangeAccent
|
||||
..strokeCap=StrokeCap.round
|
||||
..strokeWidth=5
|
||||
// ..shader=ui.Gradient.linear(Offset(0,0), Offset(100,100), [Colors.green, Colors.amber, Colors.blue])
|
||||
..style=PaintingStyle.stroke;
|
||||
final contentPainter = Paint()
|
||||
..color=Colors.brown
|
||||
..strokeCap=StrokeCap.round
|
||||
..strokeWidth=1;
|
||||
|
||||
|
||||
final outline = Path();
|
||||
|
||||
outline.moveTo(hourglassInset, hourglassInset);
|
||||
outline.arcToPoint(Offset(size.width-hourglassInset,hourglassInset));
|
||||
outline.arcToPoint(Offset(size.width * 0.6,size.height * 0.45),radius: Radius.circular(hourglassCurve),clockwise: true);
|
||||
outline.arcToPoint(Offset(size.width * 0.55,size.height * 0.55),radius: Radius.circular(20),clockwise: false);
|
||||
outline.arcToPoint(Offset(size.width-hourglassInset,size.height-10),radius: Radius.circular(hourglassCurve),clockwise: true);
|
||||
outline.arcToPoint(Offset(hourglassInset, size.height-hourglassInset));
|
||||
outline.arcToPoint(Offset(size.width * 0.45,size.height * 0.55),radius: Radius.circular(hourglassCurve),clockwise: true);
|
||||
outline.arcToPoint(Offset(size.width * 0.4,size.height * 0.45),radius: Radius.circular(20),clockwise: false);
|
||||
outline.arcToPoint(Offset(hourglassInset,hourglassInset),radius: Radius.circular(hourglassCurve),clockwise: true);
|
||||
outline.close();
|
||||
|
||||
final topContent = Path();
|
||||
double topStartHeight = size.height*(0.4 -((1-fillAmount) *0.3));
|
||||
double topEndHeight = size.height * 0.48;
|
||||
double topContentStartWidthOffset = getTopContentWidthOffset(size.width, topStartHeight, hourglassHalfHeight, hourglassInset);
|
||||
double topContentEndWidthOffset = getTopContentWidthOffset(size.width, topEndHeight, hourglassHalfHeight, hourglassInset);
|
||||
// double contentWidthOffset = (((size.width /2) - hourglassInset) * sin((endHeight/hourglassHalfHeight) * (pi/6)));
|
||||
|
||||
topContent.moveTo(topContentStartWidthOffset,topStartHeight);
|
||||
topContent.arcToPoint(Offset(hourglassInset+ topContentEndWidthOffset,topEndHeight), radius: Radius.circular(hourglassCurve),clockwise: false);
|
||||
topContent.arcToPoint(Offset((size.width - hourglassInset)-topContentEndWidthOffset,topEndHeight));
|
||||
topContent.arcToPoint(Offset(size.width - topContentStartWidthOffset,topStartHeight), radius: Radius.circular(hourglassCurve),clockwise: false);
|
||||
topContent.close();
|
||||
|
||||
final bottomContent = Path();
|
||||
double bottomStartHeight = size.height-hourglassInset;
|
||||
double bottomEndHeight = size.height * (0.95 - (fillAmount * 0.32));
|
||||
double bottomContentStartWidthOffset = getBottomContentWidthOffset(size.width, bottomStartHeight, hourglassHalfHeight, hourglassInset);
|
||||
double bottomContentEndWidthOffset = getBottomContentWidthOffset(size.width, bottomEndHeight, hourglassHalfHeight, hourglassInset);
|
||||
// double contentWidthOffset = (((size.width /2) - hourglassInset) * sin((endHeight/hourglassHalfHeight) * (pi/6)));
|
||||
|
||||
bottomContent.moveTo(bottomContentStartWidthOffset,bottomStartHeight);
|
||||
bottomContent.arcToPoint(Offset(hourglassInset+ bottomContentEndWidthOffset,bottomEndHeight), radius: Radius.circular(hourglassCurve),clockwise: true);
|
||||
bottomContent.arcToPoint(Offset(size.width/2,bottomEndHeight-size.height*0.02),);
|
||||
bottomContent.arcToPoint(Offset((size.width - hourglassInset)-bottomContentEndWidthOffset,bottomEndHeight));
|
||||
bottomContent.arcToPoint(Offset(size.width - bottomContentStartWidthOffset,bottomStartHeight), radius: Radius.circular(hourglassCurve),clockwise: true);
|
||||
bottomContent.close();
|
||||
|
||||
final fallingSand = Path();
|
||||
fallingSand.moveTo(size.width*0.4,(size.height*0.48));
|
||||
fallingSand.arcToPoint(Offset(size.width*0.495,(size.height*0.57)));
|
||||
fallingSand.lineTo(size.width*0.48,size.height -hourglassInset);
|
||||
fallingSand.lineTo(size.width*0.52,size.height -hourglassInset);
|
||||
fallingSand.arcToPoint(Offset(size.width*0.505,(size.height*0.57)));
|
||||
fallingSand.arcToPoint(Offset(size.width*0.6,(size.height*0.48)));
|
||||
fallingSand.close();
|
||||
|
||||
final gradient = ui.Gradient.linear(
|
||||
Offset(size.width/2, bottomStartHeight),
|
||||
Offset(size.width/2, bottomEndHeight),
|
||||
colors,
|
||||
colorStops);
|
||||
|
||||
final bottomContentPainter = Paint()
|
||||
..shader=gradient
|
||||
..style=PaintingStyle.fill
|
||||
..strokeCap=StrokeCap.round
|
||||
..strokeWidth=1;
|
||||
|
||||
|
||||
canvas.drawPath(fallingSand, contentPainter);
|
||||
canvas.drawPath(topContent, contentPainter);
|
||||
canvas.drawPath(bottomContent, bottomContentPainter);
|
||||
canvas.drawPath(outline, outlinePainter);
|
||||
canvas.drawLine(Offset(0,0),Offset(size.width,0),outlinePainter);
|
||||
canvas.drawLine(Offset(0,size.height),Offset(size.width,size.height),outlinePainter);
|
||||
}
|
||||
|
||||
double getTopContentWidthOffset(double width,double height,double fullHeight, double inset){
|
||||
return (((width /2) - inset) * sin((height/fullHeight) * (pi/3.8)));
|
||||
}
|
||||
double getBottomContentWidthOffset(double width,double height,double fullHeight, double inset){
|
||||
return (((width /2) - inset) * sin(1-((height/fullHeight) * (pi/8.9))));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
bool shouldRepaint(covariant CustomPainter oldDelegate) {
|
||||
return true;
|
||||
//throw UnimplementedError();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user