feat(player): 重做播放页信息层级与互动栏点击动效
This commit is contained in:
1 parent
aed9ee2b01
commit
fd2ba0bf43
15 files changed
+2074
-551
No files matched your search
@@ -0,0 +1,88 @@
|
||||
// Author: fruit.com.cn
|
||||
// 职责:绘制收藏点赞周围的紧凑双向短线,无圆环或阴影,不参与手势。
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
const int _rayCount = 8;
|
||||
const double _startProgress = 0.1;
|
||||
const double _radiusStart = 0.34;
|
||||
const double _radiusTravel = 0.14;
|
||||
const double _rayLength = 0.07;
|
||||
const double _strokeFraction = 0.025;
|
||||
const double _rayAlpha = 0.65;
|
||||
const double _fullCircle = math.pi * 2;
|
||||
const double _rayRotation = math.pi / _rayCount;
|
||||
|
||||
/// 收藏/点赞的装饰反馈:选中外扩,取消收束。
|
||||
class RailTapBurst extends StatelessWidget {
|
||||
/// [progress] 来自按钮的点击动画,不创建独立计时器。
|
||||
const RailTapBurst({
|
||||
super.key,
|
||||
required this.progress,
|
||||
required this.color,
|
||||
required this.contracting,
|
||||
});
|
||||
|
||||
final double progress;
|
||||
final Color color;
|
||||
final bool contracting;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => IgnorePointer(
|
||||
child: CustomPaint(
|
||||
painter: _RailBurstPainter(
|
||||
progress: progress,
|
||||
color: color,
|
||||
contracting: contracting,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
class _RailBurstPainter extends CustomPainter {
|
||||
const _RailBurstPainter({
|
||||
required this.progress,
|
||||
required this.color,
|
||||
required this.contracting,
|
||||
});
|
||||
|
||||
final double progress;
|
||||
final Color color;
|
||||
final bool contracting;
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final phase = ((progress - _startProgress) / (1 - _startProgress)).clamp(
|
||||
0.0,
|
||||
1.0,
|
||||
);
|
||||
if (phase == 0 || phase == 1) return;
|
||||
final eased = Curves.easeOutCubic.transform(phase);
|
||||
final travel = contracting ? 1 - eased : eased;
|
||||
final base = size.shortestSide;
|
||||
final radius = base * (_radiusStart + _radiusTravel * travel);
|
||||
final alpha = math.sin(math.pi * phase);
|
||||
final paint = Paint()
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeCap = StrokeCap.round
|
||||
..strokeWidth = base * _strokeFraction
|
||||
..color = color.withValues(alpha: alpha * _rayAlpha);
|
||||
final center = size.center(Offset.zero);
|
||||
final length = base * _rayLength * (1 - phase);
|
||||
for (var index = 0; index < _rayCount; index++) {
|
||||
final angle = _fullCircle * index / _rayCount + _rayRotation;
|
||||
canvas.drawLine(
|
||||
center + Offset.fromDirection(angle, radius),
|
||||
center + Offset.fromDirection(angle, radius + length),
|
||||
paint,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(covariant _RailBurstPainter oldDelegate) =>
|
||||
oldDelegate.progress != progress ||
|
||||
oldDelegate.color != color ||
|
||||
oldDelegate.contracting != contracting;
|
||||
}
|
||||
Reference in new issue
Block a user