from nbdev.showdoc import show_docSVG
你可以直接从字符串创建SVG,比如(和往常一样,使用 NotStr 或 Safe 告诉FastHTML不要转义文本):
svg = '<svg width="50" height="50"><circle cx="20" cy="20" r="15" fill="red"></circle></svg>'
show(NotStr(svg))你也可以使用像 fa6-icons 这样的库。
要使用Python API创建和修改SVG,请使用下面讨论的fasthtml.svg中的FT元素。
注意: fasthtml.common 不会自动导出 SVG 元素。要访问它们,您需要像这样导入 fasthtml.svg
from fasthtml.svg import *矢量图形
Svg (*args, viewBox=None, h=None, w=None, height=None, width=None, xmlns='http://www.w3.org/2000/svg', **kwargs)
一个SVG标签;xmlns会自动添加,如果未提供,viewBox默认为高度和宽度
要创建您自己的SVG,请使用 SVG。如果没有提供,系统会自动根据高度和宽度设置 viewBox。
我们所有的形状将通过使用 ft_svg 添加一些方便的kwargs:
ft_svg
ft_svg (tag:str, *c, transform=None, opacity=None, clip=None, mask=None, filter=None, vector_effect=None, pointer_events=None, target_id=None, hx_vals=None, hx_target=None, id=None, cls=None, title=None, style=None, accesskey=None, contenteditable=None, dir=None, draggable=None, enterkeyhint=None, hidden=None, inert=None, inputmode=None, lang=None, popover=None, spellcheck=None, tabindex=None, translate=None, hx_get=None, hx_post=None, hx_put=None, hx_delete=None, hx_patch=None, hx_trigger=None, hx_swap=None, hx_swap_oob=None, hx_include=None, hx_select=None, hx_select_oob=None, hx_indicator=None, hx_push_url=None, hx_confirm=None, hx_disable=None, hx_replace_url=None, hx_disabled_elt=None, hx_ext=None, hx_headers=None, hx_history=None, hx_history_elt=None, hx_inherit=None, hx_params=None, hx_preserve=None, hx_prompt=None, hx_request=None, hx_sync=None, hx_validate=None)
创建一个具有一些特定于SVG的属性的标准 FT 元素
基本形状
我们将定义一个简单的函数来在本笔记本中显示SVG形状:
def demo(el, h=50, w=50): return show(Svg(h=h,w=w)(el))矩形
Rect (width, height, x=0, y=0, fill=None, stroke=None, stroke_width=None, rx=None, ry=None, transform=None, opacity=None, clip=None, mask=None, filter=None, vector_effect=None, pointer_events=None, target_id=None, hx_vals=None, hx_target=None, id=None, cls=None, title=None, style=None, accesskey=None, contenteditable=None, dir=None, draggable=None, enterkeyhint=None, hidden=None, inert=None, inputmode=None, lang=None, popover=None, spellcheck=None, tabindex=None, translate=None, hx_get=None, hx_post=None, hx_put=None, hx_delete=None, hx_patch=None, hx_trigger=None, hx_swap=None, hx_swap_oob=None, hx_include=None, hx_select=None, hx_select_oob=None, hx_indicator=None, hx_push_url=None, hx_confirm=None, hx_disable=None, hx_replace_url=None, hx_disabled_elt=None, hx_ext=None, hx_headers=None, hx_history=None, hx_history_elt=None, hx_inherit=None, hx_params=None, hx_preserve=None, hx_prompt=None, hx_request=None, hx_sync=None, hx_validate=None)
一个标准的 SVG rect 元素
我们所有的形状只是创建常规 FT 元素。大多数形状提供的唯一额外功能是添加额外定义的关键字参数以改善IDE和笔记本中的自动完成,并重新排列参数,以便也可以使用位置参数来节省一些输入,例如:
demo(Rect(30, 30, fill='blue', rx=8, ry=8))圆
Circle (r, cx=0, cy=0, fill=None, stroke=None, stroke_width=None, transform=None, opacity=None, clip=None, mask=None, filter=None, vector_effect=None, pointer_events=None, target_id=None, hx_vals=None, hx_target=None, id=None, cls=None, title=None, style=None, accesskey=None, contenteditable=None, dir=None, draggable=None, enterkeyhint=None, hidden=None, inert=None, inputmode=None, lang=None, popover=None, spellcheck=None, tabindex=None, translate=None, hx_get=None, hx_post=None, hx_put=None, hx_delete=None, hx_patch=None, hx_trigger=None, hx_swap=None, hx_swap_oob=None, hx_include=None, hx_select=None, hx_select_oob=None, hx_indicator=None, hx_push_url=None, hx_confirm=None, hx_disable=None, hx_replace_url=None, hx_disabled_elt=None, hx_ext=None, hx_headers=None, hx_history=None, hx_history_elt=None, hx_inherit=None, hx_params=None, hx_preserve=None, hx_prompt=None, hx_request=None, hx_sync=None, hx_validate=None)
一个标准的 SVG circle 元素
demo(Circle(20, 25, 25, stroke='red', stroke_width=3))椭圆
Ellipse (rx, ry, cx=0, cy=0, fill=None, stroke=None, stroke_width=None, transform=None, opacity=None, clip=None, mask=None, filter=None, vector_effect=None, pointer_events=None, target_id=None, hx_vals=None, hx_target=None, id=None, cls=None, title=None, style=None, accesskey=None, contenteditable=None, dir=None, draggable=None, enterkeyhint=None, hidden=None, inert=None, inputmode=None, lang=None, popover=None, spellcheck=None, tabindex=None, translate=None, hx_get=None, hx_post=None, hx_put=None, hx_delete=None, hx_patch=None, hx_trigger=None, hx_swap=None, hx_swap_oob=None, hx_include=None, hx_select=None, hx_select_oob=None, hx_indicator=None, hx_push_url=None, hx_confirm=None, hx_disable=None, hx_replace_url=None, hx_disabled_elt=None, hx_ext=None, hx_headers=None, hx_history=None, hx_history_elt=None, hx_inherit=None, hx_params=None, hx_preserve=None, hx_prompt=None, hx_request=None, hx_sync=None, hx_validate=None)
一个标准的 SVG ellipse 元素
demo(Ellipse(20, 10, 25, 25))变换的
transformd (translate=None, scale=None, rotate=None, skewX=None, skewY=None, matrix=None)
创建一个 SVG transform 关键字参数字典
rot = transformd(rotate=(45, 25, 25))
rot{'transform': 'rotate(45,25,25)'}
demo(Ellipse(20, 10, 25, 25, **rot))线路
Line (x1, y1, x2=0, y2=0, stroke='black', w=None, stroke_width=1, transform=None, opacity=None, clip=None, mask=None, filter=None, vector_effect=None, pointer_events=None, target_id=None, hx_vals=None, hx_target=None, id=None, cls=None, title=None, style=None, accesskey=None, contenteditable=None, dir=None, draggable=None, enterkeyhint=None, hidden=None, inert=None, inputmode=None, lang=None, popover=None, spellcheck=None, tabindex=None, translate=None, hx_get=None, hx_post=None, hx_put=None, hx_delete=None, hx_patch=None, hx_trigger=None, hx_swap=None, hx_swap_oob=None, hx_include=None, hx_select=None, hx_select_oob=None, hx_indicator=None, hx_push_url=None, hx_confirm=None, hx_disable=None, hx_replace_url=None, hx_disabled_elt=None, hx_ext=None, hx_headers=None, hx_history=None, hx_history_elt=None, hx_inherit=None, hx_params=None, hx_preserve=None, hx_prompt=None, hx_request=None, hx_sync=None, hx_validate=None)
一个标准的SVG line 元素
demo(Line(20, 30, w=3))折线
Polyline (*args, points=None, fill=None, stroke=None, stroke_width=None, transform=None, opacity=None, clip=None, mask=None, filter=None, vector_effect=None, pointer_events=None, target_id=None, hx_vals=None, hx_target=None, id=None, cls=None, title=None, style=None, accesskey=None, contenteditable=None, dir=None, draggable=None, enterkeyhint=None, hidden=None, inert=None, inputmode=None, lang=None, popover=None, spellcheck=None, tabindex=None, translate=None, hx_get=None, hx_post=None, hx_put=None, hx_delete=None, hx_patch=None, hx_trigger=None, hx_swap=None, hx_swap_oob=None, hx_include=None, hx_select=None, hx_select_oob=None, hx_indicator=None, hx_push_url=None, hx_confirm=None, hx_disable=None, hx_replace_url=None, hx_disabled_elt=None, hx_ext=None, hx_headers=None, hx_history=None, hx_history_elt=None, hx_inherit=None, hx_params=None, hx_preserve=None, hx_prompt=None, hx_request=None, hx_sync=None, hx_validate=None)
一个标准的SVG polyline 元素
demo(Polyline((0,0), (10,10), (20,0), (30,10), (40,0),
fill='yellow', stroke='blue', stroke_width=2))demo(Polyline(points='0,0 10,10 20,0 30,10 40,0', fill='purple', stroke_width=2))多边形
Polygon (*args, points=None, fill=None, stroke=None, stroke_width=None, transform=None, opacity=None, clip=None, mask=None, filter=None, vector_effect=None, pointer_events=None, target_id=None, hx_vals=None, hx_target=None, id=None, cls=None, title=None, style=None, accesskey=None, contenteditable=None, dir=None, draggable=None, enterkeyhint=None, hidden=None, inert=None, inputmode=None, lang=None, popover=None, spellcheck=None, tabindex=None, translate=None, hx_get=None, hx_post=None, hx_put=None, hx_delete=None, hx_patch=None, hx_trigger=None, hx_swap=None, hx_swap_oob=None, hx_include=None, hx_select=None, hx_select_oob=None, hx_indicator=None, hx_push_url=None, hx_confirm=None, hx_disable=None, hx_replace_url=None, hx_disabled_elt=None, hx_ext=None, hx_headers=None, hx_history=None, hx_history_elt=None, hx_inherit=None, hx_params=None, hx_preserve=None, hx_prompt=None, hx_request=None, hx_sync=None, hx_validate=None)
一个标准的 SVG polygon 元素
demo(Polygon((25,5), (43.3,15), (43.3,35), (25,45), (6.7,35), (6.7,15),
fill='lightblue', stroke='navy', stroke_width=2))demo(Polygon(points='25,5 43.3,15 43.3,35 25,45 6.7,35 6.7,15',
fill='lightgreen', stroke='darkgreen', stroke_width=2))文本
Text (*args, x=0, y=0, font_family=None, font_size=None, fill=None, text_anchor=None, dominant_baseline=None, font_weight=None, font_style=None, text_decoration=None, transform=None, opacity=None, clip=None, mask=None, filter=None, vector_effect=None, pointer_events=None, target_id=None, hx_vals=None, hx_target=None, id=None, cls=None, title=None, style=None, accesskey=None, contenteditable=None, dir=None, draggable=None, enterkeyhint=None, hidden=None, inert=None, inputmode=None, lang=None, popover=None, spellcheck=None, tabindex=None, translate=None, hx_get=None, hx_post=None, hx_put=None, hx_delete=None, hx_patch=None, hx_trigger=None, hx_swap=None, hx_swap_oob=None, hx_include=None, hx_select=None, hx_select_oob=None, hx_indicator=None, hx_push_url=None, hx_confirm=None, hx_disable=None, hx_replace_url=None, hx_disabled_elt=None, hx_ext=None, hx_headers=None, hx_history=None, hx_history_elt=None, hx_inherit=None, hx_params=None, hx_preserve=None, hx_prompt=None, hx_request=None, hx_sync=None, hx_validate=None)
一个标准的SVG text 元素
demo(Text("Hello!", x=10, y=30))路径
SVG中的路径更为复杂,因此我们添加了一个小的(可选的)流畅接口来构造它们:
路径FT
PathFT (tag:str, cs:tuple, attrs:dict=None, void_=False, **kwargs)
一个“快速标签”结构,包含 tag,children和 attrs
路径
Path (d='', fill=None, stroke=None, stroke_width=None, transform=None, opacity=None, clip=None, mask=None, filter=None, vector_effect=None, pointer_events=None, target_id=None, hx_vals=None, hx_target=None, id=None, cls=None, title=None, style=None, accesskey=None, contenteditable=None, dir=None, draggable=None, enterkeyhint=None, hidden=None, inert=None, inputmode=None, lang=None, popover=None, spellcheck=None, tabindex=None, translate=None, hx_get=None, hx_post=None, hx_put=None, hx_delete=None, hx_patch=None, hx_trigger=None, hx_swap=None, hx_swap_oob=None, hx_include=None, hx_select=None, hx_select_oob=None, hx_indicator=None, hx_push_url=None, hx_confirm=None, hx_disable=None, hx_replace_url=None, hx_disabled_elt=None, hx_ext=None, hx_headers=None, hx_history=None, hx_history_elt=None, hx_inherit=None, hx_params=None, hx_preserve=None, hx_prompt=None, hx_request=None, hx_sync=None, hx_validate=None)
创建一个标准 path SVG 元素。这是一个特殊的对象
让我们创建一个正方形形状,但使用 Path 而不是 Rect:
- M(10, 10): 移动到起始点 (10, 10)
- L(40, 10): 直线到 (40, 10) - 顶边
- L(40, 40): 线到 (40, 40) - 右边缘
- L(10, 40): 画线到 (10, 40) - 底边
- Z(): 关闭路径 - 连接回起点
M = 移动到, L = 线条到, Z = 关闭路径
demo(Path(fill='none', stroke='purple', stroke_width=2
).M(10, 10).L(40, 10).L(40, 40).L(10, 40).Z())使用曲线我们可以创建一个螺旋:
p = (Path(fill='none', stroke='purple', stroke_width=2)
.M(25, 25)
.C(25, 25, 20, 20, 30, 20)
.C(40, 20, 40, 30, 30, 30)
.C(20, 30, 20, 15, 35, 15)
.C(50, 15, 50, 35, 25, 35)
.C(0, 35, 0, 10, 40, 10)
.C(80, 10, 80, 40, 25, 40))
demo(p, 50, 100)使用弧线和曲线我们可以创建一个地图标记图标:
p = (Path(fill='red')
.M(25,45)
.C(25,45,10,35,10,25)
.A(15,15,0,1,1,40,25)
.C(40,35,25,45,25,45)
.Z())
demo(p)在幕后,它只是创建常规的 SVG 路径 d 属性 - 如果你愿意,可以直接传递 d。
print(p.d) M25 45 C25 45 10 35 10 25 A15 15 0 1 1 40 25 C40 35 25 45 25 45 Z
demo(Path(d='M25 45 C25 45 10 35 10 25 A15 15 0 1 1 40 25 C40 35 25 45 25 45 Z'))路径FT.M
PathFT.M (x, y)
移动到。
路径FT.L
PathFT.L (x, y)
行到。
路径FT.H
PathFT.H (x)
水平线到。
路径FT.V
PathFT.V (y)
垂直线到。
路径FT.Z
PathFT.Z ()
关闭路径。
PathFT.C
PathFT.C (x1, y1, x2, y2, x, y)
三次贝塞尔曲线。
路径FT.S
PathFT.S (x2, y2, x, y)
平滑的三次Bézier曲线。
路径FT.Q
PathFT.Q (x1, y1, x, y)
二次贝塞尔曲线。
PathFT.T
PathFT.T (x, y)
平滑的二次贝塞尔曲线。
路径FT.A
PathFT.A (rx, ry, x_axis_rotation, large_arc_flag, sweep_flag, x, y)
椭圆弧。
HTMX助手
SvgOob
SvgOob (*args, **kwargs)
根据HTMX OOB交换的要求包装SVG形状
在HTMX中以带外(OOB)方式返回SVG形状时,您需要使用SvgOob将其包装起来,以使其正确显示。 (SvgOob只是Template(Svg(...))的简写,这是使SVG OOB交换工作的技巧。)
SvgInb
SvgInb (*args, **kwargs)
根据HTMX的内部交换要求包装SVG形状
在HTMX中以带内形式返回SVG形状时,可以让调用元素包含 hx_select='svg>*',或 **svg_inb(这两种方式表达的是同一个意思),或者使用 SvgInb 将响应包裹起来,使其正确显示。 (SvgInb 只是元组 (Svg(...), HtmxResponseHeaders(hx_reselect='svg>*')) 的快捷方式,这个技巧使得SVG带内交换得以实现。)