import mathcore
__file__='../fastlucide/_icons.py'read_icons
def read_icons(
):
icons = read_icons()nm = 'a-arrow-down'
ico = icons[nm]
ico[['path', {'d': 'M3.5 13h6'}],
['path', {'d': 'm2 16 4.5-9 4.5 9'}],
['path', {'d': 'M18 7v9'}],
['path', {'d': 'm14 12 4 4 4-4'}]]
svg_attrs = dict(fill='none', stroke='currentColor', stroke_width='2', stroke_linecap='round', stroke_linejoin='round')sz_attrs
def sz_attrs(
sz, vbox:int=24
):
sym = [ft(t, **attrs) for t,attrs in ico]
show(Svg(*sym, **sz_attrs(24), **svg_attrs))
show(Svg(*sym, **sz_attrs(16), **svg_attrs))symbol
def symbol(
icons, # icon dict
nm, # Name of icon in lucide
pre:str='', # Prefix to add to element id
):
Create a symbol element for an icon
symbol(icons, nm, 'l-')<symbol id="l-a-arrow-down"><path d="M3.5 13h6"></path><path d="m2 16 4.5-9 4.5 9"></path><path d="M18 7v9"></path><path d="m14 12 4 4 4-4"></path></symbol>sprites
def sprites(
icons, # icon dict
nms, # List of lucide icon names
pre:str='', # Prefix to add to all element ids
):
SVG element containing all symbols in nms
sps = sprites(icons, [nm, 'accessibility'], 'l-')
show(sps)Icon
def Icon(
nm, # Name of icon in lucide
pre:str='', # Prefix to add to element id
cls:str='lucide-icon', # class to use for svg
vbox:int=24, # viewBox size (int for square, or (w,h) tuple)
sz:int=24, # size of svg
stroke:NoneType=None, # Stroke CSS
stroke_width:NoneType=None, # Stroke width CSS
fill:NoneType=None, # Fill CSS
trans:NoneType=None, # SVG transform attribute
attrs:VAR_KEYWORD
):
A use element in an svg element refering to nm
accs = Icon('accessibility', 'l-', sz=16)
accs<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" height="16px" width="16px" class="lucide-icon"><use href="#l-accessibility"></use></svg>print(accs(foo='bar'))<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" height="16px" width="16px" class="lucide-icon" foo="bar"><use href="#l-accessibility"></use></svg>
show(accs)show(Icon('accessibility', 'l-', sz=16, stroke_width=3))Transforms
Now let’s add a helper function to transform Icon’s with python object methods.
Using that we can define the six svg transforms as python instance methods.
Icon.rotate
def rotate(
a, cx:int=0, cy:int=0
):
Rotates the element by a degrees, optionally around point (cx, cy).
show(au:=Icon('arrow-up','l-'))
show(au.rotate(45,12,12))Icon.scale
def scale(
x, y:int=0
):
Scales the element by x (and optionally y).
Now we can also demonstrate transform chaining:
show(au)
show(au.scale(0.75,0.75))
show(au.scale(0.75,0.75).rotate(45,12,12))Continuing with the other transforms:
Icon.translate
def translate(
x, y:int=0
):
Moves the element by x horizontally and optionally y vertically.
show(au)
show(au.translate(-5,-5))Icon.skewY
def skewY(
a
):
Skews the element along the Y axis by a degrees.
Icon.skewX
def skewX(
a
):
Skews the element along the X axis by a degrees.
show(au)
show(au.skewX(20))
show(au.skewY(20))The matrix(a, b, c, d, e, f) transform combines all other transforms into one. The parameters map to:
a,d— scale X and Yb,c— skew Y and X
e,f— translate X and Y
Common patterns: - matrix(1, 0, 0, 1, tx, ty) — translate by (tx, ty) - matrix(sx, 0, 0, sy, 0, 0) — scale by (sx, sy) - matrix(1, tan(ay), tan(ax), 1, 0, 0) — skew by angles ax, ay
For more details see MDN SVG matrix transform docs.
Icon.matrix
def matrix(
a, b, c, d, e, f
):
Applies a matrix transformation with 6 values.
Examples showing their equivalence to the other transforms:
show(au.translate(5, 5))
show(au.matrix(1, 0, 0, 1, 5, 5))show(au.scale(0.7, 0.7))
show(au.matrix(0.7, 0, 0, 0.7, 0, 0))show(au.skewX(20))
show(au.matrix(1, 0, math.tan(math.radians(20)), 1, 0, 0))Combining icons
Icon.__add__
def __add__(
b
):
Icon.__iadd__
def __iadd__(
b
):
ad = Icon('a-arrow-down', 'l-')
show(accs+ad)sps = sprites(icons, [nm, 'accessibility', 'check', 'user', 'plus', 'circle', 'file', 'arrow-up'], 'l-')
show(sps)show(Icon('circle', 'l-', sz=24) + Icon('check', 'l-', stroke='red'))show(Icon('circle', 'l-', sz=24) + Icon('check', 'l-', stroke='red').translate(2,3).scale(0.8))show(Icon('user', 'l-', sz=24, stroke_width=1).translate(-4, 0) +
Icon('plus', 'l-', stroke_width=3).translate(9, 3).scale(0.6))show(Icon('file', 'l-', sz=24, fill='yellow') +
Icon('arrow-up', 'l-').translate(2,3).scale(0.7))Finally, lets show we can also apply transforms to combined icons by adding a skewX to the last icon:
show((Icon('file', 'l-', sz=24, fill='yellow') +
Icon('arrow-up', 'l-').translate(2,3).scale(0.7)).skewX(10))SvgStyle
def SvgStyle(
cls:str='lucide-icon'
):
Styles required for lucide icons to display correctly
SvgSprites
def SvgSprites(
pre:str='', vbox:int=24, sz:int=24, cls:str='lucide-icon', nms:tuple=(), attrs:VAR_KEYWORD
):
Create and track used icons
ss = SvgSprites('lc-', sz=18)
ss(nm)<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" height="18px" width="18px" class="lucide-icon "><use href="#lc-a-arrow-down"></use></svg>show(ss('a-arrow-down'))
show(ss('accessibility', stroke_width=3))
show(ss)show(Style('.hover-bg:hover { background-color: aliceblue; }'))
show(ss('accessibility', sz=30, cls='hover-bg'))show(ss('accessibility', stroke='blue'))show(Div(ss('accessibility', stroke='blue'), style='background-color: aliceblue'))ss = SvgSprites('lc-', sz=32)
show(ss('circle', stroke='steelblue') + ss('x', stroke='crimson'))show(ss('arrow-up').scale(0.7).translate(8,3) +
ss('zap', stroke='red').scale(0.5).translate(2, 19))
show(ss)show(ss('arrow-down').scale(0.7).translate(8,0) +
ss('zap', stroke='red').scale(0.5).translate(2, 19))
show(ss)