跳到主要内容

画布

画布是一种控件,用于使用一组基本图形或“形状”如线、弧、路径和文本绘制任意图形。

示例

在线示例

基本用法

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

当画布的大小发生变化时触发。

事件对象 eCanvasResizeEvent 类的实例

Arc 形状属性

绘制一个缩放以适应给定矩形的弧。

从椭圆上的 start_angle 弧度开始,直到椭圆上的 start_angle + sweep_angle 弧度结束,零弧度是椭圆右侧与椭圆中心水平线相交的点,正角度顺时针绕椭圆旋转。如果 use_centerTrue,则弧回到中心,形成一个圆扇形。否则,弧不会闭合,形成一个圆段。

[图片] - https://api.flutter.dev/flutter/dart-ui/Canvas/drawArc.html

x

弧的左上点的 x 轴坐标。

y

弧的左上点的 y 轴坐标。

width

包含弧的椭圆的矩形的宽度。

height

包含弧的椭圆的矩形的高度。

start_angle

绘制弧的起始角度(以弧度为单位)。

sweep_angle

弧的长度(以弧度为单位)。

use_center

如果 use_centerTrue,则弧回到中心,形成一个圆扇形。否则,弧不会闭合,形成一个圆段。

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)

添加一个新子路径,其中包含一个弧段,该弧段沿椭圆的边缘,椭圆由以 xy 为左上角,宽度和高度为 widthheight 的矩形限定,从 start_angle 弧度绕椭圆旋转到 start_angle + sweep_angle 弧度,零弧度是椭圆右侧与椭圆中心水平线相交的点,正角度顺时针绕椭圆旋转。

Path.ArcTo(x, y, radius, rotation, large_arc, clockwise)

附加最多四条加权为描述椭圆的圆锥曲线,半径为 radius,旋转角度为 rotation(以度为单位,顺时针方向)。

第一条曲线从路径的最后一点开始,最后一点结束于 xy。曲线按照 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

定义绘制一组点时如何解释点列表。该值为PointMode.

paint

绘制点的样式。该属性的值是 Paint 类的实例。

Rect 形状属性

绘制一个矩形。

x

矩形左上角的 x 轴坐标。

y

矩形左上角的 y 轴坐标。

width

矩形的宽度。

height

矩形的高度。

border_radius

矩形的边框半径,值为 BorderRadius 类型。

paint

绘制矩形的样式。该属性的值是 Paint 类的实例。

Shadow 形状属性

为表示给定材料 elevationpath 绘制阴影。

如果遮挡物体不透明,则 transparent_occluder 参数应为 True

path

描述路径的 Path.PathElement 对象列表。

color

阴影的 颜色

elevation

阴影的高度。

transparent_occluder

如果遮挡物体不透明,则为 True。默认值为 False

Text 形状属性

在给定点 (x, y) 处绘制 textstyle

x

文本对齐点的 x 轴坐标。

y

文本对齐点的 y 轴坐标。

text

要绘制的文本。

style

绘制 textspans 的文本样式。该值为 TextStyle 类的实例。

spans

构建富文本段落的 TextSpan 对象列表。

alignment

文本矩形内的一个点,用于确定其位置和旋转中心。

该值为 Alignment 类型。默认值为 ft.alignment.top_left

text_align

文本的水平对齐。属性值为 TextAlign 。默认值为 LEFT

max_lines

绘制的最大行数。超出此数字的行将被静默丢弃。例如,如果 max_lines 为 1,则只渲染一行。如果 max_linesNone,但 ellipsis 不为 None,则超过宽度限制的行在第一行之后将被丢弃。

max_width

绘制文本的最大宽度。默认值为 None - 无限大。

ellipsis

用于省略溢出文本的字符串。

rotate

文本的旋转角度(以弧度为单位)。文本绕由 alignment 确定的点旋转。参见上面的代码示例。