mirror of
https://github.com/alibaba/flutter-go.git
synced 2025-05-21 14:56:27 +08:00
feat(add 这些组件:1.canvas 2. cricleProgressBarPainter 3.PainterPath 4. PainterSketch): add 这些组件:1.canva
add 这些组件:1.canvas 2. cricleProgressBarPainter 3.PainterPath 4. PainterSketch
This commit is contained in:
BIN
assets/app.db
BIN
assets/app.db
Binary file not shown.
BIN
assets/images/painterImg.jpeg
Normal file
BIN
assets/images/painterImg.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 185 KiB |
@ -20,6 +20,7 @@ class _FullScreenCodeDialogState extends State<FullScreenCodeDialog> {
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
print('widget.filePath=======${widget.filePath}');
|
||||
getExampleCode(context,'${widget.filePath}', DefaultAssetBundle.of(context))
|
||||
.then<void>((String code) {
|
||||
if (mounted) {
|
||||
|
@ -78,6 +78,9 @@ class WidgetName2Icon {
|
||||
"IconData":Icons.date_range,
|
||||
"IconThemeData":Icons.insert_comment,
|
||||
"Canvas":Icons.edit,
|
||||
"PainterPath":Icons.gesture,
|
||||
"CircleProgressBarPainter":Icons.av_timer,
|
||||
"PainterSketch":Icons.touch_app,
|
||||
"Material":Icons.android,
|
||||
"MaterialApp":Icons.android,
|
||||
"MaterialButton":Icons.speaker,
|
||||
|
@ -59,6 +59,7 @@ class Provider {
|
||||
//Get a location using getDatabasesPath
|
||||
String databasesPath = await getDatabasesPath();
|
||||
String path = join(databasesPath, 'flutter.db');
|
||||
print(path);
|
||||
try {
|
||||
db = await openDatabase(path);
|
||||
} catch (e) {
|
||||
|
203
lib/widgets/elements/Media/Canvas/Canvas/demo.dart
Normal file
203
lib/widgets/elements/Media/Canvas/Canvas/demo.dart
Normal file
@ -0,0 +1,203 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2019/1/20
|
||||
* Time: 上午11:34
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: Canvas 的示例
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import 'dart:ui';
|
||||
import 'dart:ui' as ui;
|
||||
import 'dart:typed_data';
|
||||
import 'package:flutter/services.dart' show rootBundle;
|
||||
|
||||
CustomPaint graph;
|
||||
var image;
|
||||
|
||||
class CustomViewPage extends StatefulWidget {
|
||||
|
||||
final String type;
|
||||
CustomViewPage({this.type='drawLine'}) : super();
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => CustomViewPageState();
|
||||
}
|
||||
|
||||
class CustomViewPageState extends State<CustomViewPage>
|
||||
with SingleTickerProviderStateMixin {
|
||||
|
||||
static Future<ui.Image> getImage(String asset) async {
|
||||
ByteData data = await rootBundle.load(asset);
|
||||
Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List());
|
||||
FrameInfo fi = await codec.getNextFrame();
|
||||
return fi.image;
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
getImage("assets/images/painterImg.jpeg").then((data) {
|
||||
setState(() {
|
||||
image = data;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
graph = CustomPaint(
|
||||
painter: DrawPainter(type:widget.type)
|
||||
);
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
height: MediaQuery.of(context).size.width * 0.6,
|
||||
margin: EdgeInsets.all(10.0),
|
||||
//padding: EdgeInsets.all(10.0),
|
||||
child: graph
|
||||
//child:Center(child: graph)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
void reassemble() {
|
||||
super.reassemble();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
///新建类继承于CustomPainter并且实现CustomPainter里面的paint()和shouldRepaint方法
|
||||
class DrawPainter extends CustomPainter {
|
||||
Paint painter;
|
||||
final type;
|
||||
|
||||
DrawPainter ({this.type}){
|
||||
// Paint painter = Paint()
|
||||
// ..color = Colors.blueAccent //画笔颜色
|
||||
// ..strokeCap = StrokeCap.round //画笔笔触类型
|
||||
// ..isAntiAlias = true //是否启动抗锯齿
|
||||
// ..blendMode = BlendMode.exclusion //颜色混合模式
|
||||
// ..style = PaintingStyle.fill //绘画风格,默认为填充
|
||||
// ..colorFilter = ColorFilter.mode(Colors.blueAccent,BlendMode.exclusion) //颜色渲染模式,一般是矩阵效果来改变的,但是flutter中只能使用颜色混合模式
|
||||
// ..maskFilter = MaskFilter.blur(BlurStyle.inner, 3.0) //模糊遮罩效果,flutter中只有这个
|
||||
// ..filterQuality = FilterQuality.high //颜色渲染模式的质量
|
||||
// ..strokeWidth = 15.0 ;//画笔的宽度
|
||||
|
||||
painter = new Paint()
|
||||
..color = Colors.blueAccent
|
||||
..strokeCap = StrokeCap.round
|
||||
..isAntiAlias = true
|
||||
..strokeWidth = 5.0
|
||||
..filterQuality = FilterQuality.high
|
||||
..style = PaintingStyle.stroke;
|
||||
}
|
||||
///Flutter中负责View绘制的地方,使用传递来的canvas和size即可完成对目标View的绘制
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
switch(type) {
|
||||
case 'drawPoints':
|
||||
const List<Offset> points1 = [Offset(20.0, 0.0), Offset(100.0, 50.0), Offset(150.0, 0.0),Offset(300.0, 0.0)];
|
||||
const List<Offset> points2 = [Offset(20.0, 100.0), Offset(100.0, 100.0), Offset(150.0, 100.0), Offset(300.0, 100.0)];
|
||||
const List<Offset> points3 = [Offset(20.0, 150.0), Offset(100.0, 150.0), Offset(150.0, 180.0), Offset(300.0, 150.0)];
|
||||
//绘制点
|
||||
canvas.drawPoints(
|
||||
///PointMode的枚举类型有三个,points(点),lines(线,隔点连接),polygon(线,相邻连接)
|
||||
PointMode.points,
|
||||
points1,
|
||||
painter..color = Colors.redAccent // 这里可以追加修改 painter 属性
|
||||
..strokeWidth = 10.0
|
||||
);
|
||||
canvas.drawPoints(
|
||||
///PointMode的枚举类型有三个,points(点),lines(线,隔点连接),polygon(线,相邻连接)
|
||||
PointMode.lines,
|
||||
points2,
|
||||
painter..color = Colors.orange // 这里可以追加修改 painter 属性
|
||||
..strokeWidth = 10.0
|
||||
);
|
||||
canvas.drawPoints(
|
||||
///PointMode的枚举类型有三个,points(点),lines(线,隔点连接),polygon(线,相邻连接)
|
||||
PointMode.polygon,
|
||||
points3,
|
||||
painter..color = Colors.blue // 这里可以追加修改 painter 属性
|
||||
..strokeWidth = 10.0
|
||||
);
|
||||
break;
|
||||
case 'drawLine':
|
||||
//绘制直线
|
||||
canvas.drawLine(Offset(20.0, 0.0), Offset(size.width*0.8, 200), painter ..color = Colors.redAccent);
|
||||
break;
|
||||
case 'rawCircle':
|
||||
//绘制圆 参数(圆心,半径,画笔)
|
||||
canvas.drawCircle(
|
||||
Offset(size.width/2, 100.0),
|
||||
100.0,
|
||||
painter
|
||||
..color = Colors.greenAccent
|
||||
..style = PaintingStyle.stroke //绘画风格改为stroke
|
||||
);
|
||||
break;
|
||||
case 'drawOval':
|
||||
// 绘制椭圆
|
||||
// 使用左上和右下角坐标来确定矩形的大小和位置,椭圆是在这个矩形之中内切的形状
|
||||
Rect rect1 = Rect.fromPoints(Offset(0.0, 0.0), Offset(size.width, 200.0));
|
||||
canvas.drawOval(rect1, painter ..color = Colors.indigo);
|
||||
break;
|
||||
case 'drawArc':
|
||||
// 绘制圆弧
|
||||
// Rect来确认圆弧的位置,还需要开始的弧度、结束的弧度、是否使用中心点绘制、以及paint弧度
|
||||
const PI = 3.1415926;
|
||||
Rect rect1 = Rect.fromCircle(center: Offset(20, 50.0), radius: 100.0);
|
||||
canvas.drawArc(rect1, 0.0, PI / 2, false, painter ..color = Colors.pink);
|
||||
|
||||
Rect rect2 = Rect.fromCircle(center: Offset(size.width*0.6, 50.0), radius: 100.0);
|
||||
canvas.drawArc(rect2, 0.0, PI / 2, true, painter ..color = Colors.deepPurple);
|
||||
break;
|
||||
case 'drawRRect':
|
||||
/// fromPoints(Offset a, Offset b)
|
||||
/// 使用左上和右下角坐标来确定矩形的大小和位置
|
||||
/// fromCircle({ Offset center, double radius })
|
||||
/// 使用圆的圆心点坐标和半径和确定外切矩形的大小和位置
|
||||
/// fromLTRB(double left, double top, double right, double bottom)
|
||||
/// 使用矩形左边的X坐标、矩形顶部的Y坐标、矩形右边的X坐标、矩形底部的Y坐标来确定矩形的大小和位置
|
||||
/// fromLTWH(double left, double top, double width, double height)
|
||||
/// 使用矩形左边的X坐标、矩形顶部的Y坐标矩形的宽高来确定矩形的大小和位置
|
||||
// 用Rect构建一个边长50,中心点坐标为50,100的矩形
|
||||
Rect rect1 = Rect.fromCircle(center: Offset(80.0, 100.0), radius: 50.0);
|
||||
Rect rect2 = Rect.fromCircle(center: Offset(250.0, 100.0), radius: 50.0);
|
||||
// 根据上面的矩形,构建一个圆角矩形
|
||||
RRect rrect1 = RRect.fromRectAndRadius(rect1, Radius.circular(0.0));
|
||||
canvas.drawRRect(rrect1, painter);
|
||||
RRect rrect2 = RRect.fromRectAndRadius(rect2, Radius.circular(20.0));
|
||||
canvas.drawRRect(rrect2, painter);
|
||||
break;
|
||||
case 'drawDRRect':
|
||||
//绘制两个矩形
|
||||
Rect rect1 = Rect.fromCircle(center: Offset(size.width/2, 100.0), radius: 60.0);
|
||||
Rect rect2 = Rect.fromCircle(center: Offset(size.width/2, 100.0), radius: 40.0);
|
||||
//分别绘制外部圆角矩形和内部的圆角矩形
|
||||
RRect outer = RRect.fromRectAndRadius(rect1, Radius.circular(30.0));
|
||||
RRect inner = RRect.fromRectAndRadius(rect2, Radius.circular(5.0));
|
||||
canvas.drawDRRect(outer, inner, painter ..color = Colors.lime);
|
||||
break;
|
||||
case 'drawImage':
|
||||
// canvas.drawImage(image, Offset(0.0, 0.0), painter);
|
||||
final src = Rect.fromLTWH(0.0, 0.0, 684.0, 442.0);
|
||||
final dst = Rect.fromLTWH(0.0, 0.0, size.width, size.height);
|
||||
canvas.drawImageRect(image, src, dst, painter);
|
||||
break;
|
||||
}
|
||||
//canvas.drawColor(Colors.red, BlendMode.colorDodge);
|
||||
}
|
||||
|
||||
///控制自定义View是否需要重绘的,返回false代表这个View在构建完成后不需要重绘。
|
||||
@override
|
||||
bool shouldRepaint(CustomPainter oldDelegate) {
|
||||
return false;
|
||||
}
|
||||
}
|
90
lib/widgets/elements/Media/Canvas/Canvas/index.dart
Normal file
90
lib/widgets/elements/Media/Canvas/Canvas/index.dart
Normal file
@ -0,0 +1,90 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_go/components/widget_demo.dart';
|
||||
import './demo.dart' as demoBoxs;
|
||||
|
||||
const Text = '''
|
||||
### **简介**
|
||||
> 用于操作图形的界面;
|
||||
- canvas 对象用于创建图片对象,这些对象本身可以与 SceneBuilder 一起用于构建场景;
|
||||
''';
|
||||
const Text1 = '''
|
||||
### **基本用法**
|
||||
- 它可以使用“平移”、“缩放”、“旋转”、“倾斜”和“变换”方法进行修改;
|
||||
- 可以使用 clipRect、clipCorrect 和 clipPath 方法进行修改;
|
||||
- 可以使用由 save、savelayer和 restore 方法管理的堆栈来保存和还原当前的转换和剪辑。
|
||||
- 以下是绘制点,线,面的基本用法
|
||||
''';
|
||||
|
||||
const Text2 = '''
|
||||
> 绘制点
|
||||
- 绘制点有三种模式, points(点),lines(线,隔点连接),polygon(线,相邻连接)
|
||||
''';
|
||||
|
||||
const Text3 = '''
|
||||
> 绘制直线
|
||||
''';
|
||||
|
||||
const Text4 = '''
|
||||
> 绘制圆
|
||||
''';
|
||||
|
||||
const Text5 = '''
|
||||
> 绘制椭圆
|
||||
- 使用左上和右下角坐标来确定矩形的大小和位置,椭圆是在这个矩形之中内切的形状
|
||||
''';
|
||||
|
||||
const Text6 = '''
|
||||
> 绘制圆弧
|
||||
- Rect 来确认圆弧的位置,还需要开始的弧度、结束的弧度、是否使用中心点绘制、以及 paint 弧度
|
||||
''';
|
||||
|
||||
const Text7 = '''
|
||||
> 绘制矩形,圆角矩形
|
||||
- 用 Rect构建矩形
|
||||
- 根据上面的矩形,构建一个圆角矩形
|
||||
''';
|
||||
|
||||
const Text8 = '''
|
||||
> 绘制两个相套矩形
|
||||
''';
|
||||
|
||||
const Text9 = '''
|
||||
> 绘制图片到canvas
|
||||
''';
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/element/Media/Canvas/PainterPath';
|
||||
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'Canvas',
|
||||
codeUrl: 'elements/Media/Canvas/Canvas/demo.dart',
|
||||
contentList: [
|
||||
Text,
|
||||
Text1,
|
||||
Text2,
|
||||
demoBoxs.CustomViewPage(type:'drawPoints'),
|
||||
Text3,
|
||||
demoBoxs.CustomViewPage(type:'drawLine'),
|
||||
Text4,
|
||||
demoBoxs.CustomViewPage(type:'rawCircle'),
|
||||
Text5,
|
||||
demoBoxs.CustomViewPage(type:'drawOval'),
|
||||
Text6,
|
||||
demoBoxs.CustomViewPage(type:'drawArc'),
|
||||
Text7,
|
||||
demoBoxs.CustomViewPage(type:'drawRRect'),
|
||||
Text8,
|
||||
demoBoxs.CustomViewPage(type:'drawDRRect'),
|
||||
Text9,
|
||||
demoBoxs.CustomViewPage(type:'drawImage')
|
||||
],
|
||||
docUrl: 'https://docs.flutter.io/flutter/dart-ui/Canvas-class.html',
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2019/1/20
|
||||
* Time: 上午11:34
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: CircleProgressBarPainter 的示例
|
||||
*/
|
||||
import 'dart:ui';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CustomViewPage extends StatefulWidget {
|
||||
@override
|
||||
State<StatefulWidget> createState() => CustomViewPageState();
|
||||
}
|
||||
|
||||
class CustomViewPageState extends State<CustomViewPage>
|
||||
with SingleTickerProviderStateMixin {
|
||||
Animation<double> _doubleAnimation;
|
||||
AnimationController _controller;
|
||||
CurvedAnimation curvedAnimation;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller =
|
||||
AnimationController(vsync: this, duration: Duration(seconds: 2));
|
||||
curvedAnimation =
|
||||
CurvedAnimation(parent: _controller, curve: Curves.decelerate);
|
||||
_doubleAnimation = Tween(begin: 0.0, end: 360.0).animate(_controller);
|
||||
|
||||
_controller.addListener(() {
|
||||
this.setState(() {});
|
||||
});
|
||||
onAnimationStart();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: 100.0,
|
||||
height: 100.0,
|
||||
margin: EdgeInsets.all(8.0),
|
||||
child: CustomPaint(
|
||||
child: Center(
|
||||
child: Text((_doubleAnimation.value / 3.6).round().toString())),
|
||||
painter: CircleProgressBarPainter(_doubleAnimation.value)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void onAnimationStart() {
|
||||
_controller.forward(from: 0.0);
|
||||
}
|
||||
|
||||
@override
|
||||
void reassemble() {
|
||||
super.reassemble();
|
||||
onAnimationStart();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
_controller.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
class CircleProgressBarPainter extends CustomPainter {
|
||||
Paint _paintBackground;
|
||||
Paint _paintFore;
|
||||
final double pi = 3.1415926;
|
||||
var jindu;
|
||||
|
||||
CircleProgressBarPainter(this.jindu) {
|
||||
_paintBackground = Paint()
|
||||
..color = Colors.grey
|
||||
..strokeCap = StrokeCap.round
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = 10.0
|
||||
..isAntiAlias = true;
|
||||
_paintFore = Paint()
|
||||
..color = Colors.red
|
||||
..strokeCap = StrokeCap.round
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = 10.0
|
||||
..isAntiAlias = true;
|
||||
}
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
canvas.drawCircle(Offset(size.width / 2, size.height / 2), size.width / 2,_paintBackground);
|
||||
Rect rect = Rect.fromCircle(
|
||||
center: Offset(size.width / 2, size.height / 2),
|
||||
radius: size.width / 2,
|
||||
);
|
||||
canvas.drawArc(rect, 0.0, jindu * 3.14 / 180, false, _paintFore);
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(CustomPainter oldDelegate) {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_go/components/widget_demo.dart';
|
||||
import './demo.dart' as demoBoxs;
|
||||
|
||||
const Text = '''
|
||||
### **简介**
|
||||
> 操作图形的界面;
|
||||
|
||||
''';
|
||||
const Text1 = '''
|
||||
### **基本用法**
|
||||
- canvas + Animation 实现一个 loading 效果;
|
||||
''';
|
||||
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/element/Media/Canvas/CircleProgressBarPainter';
|
||||
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'Canvas',
|
||||
codeUrl: 'elements/Media/Canvas/CircleProgressBarPainter/demo.dart',
|
||||
contentList: [
|
||||
Text,
|
||||
Text1,
|
||||
demoBoxs.CustomViewPage()
|
||||
],
|
||||
docUrl: 'https://docs.flutter.io/flutter/dart-ui/Canvas-class.html',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
180
lib/widgets/elements/Media/Canvas/PainterPath/demo.dart
Normal file
180
lib/widgets/elements/Media/Canvas/PainterPath/demo.dart
Normal file
@ -0,0 +1,180 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2019/1/20
|
||||
* Time: 上午11:34
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: PainterPath 的示例
|
||||
*/
|
||||
import 'dart:ui';
|
||||
import 'package:flutter/material.dart';
|
||||
CustomPaint graph;
|
||||
|
||||
class CustomViewPage extends StatefulWidget {
|
||||
|
||||
final String type;
|
||||
CustomViewPage({this.type='simpleline'}) : super();
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => CustomViewPageState();
|
||||
}
|
||||
|
||||
class CustomViewPageState extends State<CustomViewPage>
|
||||
with SingleTickerProviderStateMixin {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
graph = CustomPaint(
|
||||
painter: DrawPainter(type:widget.type)
|
||||
);
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
height: MediaQuery.of(context).size.width * 0.6,
|
||||
margin: EdgeInsets.all(50.0),
|
||||
//padding: EdgeInsets.all(10.0),
|
||||
child: graph
|
||||
//child:Center(child: graph)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
void reassemble() {
|
||||
super.reassemble();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
///新建类继承于CustomPainter并且实现CustomPainter里面的paint()和shouldRepaint方法
|
||||
class DrawPainter extends CustomPainter {
|
||||
Paint painter;
|
||||
final type;
|
||||
|
||||
DrawPainter ({this.type}){
|
||||
// Paint painter = Paint()
|
||||
// ..color = Colors.blueAccent //画笔颜色
|
||||
// ..strokeCap = StrokeCap.round //画笔笔触类型
|
||||
// ..isAntiAlias = true //是否启动抗锯齿
|
||||
// ..blendMode = BlendMode.exclusion //颜色混合模式
|
||||
// ..style = PaintingStyle.fill //绘画风格,默认为填充
|
||||
// ..colorFilter = ColorFilter.mode(Colors.blueAccent,BlendMode.exclusion) //颜色渲染模式,一般是矩阵效果来改变的,但是flutter中只能使用颜色混合模式
|
||||
// ..maskFilter = MaskFilter.blur(BlurStyle.inner, 3.0) //模糊遮罩效果,flutter中只有这个
|
||||
// ..filterQuality = FilterQuality.high //颜色渲染模式的质量
|
||||
// ..strokeWidth = 15.0 ;//画笔的宽度
|
||||
|
||||
painter = new Paint()
|
||||
..color = Colors.blueAccent
|
||||
..strokeCap = StrokeCap.round
|
||||
..isAntiAlias = true
|
||||
..strokeWidth = 5.0
|
||||
..style = PaintingStyle.stroke;
|
||||
}
|
||||
///Flutter中负责View绘制的地方,使用传递来的canvas和size即可完成对目标View的绘制
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
//canvas.drawColor(Colors.red, BlendMode.colorDodge);
|
||||
Path path = new Path();
|
||||
drawThisPath(canvas, size, path);
|
||||
path.close();
|
||||
canvas.drawPath(path, painter);
|
||||
}
|
||||
|
||||
void drawThisPath(Canvas canvas, Size size, Path path,) {
|
||||
switch(type) {
|
||||
case 'simpleline':
|
||||
//新建了一个path,然后将路径起始点移动到坐标(100,100)的位置
|
||||
Path path = new Path()..moveTo(0.0, 0.0);
|
||||
path.lineTo(200.0, 200.0);
|
||||
canvas.drawPath(path, painter);
|
||||
break;
|
||||
case 'polyline':
|
||||
Path path = new Path()..moveTo(100.0, 10.0);
|
||||
|
||||
path.lineTo(200.0, 150.0);
|
||||
path.lineTo(100.0, 200.0);
|
||||
|
||||
canvas.drawPath(path, painter);
|
||||
break;
|
||||
case 'Besizerline2':
|
||||
Path path = new Path()..moveTo(0.0, 0.0);
|
||||
Rect rect1 = Rect.fromCircle(center: Offset(50.0, 100.0), radius: 60.0);
|
||||
path.arcTo(rect1, 0.0, 3.14, false);
|
||||
canvas.drawPath(path, painter);
|
||||
|
||||
Rect rect2 = Rect.fromCircle(center: Offset(200.0, 100.0), radius: 60.0);
|
||||
path.arcTo(rect2, 0.0, 3.14*2, true);
|
||||
canvas.drawPath(path, painter);
|
||||
break;
|
||||
case 'Besizerline3':
|
||||
var width = size.width;
|
||||
var height = 300;
|
||||
Path path = new Path()..moveTo(width / 2, height / 4);
|
||||
path.cubicTo((width * 6) / 7, height / 9, (width * 13) / 13,
|
||||
(height * 2) / 5, width / 2, (height * 7) / 12);
|
||||
canvas.drawPath(path, painter
|
||||
// ..style = PaintingStyle.fill
|
||||
// ..color = Colors.red
|
||||
);
|
||||
|
||||
Path path2 = new Path();
|
||||
path2.moveTo(width / 2, height / 4);
|
||||
path2.cubicTo(width / 7, height / 9, width / 21, (height * 2) / 5,
|
||||
width / 2, (height * 7) / 12);
|
||||
canvas.drawPath(path2, painter);
|
||||
break;
|
||||
case 'drawArc':
|
||||
// 绘制圆弧
|
||||
// Rect来确认圆弧的位置,还需要开始的弧度、结束的弧度、是否使用中心点绘制、以及paint弧度
|
||||
const PI = 3.1415926;
|
||||
Rect rect1 = Rect.fromCircle(center: Offset(size.width/2, 0.0), radius: 100.0);
|
||||
canvas.drawArc(rect1, 0.0, PI / 2, false, painter ..color = Colors.pink);
|
||||
|
||||
Rect rect2 = Rect.fromCircle(center: Offset(size.width/2, 150.0), radius: 100.0);
|
||||
canvas.drawArc(rect2, 0.0, PI / 2, true, painter ..color = Colors.deepPurple);
|
||||
break;
|
||||
case 'drawRRect':
|
||||
/// fromPoints(Offset a, Offset b)
|
||||
/// 使用左上和右下角坐标来确定矩形的大小和位置
|
||||
/// fromCircle({ Offset center, double radius })
|
||||
/// 使用圆的圆心点坐标和半径和确定外切矩形的大小和位置
|
||||
/// fromLTRB(double left, double top, double right, double bottom)
|
||||
/// 使用矩形左边的X坐标、矩形顶部的Y坐标、矩形右边的X坐标、矩形底部的Y坐标来确定矩形的大小和位置
|
||||
/// fromLTWH(double left, double top, double width, double height)
|
||||
/// 使用矩形左边的X坐标、矩形顶部的Y坐标矩形的宽高来确定矩形的大小和位置
|
||||
// 用Rect构建一个边长50,中心点坐标为50,100的矩形
|
||||
Rect rect1 = Rect.fromCircle(center: Offset(50.0, 50.0), radius: 50.0);
|
||||
Rect rect2 = Rect.fromCircle(center: Offset(200.0, 50.0), radius: 50.0);
|
||||
// 根据上面的矩形,构建一个圆角矩形
|
||||
RRect rrect1 = RRect.fromRectAndRadius(rect1, Radius.circular(0.0));
|
||||
canvas.drawRRect(rrect1, painter);
|
||||
RRect rrect2 = RRect.fromRectAndRadius(rect2, Radius.circular(20.0));
|
||||
canvas.drawRRect(rrect2, painter);
|
||||
break;
|
||||
case 'drawDRRect':
|
||||
//绘制两个矩形
|
||||
Rect rect1 = Rect.fromCircle(center: Offset(size.width/2, 100.0), radius: 60.0);
|
||||
Rect rect2 = Rect.fromCircle(center: Offset(size.width/2, 100.0), radius: 40.0);
|
||||
//分别绘制外部圆角矩形和内部的圆角矩形
|
||||
RRect outer = RRect.fromRectAndRadius(rect1, Radius.circular(30.0));
|
||||
RRect inner = RRect.fromRectAndRadius(rect2, Radius.circular(5.0));
|
||||
canvas.drawDRRect(outer, inner, painter ..color = Colors.lime);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
///控制自定义View是否需要重绘的,返回false代表这个View在构建完成后不需要重绘。
|
||||
@override
|
||||
bool shouldRepaint(CustomPainter oldDelegate) {
|
||||
return false;
|
||||
}
|
||||
}
|
65
lib/widgets/elements/Media/Canvas/PainterPath/index.dart
Normal file
65
lib/widgets/elements/Media/Canvas/PainterPath/index.dart
Normal file
@ -0,0 +1,65 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_go/components/widget_demo.dart';
|
||||
import './demo.dart' as demoBoxs;
|
||||
|
||||
//const Text = '''
|
||||
//### **简介**
|
||||
//> 在 canvas 上绘制时使用的样式说明;
|
||||
//- canvas 上的大多数API都使用一个绘画对象来描述用于该操作的样式。
|
||||
//''';
|
||||
const Text = '''
|
||||
### **简介**
|
||||
> 在 canvas 上绘制的图案;
|
||||
- canvas + paint 的应用。
|
||||
''';
|
||||
|
||||
const Text1 = '''
|
||||
### **基本用法**
|
||||
- canvas 的 painter 的自定义绘制线的方法;
|
||||
''';
|
||||
|
||||
const Text2 = '''
|
||||
> 绘制简单直线
|
||||
''';
|
||||
|
||||
const Text3 = '''
|
||||
> 绘制折线
|
||||
''';
|
||||
|
||||
const Text4 = '''
|
||||
> 二阶贝塞尔曲线
|
||||
''';
|
||||
|
||||
const Text5 = '''
|
||||
> 三阶贝塞尔曲线
|
||||
''';
|
||||
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/element/Media/Canvas/Canvas';
|
||||
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'PainterPath',
|
||||
codeUrl: 'elements/Media/Canvas/PainterPath/demo.dart',
|
||||
contentList: [
|
||||
Text,
|
||||
Text1,
|
||||
Text2,
|
||||
demoBoxs.CustomViewPage(type:'simpleline'),
|
||||
Text3,
|
||||
demoBoxs.CustomViewPage(type:'polyline'),
|
||||
Text4,
|
||||
demoBoxs.CustomViewPage(type:'Besizerline2'),
|
||||
Text5,
|
||||
demoBoxs.CustomViewPage(type:'Besizerline3'),
|
||||
],
|
||||
docUrl: 'https://docs.flutter.io/flutter/dart-ui/Paint-class.html',
|
||||
);
|
||||
}
|
||||
}
|
213
lib/widgets/elements/Media/Canvas/PainterSketch/demo.dart
Normal file
213
lib/widgets/elements/Media/Canvas/PainterSketch/demo.dart
Normal file
@ -0,0 +1,213 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2019/1/20
|
||||
* Time: 上午11:34
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: PainterSketchDome 的示例
|
||||
*/
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
|
||||
class PainterSketchDome extends StatefulWidget {
|
||||
PainterSketchDome({Key key, this.title}) : super(key: key);
|
||||
|
||||
final String title;
|
||||
|
||||
@override
|
||||
_PainterSketchDomeState createState() => new _PainterSketchDomeState();
|
||||
}
|
||||
|
||||
class _PainterSketchDomeState extends State<PainterSketchDome> {
|
||||
|
||||
List<LinePoints> lines = <LinePoints>[];
|
||||
List<Offset> nowPoints = <Offset>[];
|
||||
Color nowColor = Colors.redAccent;
|
||||
|
||||
void moveGestureDetector(DragUpdateDetails detail){
|
||||
RenderBox box = context.findRenderObject();
|
||||
final Offset xy = box.globalToLocal(detail.globalPosition);// 重要需要转换以下坐标位置
|
||||
Offset p = Offset(xy.dx, xy.dy - 60);
|
||||
//Offset p = Offset(detail.globalPosition.dx, detail.globalPosition.dy - 60);
|
||||
setState(() {
|
||||
nowPoints.add(p);
|
||||
});
|
||||
}
|
||||
|
||||
void newGestureDetector(DragStartDetails detail) {
|
||||
if (nowPoints.length != 0) {
|
||||
LinePoints l = LinePoints(new List<Offset>.from(nowPoints), nowColor);
|
||||
lines.add(l);
|
||||
nowPoints.clear();
|
||||
}
|
||||
RenderBox box = context.findRenderObject();
|
||||
final Offset xy = box.globalToLocal(detail.globalPosition);// 重要需要转换以下坐标位置
|
||||
Offset p = Offset(xy.dx, xy.dy - 60);
|
||||
//Offset p = Offset(detail.globalPosition.dx, detail.globalPosition.dy - 60);
|
||||
setState(() {
|
||||
nowPoints.add(p);
|
||||
});
|
||||
}
|
||||
|
||||
void changeColor (Color c){
|
||||
if (nowPoints.length != 0) {
|
||||
LinePoints l = LinePoints(new List<Offset>.from(nowPoints), nowColor);
|
||||
lines.add(l);
|
||||
}
|
||||
setState(() {
|
||||
nowPoints.clear();
|
||||
nowColor = c;
|
||||
});
|
||||
}
|
||||
|
||||
List<Color> colors = <Color>[
|
||||
Colors.redAccent,
|
||||
Colors.pink,
|
||||
Colors.greenAccent,
|
||||
Colors.blueAccent,
|
||||
Colors.amber,
|
||||
Colors.purpleAccent,
|
||||
Colors.deepPurpleAccent,
|
||||
Colors.lightBlueAccent,
|
||||
Colors.lightGreenAccent,
|
||||
Colors.cyanAccent,];
|
||||
|
||||
void _tapClear(){
|
||||
setState(() {
|
||||
lines.clear();
|
||||
nowPoints.clear();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<Widget> pallet = <Widget>[];
|
||||
for (int i = 0; i < colors.length; i++) {
|
||||
Color c = colors[i];
|
||||
pallet.add(ColorPallet(color: c,changeColor: changeColor,isSelect: c==nowColor,));
|
||||
}
|
||||
|
||||
return SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.9,
|
||||
height: MediaQuery.of(context).size.height * 0.6,
|
||||
child:new Scaffold(
|
||||
primary: false,
|
||||
body: new Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white
|
||||
),
|
||||
child:new Flex(
|
||||
direction: Axis.vertical,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
decoration:BoxDecoration(
|
||||
color: Colors.black12
|
||||
),
|
||||
child: ListView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
children: pallet
|
||||
,
|
||||
),
|
||||
height: 60.0,
|
||||
),
|
||||
Expanded(
|
||||
child: AspectRatio(
|
||||
aspectRatio: 1.0,
|
||||
child: GestureDetector(
|
||||
child: CustomPaint(
|
||||
painter: PaintCanvas(lines,nowPoints,nowColor),
|
||||
),
|
||||
onHorizontalDragUpdate: moveGestureDetector,
|
||||
onVerticalDragUpdate: moveGestureDetector,
|
||||
onHorizontalDragStart: newGestureDetector,
|
||||
onVerticalDragStart: newGestureDetector,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: _tapClear,
|
||||
backgroundColor: Colors.redAccent,
|
||||
foregroundColor: Colors.white,
|
||||
child: Icon(Icons.delete),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class PaintCanvas extends CustomPainter{
|
||||
|
||||
final List<LinePoints> lines;
|
||||
final List<Offset> nowPoints;
|
||||
final Color nowColor;
|
||||
|
||||
PaintCanvas(this.lines, this.nowPoints, this.nowColor);
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
Paint p = new Paint()
|
||||
..color = Colors.redAccent
|
||||
..strokeCap = StrokeCap.round
|
||||
..strokeWidth = 5.0;
|
||||
canvas.save();
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
LinePoints l = lines[i];
|
||||
for (int j = 1; j < l.points.length; j++){
|
||||
Offset p1 = l.points[j - 1];
|
||||
Offset p2 = l.points[j];
|
||||
p.color = l.lineColor;
|
||||
canvas.drawLine(p1, p2, p);
|
||||
}
|
||||
}
|
||||
for (int i = 1; i < nowPoints.length; i++){
|
||||
Offset p1 = nowPoints[i - 1];
|
||||
Offset p2 = nowPoints[i];
|
||||
p.color = nowColor;
|
||||
canvas.drawLine(p1, p2, p);
|
||||
}
|
||||
|
||||
canvas.restore();
|
||||
}
|
||||
@override
|
||||
bool shouldRepaint(CustomPainter oldDelegate) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class LinePoints{
|
||||
final List<Offset> points;
|
||||
final Color lineColor;
|
||||
LinePoints(this.points, this.lineColor);
|
||||
}
|
||||
|
||||
class ColorPallet extends StatelessWidget {
|
||||
final Color color;
|
||||
final Function changeColor;
|
||||
const ColorPallet({Key key, this.color, this.changeColor, this.isSelect}) : super(key: key);
|
||||
final bool isSelect;
|
||||
|
||||
void onPressed(){
|
||||
changeColor(color);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new RawMaterialButton(
|
||||
onPressed: onPressed,
|
||||
constraints: BoxConstraints(minWidth: 60.0,minHeight: 50.0),
|
||||
child: new Container(
|
||||
margin: EdgeInsets.only(top: 5.0,bottom: 5.0),
|
||||
width: 50.0,
|
||||
height: 50.0,
|
||||
decoration: BoxDecoration(
|
||||
color: color,
|
||||
borderRadius: BorderRadius.all(Radius.circular(25.0)),
|
||||
border: Border.all(color: Colors.white,width: isSelect?3.0:0.0)
|
||||
),
|
||||
)) ;
|
||||
}
|
||||
}
|
37
lib/widgets/elements/Media/Canvas/PainterSketch/index.dart
Normal file
37
lib/widgets/elements/Media/Canvas/PainterSketch/index.dart
Normal file
@ -0,0 +1,37 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_go/components/widget_demo.dart';
|
||||
import './demo.dart' as demoBoxs;
|
||||
|
||||
const Text = '''
|
||||
### **简介**
|
||||
> 操作图形的界面;
|
||||
|
||||
''';
|
||||
const Text1 = '''
|
||||
### **基本用法**
|
||||
- canvas + paint + GestureDetector 实现一个 简易的画板;
|
||||
''';
|
||||
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/element/Media/Canvas/PainterSketch';
|
||||
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'Canvas',
|
||||
codeUrl: 'elements/Media/Canvas/PainterSketch/demo.dart',
|
||||
contentList: [
|
||||
Text,
|
||||
Text1,
|
||||
demoBoxs.PainterSketchDome()
|
||||
],
|
||||
docUrl: 'https://docs.flutter.io/flutter/dart-ui/Paint-class.html',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1 +1,31 @@
|
||||
// import 'package:flutter/material.dart';
|
||||
import 'package:flutter_go/model/widget.dart';
|
||||
import "package:flutter/material.dart";
|
||||
|
||||
import 'PainterSketch/index.dart' as PainterSketch;
|
||||
import 'Canvas/index.dart' as Canvas;
|
||||
import 'PainterPath/index.dart' as PainterPath;
|
||||
import 'CircleProgressBarPainter/index.dart' as CircleProgressBarPainter;
|
||||
|
||||
|
||||
List<WidgetPoint> widgetPoints = [
|
||||
WidgetPoint(
|
||||
name: 'PainterSketch',
|
||||
routerName: PainterSketch.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => PainterSketch.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name: 'Canvas',
|
||||
routerName: Canvas.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => Canvas.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name: 'PainterPath',
|
||||
routerName: PainterPath.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => PainterPath.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name: 'CircleProgressBarPainter',
|
||||
routerName: CircleProgressBarPainter.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => CircleProgressBarPainter.Demo(),
|
||||
)
|
||||
];
|
||||
|
@ -6,10 +6,12 @@
|
||||
*/
|
||||
import 'Image/index.dart' as Image;
|
||||
import 'Icon/index.dart' as Icon;
|
||||
import 'Canvas/index.dart' as Canvas;
|
||||
|
||||
List getWidgets() {
|
||||
List result = [];
|
||||
result.addAll(Image.widgetPoints);
|
||||
result.addAll(Icon.widgetPoints);
|
||||
result.addAll(Canvas.widgetPoints);
|
||||
return result;
|
||||
}
|
@ -159,6 +159,10 @@ flutter:
|
||||
- lib/widgets/elements/Media/Image/paintImage/paint_image_demo.dart
|
||||
- lib/widgets/elements/Media/Image/precacheImage/precache_image_demo.dart
|
||||
- lib/widgets/elements/Media/Image/RawImage/raw_image_demo.dart
|
||||
- lib/widgets/elements/Media/Canvas/Canvas/demo.dart
|
||||
- lib/widgets/elements/Media/Canvas/CircleProgressBarPainter/demo.dart
|
||||
- lib/widgets/elements/Media/Canvas/PainterPath/demo.dart
|
||||
- lib/widgets/elements/Media/Canvas/PainterSketch/demo.dart
|
||||
- lib/widgets/themes/Material/MaterialApp/demo.dart
|
||||
- lib/widgets/themes/Material/MaterialButton/demo.dart
|
||||
- lib/widgets/themes/Material/MaterialColor/demo.dart
|
||||
|
Reference in New Issue
Block a user