画布
画布是一种控件,用于使用一组基本图形或“形状”如线、弧、路径和文本绘制任意图形。
示例
基本用法
import math
import flet as ft
import flet.canvas as cv
def main(page: ft.Page):
stroke_paint = ft.Paint(stroke_width=2, style=ft.PaintingStyle.STROKE)
fill_paint = ft.Paint(style=ft.PaintingStyle.FILL)
cp = cv.Canvas(
[
cv.Circle(100, 100, 50, stroke_paint),
cv.Circle(80, 90, 10, stroke_paint),
cv.Circle(84, 87, 5, fill_paint),
cv.Circle(120, 90, 10, stroke_paint),
cv.Circle(124, 87, 5, fill_paint),
cv.Arc(70, 95, 60, 40, 0, math.pi, paint=stroke_paint),
],
width=float("inf"),
expand=True,
)
page.add(cp)
ft.app(main)
路径
形状示例
import math
import flet as ft
import flet.canvas as cv
def main(page: ft.Page):
cp = cv.Canvas(
[
cv.Path(
[
cv.Path.MoveTo(25, 25),
cv.Path.LineTo(105, 25),
cv.Path.LineTo(25, 105),
],
paint=ft.Paint(
style=ft.PaintingStyle.FILL,
),
),
cv.Path(
[
cv.Path.MoveTo(125, 125),
cv.Path.LineTo(125, 45),
cv.Path.LineTo(45, 125),
cv.Path.Close(),
],
paint=ft.Paint(
stroke_width=2,
style=ft.PaintingStyle.STROKE,
),
),
],
width=float("inf"),
expand=True,
)
page.add(cp)
ft.app(main)
贝塞尔曲线
import math
import flet as ft
import flet.canvas as cv
def main(page: ft.Page):
cp = cv.Canvas(
[
cv.Path(
[
cv.Path.MoveTo(75, 25),
cv.Path.QuadraticTo(25, 25, 25, 62.5),
cv.Path.QuadraticTo(25, 100, 50, 100),
cv.Path.QuadraticTo(50, 120, 30, 125),
cv.Path.QuadraticTo(60, 120, 65, 100),
cv.Path.QuadraticTo(125, 100, 125, 62.5),
cv.Path.QuadraticTo(125, 25, 75, 25),
],
paint=ft.Paint(
stroke_width=2,
style=ft.PaintingStyle.STROKE,
),
),
cv.Path(
[
cv.Path.SubPath(
[
cv.Path.MoveTo(75, 40),
cv.Path.CubicTo(75, 37, 70, 25, 50, 25),
cv.Path.CubicTo(20, 25, 20, 62.5, 20, 62.5),
cv.Path.CubicTo(20, 80, 40, 102, 75, 120),
cv.Path.CubicTo(110, 102, 130, 80, 130, 62.5),
cv.Path.CubicTo(130, 62.5, 130, 25, 100, 25),
cv.Path.CubicTo(85, 25, 75, 37, 75, 40),
],
100,
100,
)
],
paint=ft.Paint(
gradient=ft.PaintRadialGradient(
ft.Offset(150, 150), 50, [ft.colors.PINK_100, ft.colors.PINK]
),
style=ft.PaintingStyle.FILL,
),
),
],
width=float("inf"),
expand=True,
)
page.add(cp)
ft.app(main)
绘制文本
import math
import flet as ft
import flet.canvas as cv
def main(page: ft.Page):
cp = cv.Canvas(
[
cv.Text(0, 0, "Just a text"),
cv.Circle(200, 100, 2, ft.Paint(color=ft.colors.RED)),
cv.Text(
200,
100,
"Rotated",
ft.TextStyle(weight=ft.FontWeight.BOLD, size=30),
spans=[
ft.TextSpan(
"around top_center",
ft.TextStyle(italic=True, color=ft.colors.GREEN, size=20),
)
],
alignment=ft.alignment.top_center,
rotate=math.pi * 0.15,
),
cv.Circle(400, 100, 2, ft.Paint(color=ft.colors.RED)),
cv.Text(
400,
100,
"Rotated around top_left",
ft.TextStyle(size=20),
alignment=ft.alignment.top_left,
rotate=math.pi * -0.15,
),
cv.Circle(600, 200, 2, ft.Paint(color=ft.colors.RED)),
cv.Text(
600,
200,
"Rotated around center",
ft.TextStyle(size=20),
alignment=ft.alignment.center,
rotate=math.pi / 2,
),
cv.Text(
300,
400,
"Limited to max_width and right-aligned.\nLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
text_align=ft.TextAlign.RIGHT,
max_width=400,
),
cv.Text(
200,
200,
"WOW!",
ft.TextStyle(
weight=ft.FontWeight.BOLD,
size=100,
foreground=ft.Paint(
gradient=ft.PaintLinearGradient(
(200, 200),
(300, 300),
colors=[ft.colors.YELLOW, ft.colors.RED],
),
),
),
),
cv.Text(
200,
200,
"WOW!",
ft.TextStyle(
weight=ft.FontWeight.BOLD,
size=100,
foreground=ft.Paint(
color=ft.colors.PINK,
stroke_width=6,
style=ft.PaintingStyle.STROKE,
stroke_join=ft.StrokeJoin.ROUND,
stroke_cap=ft.StrokeCap.ROUND,
),
),
),
],
width=float("inf"),
expand=True,
)
page.add(cp)
ft.app(main)
自由手绘工具 - 带手势检测器的画布
import flet as ft
import flet.canvas as cv
class State:
x: float
y: float
state = State()
def main(page: ft.Page):
page.title = "Flet Brush"
def pan_start(e: ft.DragStartEvent):
state.x = e.local_x
state.y = e.local_y
def pan_update(e: ft.DragUpdateEvent):
cp.shapes.append(
cv.Line(
state.x, state.y, e.local_x, e.local_y, paint=ft.Paint(stroke_width=3)
)
)
cp.update()
state.x = e.local_x
state.y = e.local_y
cp = cv.Canvas(
[
cv.Fill(
ft.Paint(
gradient=ft.PaintLinearGradient(
(0, 0), (600, 600), colors=[ft.colors.CYAN_50, ft.colors.GREY]
)
)
),
],
content=ft.GestureDetector(
on_pan_start=pan_start,
on_pan_update=pan_update,
drag_interval=10,
),
expand=False,
)
page.add(
ft.Container(
cp,
border_radius=5,
width=float("inf"),
expand=True,
)
)
ft.app(main)
Canvas
属性
resize_interval
on_resize
事件的采样间隔,以毫秒为单位。默认值为 0
- 在每次更改时调用 on_resize
。
shapes
在画布上绘制的 Shape
对象列表(见下文)。
Canvas
事件
on_resize
当画布的大小发生变化时触发。
事件对象 e
是 CanvasResizeEvent
类的实例,具有以下字段:
width
- 画布的新宽度。height
- 画布的新高度。
Arc
形状属性
绘制一个缩放以适应给定矩形的弧。
从椭圆上的 start_angle
弧度开始,直到椭圆上的 start_angle
+ sweep_angle
弧度结束,零弧度是椭圆右侧与椭圆中心水平线相交的点,正角度顺时针绕椭圆旋转。如果 use_center
为 True
,则弧回到中心,形成一个圆扇形。否则,弧不会闭合,形成一个圆段。
[图片] - https://api.flutter.dev/flutter/dart-ui/Canvas/drawArc.html
x
弧的左上点的 x 轴坐标。
y
弧的左上点的 y 轴坐标。
width
包含弧的椭圆的矩形的宽度。
height
包含弧的椭圆的矩形的高度。
start_angle
绘制弧的起始角度(以弧度为单位)。
sweep_angle
弧的长度(以弧度为单位)。
use_center
如果 use_center
为 True
,则弧回到中心,形成一个圆扇形。否则,弧不会闭合,形成一个圆段。
paint
绘制弧的样式。该属性的值是 Paint
类的实例。
Circle
形状属性
绘制一个圆。
x
圆心的 x 轴坐标。
y
圆心的 y 轴坐标。
radius
圆的半径。
paint
绘制圆的样式。该属性的值是 Paint
类的实例。
Color
形状属性
将给定的 color
涂在画布上,应用给定的 blend_mode
,其中给定颜色为源,背景为目标。
color
要涂在画布上的 颜色。
blend_mode
要应用的混合模式。
属性值为 BlendMode
枚举。
Fill
形状属性
用给定的 Paint
填充画布。
要用纯色和混合模式填充画布,请考虑使用 Color
形状。
paint
填充画布的样式。该属性的值是 Paint
类的实例。
Line
形状属性
使用给定的油漆在给定点之间绘制一条线。线条被描绘,Paint.style
的值被忽略。
x1
线条起点的 x 轴坐标。
y1
线条起点的 y 轴坐标。
x2
线条终点的 x 轴坐标。
y2
线条终点的 y 轴坐标。
paint
绘制线条的样式。该属性的值是 Paint
类的实例。
Oval
形状属性
使用给定的 Paint
绘制填充给定轴对齐矩形的轴对齐椭圆。椭圆是否填充或描边(或两者都有)由 Paint.style
控制。
x
椭圆左上角的 x 轴坐标。
y
椭圆左上角的 y 轴坐标。
width
包含椭圆的矩形的宽度。
height
包含椭圆的矩形的高度。
paint
绘制椭圆的样式。该属性的值是 Paint
类的实例。
Path
形状属性
使用给定的 Paint
绘制具有给定 elements
的路径。
是否填充或描边(或两者都有)由 Paint.style
控制。如果路径被填充,则其中的子路径隐式闭合(见 Path.Close
)。
elements
路径元素列表:
Path.MoveTo(x, y)
在给定点 (x
,y
) 开始新子路径。
Path.LineTo(x, y)
从当前点添加一条直线段到给定点 (x
,y
)。
Path.QuadraticTo(cp1x, cp1y, x, y, w)
添加一条从当前点到给定点 (x
,y
) 的贝塞尔曲线段,使用控制点 (cp1x
,cp1y
) 和权重 w
。如果权重大于 1,则曲线为双曲线;如果权重等于 1,则为抛物线;如果小于 1,则为椭圆。
Path.CubicTo(cp1x, cp1y, cp2x, cp2y, x, y)
添加一条从当前点到给 定点 (x
,y
) 的三次贝塞尔曲线段,使用控制点 (cp1x
,cp1y
) 和 (cp2x
,cp2y
)。
Path.SubPath(elements, x, y)
将 elements
描述的子路径添加到给定点 (x
,y
)。
Path.Arc(x, y, width, height, start_angle, sweep_angle)
添加一个新子路径,其中包含一个弧段,该弧段沿椭圆的边缘,椭圆由以 x
和 y
为左上角,宽度和高度为 width
和 height
的矩形限定,从 start_angle
弧度绕椭圆旋转到 start_angle
+ sweep_angle
弧度,零弧度是椭圆右侧与椭圆中心水平线相交的点,正角度顺时针绕椭圆旋转。
Path.ArcTo(x, y, radius, rotation, large_arc, clockwise)
附加最多四条加权为描述椭圆的圆锥曲线,半径为 radius
,旋转角度为 rotation
(以度为单位,顺时针方向)。
第一条曲线从路径的最后一点开始,最后一点结束于 x
和 y
。曲线按照 clockwise
(布尔值)和 large_arc
(布尔值)确定的方向跟随路径,以使得扫描角度始终小于 360 度。
如果半径为零或路径的最后一点为 (x
,y
),则附加一条简单的线段。如果两者都大于零但太小以描述一个弧,则半径被缩放以适应最后的路径点。
Path.Oval(x, y, width, height)
添加一个新子路径,该路径包含填充给定矩形的椭圆。
Path.Rect(x, y, width, height, border_radius)
添加一个矩形作为新子路径。
Path.Close
关闭最后的子路径,就像从当前点绘制了一条直线到子路径的第一个点。
paint
绘制路径的样式。该属性的值是 Paint
类的实例。
Points
形状属性
根据给定的 point_mode
绘制一系列点。
points
描述点的 ft.Offset
列表。
point_mode
定义绘制一组点时如何解释点列表。该值为 ft.PointMode
类型:
POINTS
- 单独绘制每个点。如果Paint.stroke_cap
是StrokeCap.ROUND
,则每个点绘制为一个直径为Paint.stroke_width
的圆,填充方式由Paint
描述(忽略Paint.style
)。否则,每个点绘制为边长为Paint.stroke_width
的轴对齐正方形,填充方式由Paint
描述(忽略Paint.style
)。LINES
- 将每两个点的序列绘制为一条线段。如果点的数量是奇数,则忽略最后一个点。线条的描绘方式由Paint
描述(忽略Paint.style
)。POLYGON
- 将整个点序列绘制为一条线。线条的描绘方式由Paint
描述(忽略Paint.style
)。
paint
绘制点的样式。该属性的值是 Paint
类的实例。
Rect
形状属性
绘制一个矩形。
x
矩形左上角的 x 轴坐标。
y
矩形左上角的 y 轴坐标。
width
矩形的宽度。
height
矩形的高度。
border_radius
矩形的边框半径,值为 ft.BorderRadius
类型。
paint
绘制矩形的样式。该属性的值是 Paint
类的实例。
Shadow
形状属性
为表示给定材料 elevation
的 path
绘制阴影。
如果遮挡物体不透明,则 transparent_occluder
参数应为 True
。
path
描述路径的 Path.PathElement
对象列表。
color
阴影的 颜色。
elevation
阴影的高度。
transparent_occluder
如果遮挡物体不透明,则为 True
。默认值为 False
。
Text
形状属性
在给定点 (x
, y
) 处绘制 text
和 style
。
x
文本对齐点的 x 轴坐标。
y
文本对齐点的 y 轴坐标。
text
要绘制的文本。
style
绘制 text
和 spans
的文本样式。该值为 ft.TextStyle
类的实例。
spans
构建富文本段落的 TextSpan
对象列表。
alignment
文本矩形内的一个点,用于确定其位置和旋转中心。
该值为 Alignment
类型。默认值为 ft.alignment.top_left
。
text_align
文本的水平对齐。属性值为 TextAlign
枚举。默认值为 LEFT
。
max_lines
绘制的最大行数。超出此数字的行将被静默丢弃。例如,如果 max_lines
为 1,则只渲染一行。如果 max_lines
为 None
,但 ellipsis
不为 None
,则超过宽度限制的行在第一行之后将被丢弃。
max_width
绘制文本的最大宽度。默认值为 None
- 无限大。
ellipsis
用于省略溢出文本的字符串。
rotate
文本的旋转角度(以弧度为单位)。文本绕由 alignment
确定的点旋转。参见上面的代码示例。