Created
February 17, 2020 09:48
-
-
Save JoseAlba/58e5e12bb29370bbca75f19e2685387a to your computer and use it in GitHub Desktop.
CompositedTransformTarget, CompositedTransformFollower, and LayerLink math example
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
import 'dart:math' as math; | |
import 'package:flutter/material.dart'; | |
void main() { | |
runApp(MaterialApp(home: Slide())); | |
} | |
class Indicator extends StatelessWidget { | |
Indicator({ Key key, this.link, this.offset }) : super(key: key); | |
final LayerLink link; | |
final Offset offset; | |
@override | |
Widget build(BuildContext context) { | |
return CompositedTransformFollower( | |
offset: offset, | |
link: link, | |
child: Container( | |
color: Colors.green, | |
), | |
); | |
} | |
} | |
class Slide extends StatefulWidget { | |
Slide({ Key key }) : super(key: key); | |
@override | |
_SlideState createState() => _SlideState(); | |
} | |
class _SlideState extends State<Slide> { | |
final double indicatorWidth = 24.0; | |
final double indicatorHeight = 300.0; | |
final double slideHeight = 200.0; | |
final double slideWidth = 400.0; | |
final LayerLink layerLink = LayerLink(); | |
OverlayEntry overlayEntry; | |
Offset indicatorOffset; | |
Offset getIndicatorOffset(Offset dragOffset) { | |
final double x = (dragOffset.dx - (indicatorWidth / 2.0)).clamp(0.0, slideWidth - indicatorWidth); | |
final double y = (slideHeight - indicatorHeight) / 2.0; | |
return Offset(x, y); | |
} | |
void showIndicator(DragStartDetails details) { | |
indicatorOffset = getIndicatorOffset(details.localPosition); | |
overlayEntry = OverlayEntry( | |
builder: (BuildContext context) { | |
return Positioned( | |
top: 0.0, | |
left: 0.0, | |
child: SizedBox( | |
width: indicatorWidth, | |
height: indicatorHeight, | |
child: Indicator( | |
offset: indicatorOffset, | |
link: layerLink | |
), | |
), | |
); | |
}, | |
); | |
Overlay.of(context).insert(overlayEntry); | |
} | |
void updateIndicator(DragUpdateDetails details) { | |
indicatorOffset = getIndicatorOffset(details.localPosition); | |
overlayEntry.markNeedsBuild(); | |
} | |
void hideIndicator(DragEndDetails details) { | |
overlayEntry.remove(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar(title: const Text('Overlay Indicator')), | |
body: Transform.rotate( | |
angle: -math.pi / 12.0, | |
child: Center( | |
child: CompositedTransformTarget( | |
link: layerLink, | |
child: Container( | |
width: slideWidth, | |
height: slideHeight, | |
color: Colors.blue.withOpacity(0.2), | |
child: GestureDetector( | |
onPanStart: showIndicator, | |
onPanUpdate: updateIndicator, | |
onPanEnd: hideIndicator, | |
), | |
), | |
), | |
), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment