fix(player): 使用根Overlay承载飘心
This commit is contained in:
1 parent
db3e153409
commit
ed2cf4c18c
2 files changed
+71
-33
No files matched your search
@@ -123,47 +123,43 @@ class _PlayerDoubleTapHeartBurstState extends State<PlayerDoubleTapHeartBurst>
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return IgnorePointer(
|
return IgnorePointer(
|
||||||
child: SizedBox.shrink(
|
child: AnimatedBuilder(
|
||||||
child: AnimatedBuilder(
|
animation: _controller,
|
||||||
animation: _controller,
|
builder: (context, _) {
|
||||||
builder: (context, _) {
|
final elapsed =
|
||||||
final elapsed =
|
_controller.value * _controller.duration!.inMilliseconds;
|
||||||
_controller.value * _controller.duration!.inMilliseconds;
|
return Stack(
|
||||||
return Stack(
|
fit: StackFit.expand,
|
||||||
fit: StackFit.expand,
|
clipBehavior: Clip.none,
|
||||||
clipBehavior: Clip.none,
|
children: [
|
||||||
children: [
|
for (var index = 0; index < _hearts.length; index++)
|
||||||
for (var index = 0; index < _hearts.length; index++)
|
_heart(_hearts[index], elapsed, index),
|
||||||
_heart(_hearts[index], elapsed, index),
|
if (kDebugMode)
|
||||||
if (kDebugMode)
|
Positioned(
|
||||||
Positioned(
|
left: widget.origin.dx + 8,
|
||||||
left: widget.origin.dx + 8,
|
top: widget.origin.dy + 10,
|
||||||
top: widget.origin.dy,
|
child: IgnorePointer(
|
||||||
child: IgnorePointer(
|
child: Text(
|
||||||
child: Text(
|
'${elapsed.round()}ms',
|
||||||
'${elapsed.round()}ms',
|
key: const Key('heart-burst-elapsed-debug'),
|
||||||
key: const Key('heart-burst-elapsed-debug'),
|
style: const TextStyle(
|
||||||
style: const TextStyle(
|
color: Colors.white60,
|
||||||
color: Colors.white60,
|
fontSize: 11,
|
||||||
fontSize: 11,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
);
|
],
|
||||||
},
|
);
|
||||||
),
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _heart(_HeartParticle heart, double elapsed, int index) {
|
Widget _heart(_HeartParticle heart, double elapsed, int index) {
|
||||||
final progress = ((elapsed - heart.delay) / _heartDurationMs).clamp(
|
final rawProgress = (elapsed - heart.delay) / _heartDurationMs;
|
||||||
0.0,
|
if (rawProgress < 0) return const SizedBox.shrink();
|
||||||
1.0,
|
final progress = rawProgress.clamp(0.0, 1.0);
|
||||||
);
|
|
||||||
if (progress <= 0) return const SizedBox.shrink();
|
|
||||||
final move = Curves.easeOutCubic.transform(progress);
|
final move = Curves.easeOutCubic.transform(progress);
|
||||||
final scale = progress < _heartPopPortion
|
final scale = progress < _heartPopPortion
|
||||||
? _heartStartScale +
|
? _heartStartScale +
|
||||||
|
|||||||
@@ -57,6 +57,48 @@ void main() {
|
|||||||
expect(_opacity(tester, 0), lessThan(0.5));
|
expect(_opacity(tester, 0), lessThan(0.5));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('heart position is anchored to the overlay origin', (
|
||||||
|
tester,
|
||||||
|
) async {
|
||||||
|
const origin = Offset(300, 546);
|
||||||
|
await tester.pumpWidget(
|
||||||
|
const MaterialApp(
|
||||||
|
home: Scaffold(
|
||||||
|
body: Stack(
|
||||||
|
fit: StackFit.expand,
|
||||||
|
children: [
|
||||||
|
Positioned.fill(
|
||||||
|
child: PlayerDoubleTapHeartBurst(
|
||||||
|
burstId: 4,
|
||||||
|
origin: origin,
|
||||||
|
onCompleted: _noop,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final firstHeart = find.byKey(const Key('double-tap-heart-0'));
|
||||||
|
expect(
|
||||||
|
(tester.getCenter(firstHeart) - origin).distance,
|
||||||
|
lessThanOrEqualTo(1),
|
||||||
|
);
|
||||||
|
final debugTopLeft = tester.getTopLeft(
|
||||||
|
find.byKey(const Key('heart-burst-elapsed-debug')),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
(debugTopLeft - const Offset(308, 556)).distance,
|
||||||
|
lessThanOrEqualTo(1),
|
||||||
|
);
|
||||||
|
|
||||||
|
await tester.pump(const Duration(milliseconds: 750));
|
||||||
|
final midpoint = tester.getCenter(firstHeart);
|
||||||
|
expect(midpoint.dy, lessThan(origin.dy));
|
||||||
|
expect((midpoint.dx - origin.dx).abs(), lessThanOrEqualTo(1));
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('develop heart burst completes after about 1590ms', (
|
testWidgets('develop heart burst completes after about 1590ms', (
|
||||||
tester,
|
tester,
|
||||||
) async {
|
) async {
|
||||||
|
|||||||
Reference in new issue
Block a user