curve 查看器

This commit is contained in:
toly
2021-07-08 17:17:02 +08:00
parent ca81162e51
commit e07df72ece
5 changed files with 279 additions and 12 deletions

View File

@@ -0,0 +1,4 @@
#storePassword=toly1994
#keyPassword=toly1994328
#keyAlias= king
#storeFile=/Users/mac/Coder/files/key/toly1994.jks

View File

@@ -73,7 +73,7 @@ class AnimPainter extends CustomPainter {
if(points.values.length>0){
canvas.drawLine(Offset(0, -points.values.last*step*10), Offset(280, -points.values.last*step*10), Paint()..color=Colors.purple);
canvas.drawCircle(Offset(240, -points.values.last*step*10), 10, Paint()..color=Colors.orange);
canvas.drawCircle(Offset(230, -points.values.last*step*10), 10, Paint()..color=Colors.orange);
}
Path scalePath = Path();

View File

@@ -1,6 +1,7 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_unit/views/components/drop_selectable_widget.dart';
import 'anim_painter.dart';
import 'point_data.dart';
@@ -22,6 +23,50 @@ class _CurveAnimShowerState extends State<CurveAnimShower>
Animation<double> curveAnim;
Map<String, Curve> maps = {
'bounceOut': Curves.bounceOut,
'linear': Curves.linear,
'decelerate': Curves.decelerate,
'fastLinearToSlowEaseIn': Curves.fastLinearToSlowEaseIn,
'ease': Curves.ease,
'easeIn': Curves.easeIn,
'easeInToLinear': Curves.easeInToLinear,
'easeInSine': Curves.easeInSine,
'easeInQuad': Curves.easeInQuad,
'easeInCubic': Curves.easeInCubic,
'easeInQuart': Curves.easeInQuart,
'easeInQuint': Curves.easeInQuint,
'easeInExpo': Curves.easeInExpo,
'easeInCirc': Curves.easeInCirc,
'easeInBack': Curves.easeInBack,
'easeOut': Curves.easeOut,
'linearToEaseOut': Curves.linearToEaseOut,
'easeOutSine': Curves.easeOutSine,
'easeOutQuad': Curves.easeOutQuad,
'easeOutCubic': Curves.easeOutCubic,
'easeOutQuart': Curves.easeOutQuart,
'easeOutQuint': Curves.easeOutQuint,
'easeOutExpo': Curves.easeOutExpo,
'easeOutCirc': Curves.easeOutCirc,
'easeOutBack': Curves.easeOutBack,
'easeInOut': Curves.easeInOut,
'easeInOutSine': Curves.easeInOutSine,
'easeInOutQuad': Curves.easeInOutQuad,
'easeInOutCubic': Curves.easeInOutCubic,
'easeInOutQuart': Curves.easeInOutQuart,
'easeInOutExpo': Curves.easeInOutExpo,
'easeInOutQuint': Curves.easeInOutQuint,
'easeInOutCirc': Curves.easeInOutCirc,
'easeInOutBack': Curves.easeInOutBack,
'fastOutSlowIn': Curves.fastOutSlowIn,
'slowMiddle': Curves.slowMiddle,
'bounceIn': Curves.bounceIn,
'bounceInOut': Curves.bounceInOut,
'elasticIn': Curves.elasticIn,
'elasticOut': Curves.elasticOut,
'elasticInOut': Curves.elasticInOut,
};
@override
void initState() {
super.initState();
@@ -52,15 +97,35 @@ class _CurveAnimShowerState extends State<CurveAnimShower>
Widget build(BuildContext context) {
return GestureDetector(
onTap: _startAnim,
child: Padding(
padding: const EdgeInsets.all(30.0),
child: CustomPaint(
painter: AnimPainter(points),
size: const Size(
200,
200,
),
),
child: Stack(
alignment: Alignment.center,
children: [
Positioned(
right: 5,
top: 5,
child: DropSelectableWidget(
fontSize: 12,
data: maps.keys.toList(),
iconSize: 20,
height: 25,
width: 180,
disableColor: Color(0xff1F425F),
onDropSelected: (int index) async {
curveAnim = CurvedAnimation(
parent: _ctrl, curve: maps.values.toList()[index]);
_startAnim();
},
)),
Padding(
padding: const EdgeInsets.all(30.0),
child: CustomPaint(
painter: AnimPainter(points),
size: const Size(
200,
200,
),
)),
],
),
);
}

View File

@@ -23,8 +23,7 @@ class _DrawPathState extends State<DrawPath> with SingleTickerProviderStateMixin
_controller = AnimationController(
duration: const Duration(seconds: 15),
vsync: this,
)..repeat()
;
)..repeat();
}
@override

View File

@@ -0,0 +1,199 @@
import 'dart:math';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
typedef OnDropSelected = void Function(int index);
class DropSelectableWidget extends StatefulWidget {
final List<String> data;
final OnDropSelected onDropSelected;
final Color disableColor;
final double iconSize;
final double height;
final double width;
final double fontSize;
const DropSelectableWidget(
{Key key,
this.data = const [],
this.onDropSelected,
this.disableColor = Colors.black,
this.iconSize = 24,
this.height = 30,
this.width = 200,
this.fontSize = 14,
})
: super(key: key);
@override
_DropSelectableWidgetState createState() => _DropSelectableWidgetState();
}
class _DropSelectableWidgetState extends State<DropSelectableWidget>
with SingleTickerProviderStateMixin {
FocusNode _node;
bool _focused = false;
FocusAttachment _nodeAttachment;
Color _color = Colors.white;
OverlayEntry _overlayEntry;
AnimationController _ctrl;
Animation<double> animation;
final LayerLink layerLink = LayerLink();
int _selectedIndex = 0;
@override
void initState() {
super.initState();
_ctrl = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 200),
);
animation = Tween<double>(begin: 0, end: pi).animate(_ctrl);
_node = FocusNode()
..addListener(() {
if (_node.hasFocus != _focused) {
if (!_focused) {
_ctrl.forward();
_showOverlay();
} else {
_hideOverlay();
_ctrl.reverse();
}
setState(() {
_focused = _node.hasFocus;
});
}
});
_nodeAttachment = _node.attach(context);
}
@override
void dispose() {
_node.dispose();
_ctrl.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
_nodeAttachment.reparent();
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
if (_focused) {
_node.unfocus();
} else {
_node.requestFocus();
}
},
child: CompositedTransformTarget(
link: layerLink,
child: buildTarget(),
),
);
}
void _showOverlay() {
_overlayEntry = _createOverlayEntry();
Overlay.of(context).insert(_overlayEntry);
}
void _hideOverlay() {
_overlayEntry?.remove();
}
Widget buildTarget() {
return Container(
width: widget.width,
height: widget.height,
padding: EdgeInsets.only(left: 10, right: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
border: Border.all(
color: _focused ? Colors.blue : widget.disableColor,
)),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'${widget.data.isNotEmpty ? widget.data[_selectedIndex] : "暂无数据"}',style: TextStyle(
height: 1,
fontSize: widget.fontSize
),),
AnimatedBuilder(
animation: animation,
builder: (_, child) => Transform.rotate(
angle: animation.value,
child: child,
),
child: Icon(
Icons.keyboard_arrow_down,
size: widget.iconSize,
),
),
],
),
);
}
OverlayEntry _createOverlayEntry() => OverlayEntry(
builder: (BuildContext context) => UnconstrainedBox(
child: CompositedTransformFollower(
link: layerLink,
targetAnchor: Alignment.bottomCenter,
followerAnchor: Alignment.topCenter,
child: Padding(
padding: const EdgeInsets.only(top: 4.0),
child: Material(
shape: RoundedRectangleBorder(
side: BorderSide.none,
borderRadius: BorderRadius.all(Radius.circular(5))),
elevation: 1,
child: ClipRRect(
borderRadius: BorderRadius.circular(5),
child: Container(
height: 200,
// alignment: Alignment.center,
decoration: BoxDecoration(
color: Color(0xffDAE3FF),
),
// padding: const EdgeInsets.only(top: 5),
width: widget.width,
child: CupertinoScrollbar(
child: ListView.builder(
padding: EdgeInsets.zero,
// shrinkWrap: true,
itemCount: widget.data.length,
itemBuilder: _buildItem),
),
),
),
),
),
),
),
);
Widget _buildItem(BuildContext context, int index) {
return Material(
child: InkWell(
onTap: () {
if (_selectedIndex != index) widget.onDropSelected?.call(index);
_selectedIndex = index;
_overlayEntry.markNeedsBuild();
_node.unfocus();
},
child: Container(
padding: EdgeInsets.all(8),
color: index == _selectedIndex
? Colors.blue.withOpacity(0.2)
: Colors.transparent,
child: Text('${widget.data[index]}',style: TextStyle(fontSize: widget.fontSize),)),
),
);
}
}