绘制完美的压力感应手绘线条。
? 这是 perfect-freehand JavaScript 库的移植。 试试这个演示。
? 是否在商业产品中使用此库?请考虑 成为赞助者。
目录
用法
此包导出一个名为 getStroke 的函数,该函数
- 接受一个点数组和若干选项
- 返回一个笔画轮廓作为点数组
import 'package:perfect_freehand/perfect_freehand.dart';
List<Point> myPoints = [
Point(0, 0),
Point(1, 2),
// etc...
];
final stroke = getStroke(myPoints);
您也可以提供命名参数作为选项
final stroke = getStroke(
myPoints,
size: 16,
thinning: 0.7,
smoothing: 0.5,
streamline: 0.5,
taperStart: 0.0,
taperEnd: 0.0,
capStart: true,
capEnd: true,
simulatePressure: true,
isComplete: false,
);
要使用真实的压力,请将每个点的压力作为第三个参数提供。
List<Point> myPoints = [
Point(0, 0, 0.2),
Point(1, 2, 0.3),
Point(2, 4, 0.4),
// etc...
];
final stroke = getStroke(myPoints, simulatePressure: false);
选项
可选参数为
| 属性 | 类型 | 默认值 | 描述 |
|---|---|---|---|
size |
双精度 | 16 | 笔画的基础尺寸(直径)。 |
细化 |
双精度 | .5 | 压力对笔画尺寸的影响。 |
平滑 |
双精度 | .5 | 对笔画边缘进行柔化处理的程度。 |
流线化 |
双精度 | .5 | 从输入点中去除变化的程度。 |
起始锥度 |
双精度 | 0 | 线开始处锥形的程度。 |
结束锥度 |
双精度 | 0 | 线结束处锥形的程度。 |
isComplete |
boolean | 真 | 笔画是否完整。 |
simulatePressure |
boolean | 真 | 是根据点之间的距离模拟压力,还是使用提供的点的压力。 |
注意:当 last 属性为 true 时,线条的末端将绘制在最后一个输入点处,而不是稍稍靠后。
注意:当 taper 大于零时,cap 属性无效。
提示:要创建具有稳定线条的笔画,请将 thinning 选项设置为 0。
提示:要创建一条随着压力变细而不是变粗的笔画,请将 thinning 选项设置为负数。
渲染
虽然 getStroke 返回一个表示笔画轮廓的点数组,但如何渲染这些点由您决定。请查看 **示例项目**,了解如何在 Flutter 中使用 CustomPainter 绘制这些点。
import 'package:flutter/material.dart';
import 'package:perfect_freehand/perfect_freehand.dart';
class StrokePainter extends CustomPainter {
final List<Point> points;
StrokePainter({ required this.points });
@override
void paint(Canvas canvas, Size size) {
Paint paint = Paint() ..color = Colors.black;
// 1. Get the outline points from the input points
final outlinePoints = getStroke(points);
// 2. Render the points as a path
final path = Path();
if (outlinePoints.isEmpty) {
// If the list is empty, don't do anything.
return;
} else if (outlinePoints.length < 2) {
// If the list only has one point, draw a dot.
path.addOval(Rect.fromCircle(
center: Offset(outlinePoints[0].x, outlinePoints[0].y), radius: 1));
} else {
// Otherwise, draw a line that connects each point with a bezier curve segment.
path.moveTo(outlinePoints[0].x, outlinePoints[0].y);
for (int i = 1; i < outlinePoints.length - 1; ++i) {
final p0 = outlinePoints[i];
final p1 = outlinePoints[i + 1];
path.quadraticBezierTo(
p0.x, p0.y, (p0.x + p1.x) / 2, (p0.y + p1.y) / 2);
}
}
// 3. Draw the path to the canvas
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(StrokePainter oldDelegate) {
return true;
}
}
高级用法
对于高级用法,该库还导出了 getStroke 用于生成其轮廓点的较小函数。
getStrokePoints
一个接受点数组并返回 StrokePoints 集合的函数。路径的总长度将是数组中最后一个点的 runningLength。与 getStroke 一样,此函数也接受上面列出的任何 可选命名参数。
List<Point> myPoints = [
Point(0, 0),
Point(1, 2),
// etc...
];
final strokePoints = getStrokePoints(myPoints, size: 16);
getOutlinePoints
一个接受笔画点数组(即 getStrokePoint 的输出)并返回定义笔画轮廓的点数组的函数。与 getStroke 一样,此函数也接受上面列出的任何 可选命名参数。
List<Point> myPoints = [
Point(0, 0),
Point(1, 2),
// etc...
];
final myStrokePoints = getStrokePoints(myPoints, size: 16);
final myOutlinePoints = getStrokeOutlinePoints(myStrokePoints, size: 16)
注意:在内部,getStroke 函数将 getStrokePoints 的结果传递给 getStrokeOutlinePoints,正如本示例所示。这意味着,在此示例中,myOutlinePoints 的结果将与 myPoints 列表传递给 getStroke 的结果相同。
支持
请 打开一个 issue 以获得支持。
讨论
有想法或想随意提问?请访问 讨论页面。