组件工坊:Reflex 组件库 100 例
·
课程概览
布局
·
Box
·
Flex
·
Stack
·
Grid
·
Container
·
Section
·
Center
·
Spacer
·
Separator
·
Card
·
Inset
·
Aspect Ratio
·
Fragment
排版
·
Text
·
Heading
·
Link
·
Code
·
Markdown
·
Blockquote
·
Quote
·
Strong
·
Em
·
Kbd
表单
·
Button
·
Input
·
Text Area
·
Checkbox
·
Switch
·
Radio Group
·
Select
·
Slider
·
Form
·
Upload
数据展示
·
Badge
·
Avatar
·
Icon
·
Callout
·
List
·
Data List
·
Code Block
·
Progress
·
Spinner
·
Scroll Area
·
Moment
展开与切换
·
Tabs
·
Accordion
·
Segmented Control
浮层
·
Tooltip
·
Popover
·
Hover Card
·
Dialog
·
Alert Dialog
·
Drawer
·
Dropdown Menu
·
Context Menu
·
Toast
动态渲染
·
Cond
·
Match
·
Foreach
·
Auto Scroll
媒体
·
Image
·
Audio
·
Video
表格与数据网格
·
Table
·
Data Table
·
Data Editor
图表
·
Area Chart
·
Bar Chart
·
Line Chart
·
Composed Chart
·
Pie Chart
·
Radar Chart
·
Radial Bar Chart
·
Scatter Chart
·
Funnel Chart
·
Treemap
·
Sankey Chart
·
Error Bar
图表部件
·
Axis
·
Cartesian Grid
·
Chart Tooltip
·
Legend
·
Label
·
Reference
·
Brush
其他图表库
·
Plotly
·
Pyplot
HTML 元素
·
HTML
·
HTML Text
·
HTML Layout
·
HTML Forms
·
HTML Media
·
HTML Tables
·
SVG
其他工具
·
Theme
·
Skeleton
·
Clipboard
·
Html Embed
·
Script
·
Memo
rx.el.svgrx.el.svg.circlerx.el.svg.defsrx.el.svg.linear_gradientrx.el.svg.polygonrx.el.svg.pathrx.el.svg.rectrx.el.svg.stop官方文档
工坊订单
画一个认证徽章:渐变圆上放一颗星,星上再加一个对勾。不用图片文件,用代码画出来。
SVG 是用坐标绘制的矢量图。放得再大也不会模糊,还能用代码改变形状和颜色。
rx.el.svg 是画布,里面的图形放在 rx.el.svg 命名空间下,比如 rx.el.svg.circle、rx.el.svg.rect。
rx.el.svg(
rx.el.svg.circle(cx=50, cy=50, r=40, fill=rx.color("indigo", 9)),
view_box="0 0 100 100",
width="100",
height="100",
)图形用位置·尺寸属性决定形状,用 fill(填充)·stroke(描边)决定颜色。值是 view_box 坐标系里的数字。
试着改属性
rect_width
corner
radius
fill
stroke
stroke_width
rx.el.svg(
rx.el.svg.rect(
x="10",
y="10",
width="100",
height="80",
rx="10",
fill="#6e56cf",
stroke="none",
stroke_width="4",
),
rx.el.svg.circle(cx="160", cy="50", r="35", fill="#6e56cf", fill_opacity="0.6", stroke="none", stroke_width="4"),
view_box="0 0 220 100",
width="264",
height="120",
)| 属性 | 取值 | 默认值 | 用途 |
|---|---|---|---|
view_box width height (svg) | "0 0 100 100" / 长度 | 无 | 图形的坐标系与显示尺寸 |
preserve_aspect_ratio (svg) | "xMidYMid meet" "none" … | "xMidYMid meet" | 比例不一致时的适配方式 |
cx cy r (circle) | 数字 | 0 | 圆心与半径 |
x y width height rx ry (rect) | 数字 | 0 | 位置、尺寸、圆角。只给 rx 时 ry 相同 |
points (polygon) | "x,y x,y …" | 无 | 顶点列表,终点自动闭合 |
d (path) | 路径命令 | 无 | M 移动、L 直线、Q·C 曲线、Z 闭合 |
path_length(图形通用) | 数字 | 实际长度 | 把线长视为这个值(用于计算虚线) |
id x1 y1 x2 y2 (linear_gradient) | 字符串·数字 | 从左到右 | 渐变的名字与方向 |
gradient_units gradient_transform spread_method href (linear_gradient) | 字符串 | 无 | 坐标基准、变换、末端处理、继承其他渐变 |
offset stop_color stop_opacity (stop) | "0%""100%" / 颜色 / 0 | 无 | 颜色的位置与颜色 |
fill stroke stroke_width … | 颜色·数字 | 黑色填充 | 不是图形的专属属性,而是作为 CSS 传入(见下文) |
view_box="0 0 100 100" 表示“内部坐标宽高都是 100”,width·height 是在屏幕上的尺寸。同一张图只改尺寸,画出来依然清晰。
比例不一致时,默认居中缩小;preserve_aspect_ratio="none" 时拉伸填满(第三张图)。
rx.el.div(
rx.el.svg(
rx.el.svg.rect(x=0, y=0, width=100, height=100, fill=rx.color("gray", 4)),
rx.el.svg.circle(cx=50, cy=50, r=30, fill=rx.color("tomato", 9)),
view_box="0 0 100 100",
width="60",
height="60",
),
rx.el.svg(
rx.el.svg.rect(x=0, y=0, width=100, height=100, fill=rx.color("gray", 4)),
rx.el.svg.circle(cx=50, cy=50, r=30, fill=rx.color("tomato", 9)),
view_box="0 0 100 100",
width="120",
height="120",
),
rx.el.svg(
rx.el.svg.rect(x=0, y=0, width=100, height=100, fill=rx.color("gray", 4)),
rx.el.svg.circle(cx=50, cy=50, r=30, fill=rx.color("tomato", 9)),
view_box="0 0 100 100",
preserve_aspect_ratio="none",
width="200",
height="80",
),
display="flex",
gap="16px",
align_items="end",
)rect、circle、polygon 是官方文档里出现的图形,Reflex 0.10 还多了 ellipse、line、polyline、g、text 等元素。
在 0.10 中,fill·stroke·stroke_width 不在图形的属性列表里,所以会作为 CSS 传入。SVG 的颜色属性用 CSS 写效果完全一样,结果相同,还能用 rx.color(...) 这类主题色。
rx.el.svg(
rx.el.svg.rect(x=10, y=20, width=60, height=60, rx=12, fill=rx.color("teal", 9)),
rx.el.svg.circle(cx=120, cy=50, r=30, fill=rx.color("amber", 9)),
rx.el.svg.polygon(points="200,20 230,80 170,80", fill=rx.color("crimson", 9)),
rx.el.svg.ellipse(cx=290, cy=50, rx=40, ry=22, fill=rx.color("blue", 9)),
rx.el.svg.line(x1=10, y1=95, x2=330, y2=95, stroke="gray", stroke_width=2),
view_box="0 0 340 100",
width="340",
height="100",
)在 d 里连续写命令。M10 80 移动画笔,Q 是二次曲线,T 平滑地接上前一段曲线。只画线条就用 fill="none"。
path_length=100 让线长被视为 100,这样 stroke_dasharray="10 5" 这类虚线就容易按比例计算。
rx.el.svg(
rx.el.svg.path(
d="M10 80 Q 55 10, 100 80 T 190 80",
fill="none",
stroke=rx.color("indigo", 9),
stroke_width=4,
),
rx.el.svg.path(
d="M10 95 L 190 95",
path_length=100,
stroke="gray",
stroke_width=3,
stroke_dasharray="10 5",
),
view_box="0 0 200 100",
width="300",
height="150",
)放在 defs 里的东西不会直接画出来,而是成为按名字(id)调用的素材。linear_gradient 的 x1·y1→x2·y2 是方向,stop 是颜色所在的位置。
给图形的 fill 设置 "url(#id)",就会用渐变上色。id 在页面内不要重复。
rx.el.svg(
rx.el.svg.defs(
rx.el.svg.linear_gradient(
rx.el.svg.stop(offset="0%", stop_color="#6e56cf"),
rx.el.svg.stop(offset="100%", stop_color="#e54d2e", stop_opacity="0.8"),
id="htmlsvg_sunset",
x1="0",
y1="0",
x2="1",
y2="1",
),
),
rx.el.svg.rect(x=0, y=0, width=200, height=100, rx=16, fill="url(#htmlsvg_sunset)"),
view_box="0 0 200 100",
width="240",
height="120",
)把 State 的值放进图形属性,图形就会跟着数据变化。这里用 rx.foreach 的第二个参数(序号)计算柱子的 x。
import random
class HtmlSvgBarState(rx.State):
values: list[int] = [40, 75, 55, 90, 30]
@rx.event
def shuffle(self):
self.values = [random.randint(10, 95) for _ in self.values]
rx.el.div(
rx.el.svg(
rx.foreach(
HtmlSvgBarState.values,
lambda v, i: rx.el.svg.rect(x=i * 40 + 10, y=100 - v, width=28, height=v, rx=4, fill=rx.color("grass", 9)),
),
view_box="0 0 210 100",
width="210",
height="100",
),
rx.el.button("Shuffle", on_click=HtmlSvgBarState.shuffle, padding="4px 12px", border="1px solid gray", border_radius="6px", margin_top="8px"),
)用 defs 里的渐变给圆上色,用 10 个顶点的 polygon 画星,再叠上一条末端圆润的 path 作为对勾。
rx.el.svg(
rx.el.svg.defs(
rx.el.svg.linear_gradient(
rx.el.svg.stop(offset="0%", stop_color="#3e63dd"),
rx.el.svg.stop(offset="100%", stop_color="#12a594"),
id="htmlsvg_badge",
x1="0",
y1="0",
x2="0",
y2="1",
),
),
rx.el.svg.circle(cx=60, cy=60, r=56, fill="url(#htmlsvg_badge)"),
rx.el.svg.polygon(points="60,18 70,44 98,46 76,63 84,90 60,75 36,90 44,63 22,46 50,44", fill="#ffd60a"),
rx.el.svg.path(d="M44 62 L56 74 L78 50", fill="none", stroke="white", stroke_width=6, stroke_linecap="round", stroke_linejoin="round"),
view_box="0 0 120 120",
width="120",
height="120",
)工坊笔记
rx.el.svg 是画布:view_box 是内部坐标,width·height 是屏幕尺寸。
图形有 rx.el.svg.rect·circle·polygon·path,0.10 还有 ellipse·line·g·text。
fill·stroke 在 0.10 中作为 CSS 传入,但结果相同。也能用主题色 rx.color。
渐变是 defs > linear_gradient(id) > stop,使用处写 fill="url(#id)"。
把 State 值放进属性、用 rx.foreach 生成图形,就成了数据图。
订阅新课时和新课程通知
本课程新增课时或推出后续课程时,我们会发邮件通知你。
问答
关于本课有任何疑问都可以在这里留言。所有语言版本页面的提问会汇集在一起。