Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-01-20 17:42:40 +08:00
parent 923af32c96
commit 0b1f6c4d0e
26 changed files with 377 additions and 451 deletions

View File

@@ -7,21 +7,21 @@ class Arc extends LeafRenderObjectWidget {
super.key,
required this.size,
required this.color,
required this.sweepAngle,
required this.progress,
this.strokeWidth = 2,
});
final double size;
final Color color;
final double sweepAngle;
final double progress;
final double strokeWidth;
@override
RenderObject createRenderObject(BuildContext context) {
return RenderArc(
size: size,
preferredSize: size,
color: color,
sweepAngle: sweepAngle,
progress: progress,
strokeWidth: strokeWidth,
);
}
@@ -32,21 +32,22 @@ class Arc extends LeafRenderObjectWidget {
RenderArc renderObject,
) {
renderObject
..preferredSize = size
..color = color
..sweepAngle = sweepAngle
..progress = progress
..strokeWidth = strokeWidth;
}
}
class RenderArc extends RenderBox {
RenderArc({
required double size,
required double preferredSize,
required Color color,
required double sweepAngle,
required double progress,
required double strokeWidth,
}) : _preferredSize = Size.square(size),
}) : _preferredSize = preferredSize,
_color = color,
_sweepAngle = sweepAngle,
_progress = progress,
_strokeWidth = strokeWidth;
Color _color;
@@ -57,11 +58,11 @@ class RenderArc extends RenderBox {
markNeedsPaint();
}
double _sweepAngle;
double get sweepAngle => _sweepAngle;
set sweepAngle(double value) {
if (_sweepAngle == value) return;
_sweepAngle = value;
double _progress;
double get progress => _progress;
set progress(double value) {
if (_progress == value) return;
_progress = value;
markNeedsPaint();
}
@@ -73,8 +74,9 @@ class RenderArc extends RenderBox {
markNeedsPaint();
}
Size _preferredSize;
set preferredSize(Size value) {
double _preferredSize;
double get preferredSize => _preferredSize;
set preferredSize(double value) {
if (_preferredSize == value) return;
_preferredSize = value;
markNeedsLayout();
@@ -82,12 +84,12 @@ class RenderArc extends RenderBox {
@override
void performLayout() {
size = constraints.constrain(_preferredSize);
size = constraints.constrainDimensions(_preferredSize, _preferredSize);
}
@override
void paint(PaintingContext context, Offset offset) {
if (sweepAngle == 0) {
if (progress == 0) {
return;
}
@@ -96,15 +98,14 @@ class RenderArc extends RenderBox {
..strokeWidth = strokeWidth
..style = PaintingStyle.stroke;
final size = this.size;
final radius = size.width / 2;
final rect = Rect.fromCircle(
center: Offset(size.width / 2, size.height / 2),
radius: size.width / 2,
center: Offset(radius, radius),
radius: radius,
);
const startAngle = -pi / 2;
context.canvas.drawArc(rect, startAngle, sweepAngle, false, paint);
context.canvas.drawArc(rect, startAngle, progress * 2 * pi, false, paint);
}
@override

View File

@@ -7,14 +7,18 @@ class DisabledIcon<T extends Widget> extends SingleChildRenderObjectWidget {
const DisabledIcon({
super.key,
required T child,
this.disable = false,
this.color,
this.iconSize,
double? lineLengthScale,
StrokeCap? strokeCap,
}) : lineLengthScale = lineLengthScale ?? 0.9,
strokeCap = strokeCap ?? StrokeCap.butt,
super(child: child);
final bool disable;
final Color? color;
final double? iconSize;
final StrokeCap strokeCap;
final double lineLengthScale;
@@ -22,12 +26,18 @@ class DisabledIcon<T extends Widget> extends SingleChildRenderObjectWidget {
@override
RenderObject createRenderObject(BuildContext context) {
late final iconTheme = IconTheme.of(context);
return RenderMaskedIcon(
disable: disable,
iconSize:
iconSize ??
(child is Icon ? (child as Icon?)?.size : null) ??
iconTheme.size ??
24.0,
color:
color ??
(child is Icon
? (child as Icon).color ?? IconTheme.of(context).color!
: IconTheme.of(context).color!),
(child is Icon ? (child as Icon?)?.color : null) ??
iconTheme.color!,
strokeCap: strokeCap,
lineLengthScale: lineLengthScale,
);
@@ -35,12 +45,18 @@ class DisabledIcon<T extends Widget> extends SingleChildRenderObjectWidget {
@override
void updateRenderObject(BuildContext context, RenderMaskedIcon renderObject) {
late final iconTheme = IconTheme.of(context);
renderObject
..disable = disable
..iconSize =
iconSize ??
(child is Icon ? (child as Icon?)?.size : null) ??
iconTheme.size ??
24.0
..color =
color ??
(child is Icon
? (child as Icon).color ?? IconTheme.of(context).color!
: IconTheme.of(context).color!)
(child is Icon ? (child as Icon?)?.color : null) ??
iconTheme.color!
..strokeCap = strokeCap
..lineLengthScale = lineLengthScale;
}
@@ -48,13 +64,33 @@ class DisabledIcon<T extends Widget> extends SingleChildRenderObjectWidget {
class RenderMaskedIcon extends RenderProxyBox {
RenderMaskedIcon({
required bool disable,
required double iconSize,
required Color color,
required StrokeCap strokeCap,
required double lineLengthScale,
}) : _color = color,
}) : _disable = disable,
_iconSize = iconSize,
_color = color,
_strokeCap = strokeCap,
_lineLengthScale = lineLengthScale;
bool _disable;
bool get disable => _disable;
set disable(bool value) {
if (_disable == value) return;
_disable = value;
markNeedsPaint();
}
double _iconSize;
double get iconSize => _iconSize;
set iconSize(double value) {
if (_iconSize == value) return;
_iconSize = value;
markNeedsPaint();
}
Color _color;
Color get color => _color;
set color(Color value) {
@@ -81,23 +117,30 @@ class RenderMaskedIcon extends RenderProxyBox {
@override
void paint(PaintingContext context, Offset offset) {
final strokeWidth = size.width / 12;
if (!disable) {
return super.paint(context, offset);
}
final canvas = context.canvas;
Size size = this.size;
final exceedWidth = size.width > _iconSize;
final exceedHeight = size.height > _iconSize;
if (exceedWidth || exceedHeight) {
final dx = exceedWidth ? (size.width - _iconSize) / 2.0 : 0.0;
final dy = exceedHeight ? (size.height - _iconSize) / 2.0 : 0.0;
size = Size.square(_iconSize);
offset = Offset(dx, dy);
} else if (size.width < _iconSize && size.height < _iconSize) {
size = Size.square(_iconSize);
}
final strokeWidth = size.width / 12;
var rect = offset & size;
final sqrt2Width = strokeWidth * sqrt2; // rotate pi / 4
// final path = Path.combine(
// PathOperation.difference,
// Path()..addRect(rect),
// Path()..moveTo(rect.left, rect.top)
// ..relativeLineTo(sqrt2Width, 0)
// ..lineTo(rect.right, rect.bottom - sqrt2Width)
// ..lineTo(rect.right, rect.bottom)
// ..close(),
// );
final path = Path.combine(
PathOperation.union,
Path() // bottom
@@ -114,7 +157,7 @@ class RenderMaskedIcon extends RenderProxyBox {
canvas
..save()
..clipPath(path, doAntiAlias: false);
super.paint(context, offset);
super.paint(context, .zero);
canvas.restore();
@@ -137,8 +180,3 @@ class RenderMaskedIcon extends RenderProxyBox {
@override
bool get isRepaintBoundary => true;
}
extension DisabledIconExt on Icon {
DisabledIcon<Icon> disable([double? lineLengthScale]) =>
DisabledIcon(lineLengthScale: lineLengthScale, child: this);
}

View File

@@ -81,9 +81,7 @@ class _MouseInteractiveViewerState extends State<MouseInteractiveViewer>
final GlobalKey _parentKey = GlobalKey();
Animation<Offset>? _animation;
CurvedAnimation? _curvedAnimation;
Animation<double>? _scaleAnimation;
CurvedAnimation? _curvedScaleAnimation;
late Offset _scaleAnimationFocalPoint;
late AnimationController _controller;
late AnimationController _scaleController;
@@ -435,20 +433,15 @@ class _MouseInteractiveViewerState extends State<MouseInteractiveViewer>
details.velocity.pixelsPerSecond.distance,
widget.interactionEndFrictionCoefficient,
);
_animation =
Tween<Offset>(
begin: translation,
end: Offset(
frictionSimulationX.finalX,
frictionSimulationY.finalX,
),
).animate(
_curvedAnimation ??= CurvedAnimation(
parent: _controller,
curve: Curves.decelerate,
),
)
..addListener(_handleInertiaAnimation);
_animation = _controller.drive(
Tween<Offset>(
begin: translation,
end: Offset(
frictionSimulationX.finalX,
frictionSimulationY.finalX,
),
).chain(CurveTween(curve: Curves.decelerate)),
)..addListener(_handleInertiaAnimation);
_controller
..duration = Duration(milliseconds: (tFinal * 1000).round())
..forward();
@@ -468,17 +461,12 @@ class _MouseInteractiveViewerState extends State<MouseInteractiveViewer>
widget.interactionEndFrictionCoefficient,
effectivelyMotionless: 0.1,
);
_scaleAnimation =
Tween<double>(
begin: scale,
end: frictionSimulation.x(tFinal),
).animate(
_curvedScaleAnimation ??= CurvedAnimation(
parent: _scaleController,
curve: Curves.decelerate,
),
)
..addListener(_handleScaleAnimation);
_scaleAnimation = _scaleController.drive(
Tween<double>(
begin: scale,
end: frictionSimulation.x(tFinal),
).chain(CurveTween(curve: Curves.decelerate)),
)..addListener(_handleScaleAnimation);
_scaleController
..duration = Duration(milliseconds: (tFinal * 1000).round())
..forward();
@@ -732,9 +720,7 @@ class _MouseInteractiveViewerState extends State<MouseInteractiveViewer>
@override
void dispose() {
_scaleGestureRecognizer.dispose();
_curvedAnimation?.dispose();
_controller.dispose();
_curvedScaleAnimation?.dispose();
_scaleController.dispose();
_transformer.removeListener(_handleTransformation);
if (widget.transformationController == null) {

View File

@@ -31,18 +31,6 @@ class HeroDialogRoute<T> extends PageRoute<T> {
@override
Color? get barrierColor => null;
CurvedAnimation? _curvedAnimation;
void _setAnimation(Animation<double> animation) {
if (_curvedAnimation?.parent != animation) {
_curvedAnimation?.dispose();
_curvedAnimation = CurvedAnimation(
parent: animation,
curve: Curves.easeOut,
);
}
}
@override
Widget buildTransitions(
BuildContext context,
@@ -50,19 +38,12 @@ class HeroDialogRoute<T> extends PageRoute<T> {
Animation<double> secondaryAnimation,
Widget child,
) {
_setAnimation(animation);
return FadeTransition(
opacity: _curvedAnimation!,
opacity: animation.drive(CurveTween(curve: Curves.easeOut)),
child: child,
);
}
@override
void dispose() {
_curvedAnimation?.dispose();
super.dispose();
}
@override
Widget buildPage(
BuildContext context,

View File

@@ -503,9 +503,7 @@ class _InteractiveViewerState extends State<InteractiveViewer>
final GlobalKey _childKey = GlobalKey();
final GlobalKey _parentKey = GlobalKey();
Animation<Offset>? _animation;
CurvedAnimation? _curvedAnimation;
Animation<double>? _scaleAnimation;
CurvedAnimation? _curvedScaleAnimation;
late Offset _scaleAnimationFocalPoint;
late AnimationController _controller;
late AnimationController _scaleController;
@@ -924,19 +922,15 @@ class _InteractiveViewerState extends State<InteractiveViewer>
details.velocity.pixelsPerSecond.distance,
widget.interactionEndFrictionCoefficient,
);
_animation =
Tween<Offset>(
begin: translation,
end: Offset(
frictionSimulationX.finalX,
frictionSimulationY.finalX,
),
).animate(
_curvedAnimation ??= CurvedAnimation(
parent: _controller,
curve: Curves.decelerate,
),
);
_animation = _controller.drive(
Tween<Offset>(
begin: translation,
end: Offset(
frictionSimulationX.finalX,
frictionSimulationY.finalX,
),
).chain(CurveTween(curve: Curves.decelerate)),
);
_controller.duration = Duration(milliseconds: (tFinal * 1000).round());
_animation!.addListener(_handleInertiaAnimation);
_controller.forward();
@@ -956,16 +950,12 @@ class _InteractiveViewerState extends State<InteractiveViewer>
widget.interactionEndFrictionCoefficient,
effectivelyMotionless: 0.1,
);
_scaleAnimation =
Tween<double>(
begin: scale,
end: frictionSimulation.x(tFinal),
).animate(
_curvedScaleAnimation ??= CurvedAnimation(
parent: _scaleController,
curve: Curves.decelerate,
),
);
_scaleAnimation = _scaleController.drive(
Tween<double>(
begin: scale,
end: frictionSimulation.x(tFinal),
).chain(CurveTween(curve: Curves.decelerate)),
);
_scaleController.duration = Duration(
milliseconds: (tFinal * 1000).round(),
);
@@ -1155,9 +1145,7 @@ class _InteractiveViewerState extends State<InteractiveViewer>
@override
void dispose() {
_curvedAnimation?.dispose();
_controller.dispose();
_curvedScaleAnimation?.dispose();
_scaleController.dispose();
_transformer.removeListener(_handleTransformation);
if (widget.transformationController == null) {

View File

@@ -114,7 +114,7 @@ class InteractiveViewerBoundaryState extends State<InteractiveViewerBoundary>
_scaleAnimation = _animateController.drive(
Tween<double>(
begin: 1,
begin: 1.0,
end: 0.25,
),
);

View File

@@ -207,13 +207,12 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
if (_transformationController.value != Matrix4.identity()) {
// animate the reset for the transformation of the interactive viewer
_animation =
Matrix4Tween(
begin: _transformationController.value,
end: Matrix4.identity(),
).animate(
CurveTween(curve: Curves.easeOut).animate(_animationController),
);
_animation = _animationController.drive(
Matrix4Tween(
begin: _transformationController.value,
end: Matrix4.identity(),
).chain(CurveTween(curve: Curves.easeOut)),
);
_animationController.forward(from: 0);
}
@@ -401,13 +400,12 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
matrix.row3.w,
]);
_animation =
Matrix4Tween(
begin: _transformationController.value,
end: matrix,
).animate(
CurveTween(curve: Curves.easeOut).animate(_animationController),
);
_animation = _animationController.drive(
Matrix4Tween(
begin: _transformationController.value,
end: matrix,
).chain(CurveTween(curve: Curves.easeOut)),
);
_animationController
.forward(from: 0)
.whenComplete(() => _onScaleChanged(targetScale));

View File

@@ -1,5 +1,3 @@
import 'dart:math';
import 'package:PiliPlus/common/widgets/custom_arc.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
@@ -35,7 +33,7 @@ class LoadingWidget extends StatelessWidget {
size: 40,
color: onSurfaceVariant,
strokeWidth: 3,
sweepAngle: progress.value * 2 * pi,
progress: progress.value,
),
),
//msg

View File

@@ -10,14 +10,7 @@ import 'package:flutter/services.dart'
PointerEnterEventListener,
PointerExitEventListener;
/// The shape of the progress bar at the left and right ends.
enum BarCapShape {
/// The left and right ends of the bar are round.
round,
/// The left and right ends of the bar are square.
square,
}
/// https://github.com/suragch/audio_video_progress_bar
/// A progress bar widget to show or set the location of the currently
/// playing audio or video content.
@@ -36,7 +29,7 @@ class ProgressBar extends LeafRenderObjectWidget {
super.key,
required this.progress,
required this.total,
this.buffered,
this.buffered = .zero,
this.onSeek,
this.onDragStart,
this.onDragUpdate,
@@ -45,7 +38,6 @@ class ProgressBar extends LeafRenderObjectWidget {
required this.baseBarColor,
required this.progressBarColor,
required this.bufferedBarColor,
this.barCapShape = BarCapShape.round,
this.thumbRadius = 10.0,
required this.thumbColor,
required this.thumbGlowColor,
@@ -65,7 +57,7 @@ class ProgressBar extends LeafRenderObjectWidget {
///
/// This is useful for streamed content. If you are playing a local file
/// then you can leave this out.
final Duration? buffered;
final Duration buffered;
/// A callback when user moves the thumb.
///
@@ -142,12 +134,6 @@ class ProgressBar extends LeafRenderObjectWidget {
/// a shade darker than [baseBarColor].
final Color bufferedBarColor;
/// The shape of the bar at the left and right ends.
///
/// This affects the base bar for the total time, the current progress bar,
/// and the buffered progress bar. The default is [BarCapShape.round].
final BarCapShape barCapShape;
/// The radius of the circle for the moveable progress bar thumb.
final double thumbRadius;
@@ -189,7 +175,7 @@ class ProgressBar extends LeafRenderObjectWidget {
return RenderProgressBar(
progress: progress,
total: total,
buffered: buffered ?? Duration.zero,
buffered: buffered,
onSeek: onSeek,
onDragStart: onDragStart,
onDragUpdate: onDragUpdate,
@@ -198,7 +184,6 @@ class ProgressBar extends LeafRenderObjectWidget {
baseBarColor: baseBarColor,
progressBarColor: progressBarColor,
bufferedBarColor: bufferedBarColor,
barCapShape: barCapShape,
thumbRadius: thumbRadius,
thumbColor: thumbColor,
thumbGlowColor: thumbGlowColor,
@@ -215,7 +200,7 @@ class ProgressBar extends LeafRenderObjectWidget {
renderObject
..total = total
..progress = progress
..buffered = buffered ?? Duration.zero
..buffered = buffered
..onSeek = onSeek
..onDragStart = onDragStart
..onDragUpdate = onDragUpdate
@@ -224,7 +209,6 @@ class ProgressBar extends LeafRenderObjectWidget {
..baseBarColor = baseBarColor
..progressBarColor = progressBarColor
..bufferedBarColor = bufferedBarColor
..barCapShape = barCapShape
..thumbRadius = thumbRadius
..thumbColor = thumbColor
..thumbGlowColor = thumbGlowColor
@@ -271,7 +255,6 @@ class ProgressBar extends LeafRenderObjectWidget {
..add(ColorProperty('baseBarColor', baseBarColor))
..add(ColorProperty('progressBarColor', progressBarColor))
..add(ColorProperty('bufferedBarColor', bufferedBarColor))
..add(StringProperty('barCapShape', barCapShape.toString()))
..add(DoubleProperty('thumbRadius', thumbRadius))
..add(ColorProperty('thumbColor', thumbColor))
..add(ColorProperty('thumbGlowColor', thumbGlowColor))
@@ -348,7 +331,6 @@ class RenderProgressBar extends RenderBox implements MouseTrackerAnnotation {
required Color baseBarColor,
required Color progressBarColor,
required Color bufferedBarColor,
required BarCapShape barCapShape,
double thumbRadius = 20.0,
required Color thumbColor,
required Color thumbGlowColor,
@@ -364,7 +346,6 @@ class RenderProgressBar extends RenderBox implements MouseTrackerAnnotation {
_baseBarColor = baseBarColor,
_progressBarColor = progressBarColor,
_bufferedBarColor = bufferedBarColor,
_barCapShape = barCapShape,
_thumbRadius = thumbRadius,
_thumbColor = thumbColor,
_thumbGlowColor = thumbGlowColor,
@@ -598,14 +579,6 @@ class RenderProgressBar extends RenderBox implements MouseTrackerAnnotation {
markNeedsPaint();
}
BarCapShape get barCapShape => _barCapShape;
BarCapShape _barCapShape;
set barCapShape(BarCapShape value) {
if (_barCapShape == value) return;
_barCapShape = value;
markNeedsPaint();
}
/// The color of the moveable thumb.
Color get thumbColor => _thumbColor;
Color _thumbColor;
@@ -765,12 +738,9 @@ class RenderProgressBar extends RenderBox implements MouseTrackerAnnotation {
required double widthProportion,
required Color color,
}) {
final strokeCap = (_barCapShape == BarCapShape.round)
? StrokeCap.round
: StrokeCap.square;
final baseBarPaint = Paint()
..color = color
..strokeCap = strokeCap
..strokeCap = StrokeCap.round
..strokeWidth = _barHeight;
final capRadius = _barHeight / 2;
final adjustedWidth = availableSize.width - barHeight;