外观
样式与主题
Background、Border、Radius、Shadow 和 Opacity 为元素的盒子设置样式,Cursor 设定指针在其上方时的形状:
go
ui.Column(c).Padding(18).Gap(12).Radius(10).
Background(t.Background).Border(1, t.Border).
Shadow(0, 1, 3, 0, ui.RGBA(0, 0, 0, 0.06))边框。
Border(1, c)在每条边的内侧画线;BorderWidth可分别设置各边,如同 CSS,配合BorderColor,例如用BorderWidth(0, 0, 1, 0)画标题下的横线,BorderStyle(ui.BorderDashed)使其成为虚线。与 CSS 的box-sizing: border-box一样,边框占据元素尺寸之内的空间,内边距和子元素都在其内。阴影。
Shadow(x, y, blur, spread, c)投出盒阴影,如同 CSS 的box-shadow:多个阴影可叠加,每个只显示在盒子之外,因此半透明背景永远不会透出自身的阴影。InsetShadow(x, y, blur, spread, c)绘制内阴影,如同box-shadow: inset:位于盒子的内边距边缘之内、边框和圆角之内,背景之上、子元素之下;偏移使其移动,正的扩散值使其向内扩张。内阴影同样可以叠加,并可与外阴影共存,例如在深色中为输入框描一圈发丝般的边:gofield.Radius(12).Background(t.Surface). Shadow(0, 8, 24, 0, ui.RGBA(0, 0, 0, 0.3)). InsetShadow(0, 0, 1, 0, ui.RGBA(255, 255, 255, 0.2))渐变与条纹。
Gradient(from, to, angle)用线性渐变填充盒子;LinearGradient还可以沿直线放置颜色(Start、End),并在 Oklab 色彩空间中混合——它能保持颜色的明度——而非 sRGB,或者用Stops接受任意多个颜色,每个都是GradientStop{Color, At},At为 0 到 1 的位置。ConicGradient则让各个停靠点绕一个点旋转,如同 CSS 的conic-gradient()(SwiftUI 的AngularGradient):从Angle开始,以从正上方顺时针计的角度,绕Center旋转,未设置时为中心。BorderLinearGradient和BorderConicGradient用渐变绘制边框,代替边框颜色,如同 SwiftUI 中用渐变做的strokeBorder:gorainbow := []ui.GradientStop{{red, 0}, {yellow, 0.33}, {blue, 0.66}, {red, 1}} ui.Box(c).Size(120, 80).Radius(16).Border(4, ui.Color{}). BorderConicGradient(ui.ConicGradient{Stops: rainbow, Oklab: true})Stripes(c, width, gap, angle)在背景上绘制条纹,如同不可用内容上的条纹。绘制器也用同样的渐变填充矩形和路径(FillGradient、FillConicGradient、FillPathGradient、FillPathConicGradient、StrokePathConicGradient)。模糊。
Blur(sigma)模糊元素及其子元素,如同 CSS 的filter: blur():它们绘制的内容在 GPU 上向四周扩散约 3×sigma 个 DIP,超出部分透明。它们每绘制一帧都会先渲染到位图中,正如效果所做的那样;点击、焦点和辅助技术仍把元素当作在其原位。光晕就是模糊后的边框——一条清晰的边框叠上若干条模糊的边框:gofor _, l := range []struct{ width, blur float32 }{{6, 0}, {9, 4}, {15, 15}} { ui.Box(c).Absolute().Top(0).Left(0).Right(0).Bottom(0).PassThrough(). Radius(16).Border(l.width, ui.Color{}).BorderConicGradient(glow).Blur(l.blur) }缓存。
Cache()把元素及其子元素绘制的内容保存在 GPU 位图中,如同 Flutter 的RepaintBoundary和 SwiftUI 的drawingGroup(),只有当绘制内容发生变化时才重绘:其他内容变化、尺寸变化、窗口缩放或主题变化。于是一张由渐变、模糊图像和围绕动态绘图的大阴影构成的静态卡片,在每一帧重绘覆盖它时只相当于一张图像;用变换旋转或缩放元素时,只是移动位图,无需重绘。位图包含盒子、它的阴影,以及它未裁剪而超出盒子的子元素;若子树自身没有不透明背景,其上的文本将以灰度平滑绘制,如同模糊中一样。配合Blur或效果使用时,保留的就是它们的位图。goui.Box(c).Size(900, 212).Radius(16).Gradient(from, to, 30). Shadow(0, 10, 40, 0, shade).Cache().Children(func() { /* … */ })材质。
Material(m)用某个包绘制的材质填充盒子,代替背景,例如 glass 插件的液态玻璃(Liquid Glass):其下方的内容透射出来,呈磨砂状并沿边缘弯曲,包括其滚动边缘和背景模糊,模糊还可沿渐变淡出。指针。
Cursor采用各平台的光标形状:CursorPointer、CursorText、CursorMove、CursorGrab和CursorGrabbing、调整大小的光标(双向、朝一侧的如CursorResizeE,以及列和行的调整光标)、用于放置(drop)的CursorCopy和CursorAlias、CursorContextMenu、CursorVerticalText、CursorNotAllowed、CursorCrosshair,以及隐藏光标的CursorNone。元素的光标在其子元素上方也生效,但接收点击的子元素除外(按钮,或任何带Clicked或OnClick的元素):那些元素显示自己的光标,除非另行设置否则是默认箭头,因此设置了CursorText的输入框中的按钮不会显示 I 形文本光标。
ui.Oklch(l, c, h) 即 CSS 的 oklch();.Alpha(a) 对应其 / a。它返回的 ui.Color 与其他颜色无异,因此填充、边框、渐变、条纹、阴影、分隔线、文本、装饰线、文本背景、玻璃的着色(tint)以及主题(t.Accent = ui.Oklch(0.6, 0.2, 240))都能接受它。它可以表示 sRGB 之外的颜色,比大多数屏幕能显示的更鲜艳。这样的颜色同时保留两者:其真实值——当窗口位于能显示更广色域的屏幕上时(近年 Mac 的 Display P3)按真实值绘制;以及最近的 sRGB 颜色——按 CSS 的方式选取(饱和度更低,明度和色相相同)。那个回退值就是它的 R、G、B,也是 sRGB 屏幕、Linux、Windows 和 SVG 图像所绘制的内容;SRGB() 只返回它而不含真实值。Mix 和过渡混合的是真实值:混合回 sRGB 之内后就是普通颜色。不要对这样的颜色赋值 R、G 或 B,否则真实值将不再匹配:应当新建一个颜色。
颜色来自 ui.RGB、ui.RGBA 和 ui.Hex("#2563eb");Mix 混合两种颜色,Alpha 使颜色半透明。
用状态,而非选择器
这里没有样式表,也没有状态选择器:视图就是代码,因此元素的外观遵循视图自身的状态,例如 if row.Hovered() { row.Background(t.SurfaceHover) };一个元素的状态也可以为另一个元素设置样式,如同 CSS 中组的悬停状态那样。
控件会返回其元素,因此可以在其后追加调用,使其样式不同于其余部分:ui.Button(c, "Save").Padding(10, 20).Radius(999)。想要自己的外观,可基于控件的无外观基础构建:参见自定义控件。
主题
控件从主题 c.Theme() 获取颜色和度量:浅色或深色主题,跟随系统外观的变化,以及系统自身控件所遵循的桌面设置。在你自己的元素中使用它的颜色,它们也会随之变化。要修改主题,设置一个副本:
go
t := *c.Theme() // the default, which follows the system
t.Accent, t.Radius = ui.Hex("#7c3aed"), 8
t.Spacing = 3 // compact
c.SetTheme(&t)Spacing 是控件留白的基本单位:它们的外边距、内边距和间隙,以及复选框、开关、滑块的尺寸和表格、树的行高,都是它的倍数。默认为 4;3 使每个控件紧凑,5 则宽松。FontSize 决定控件文本的字号,Radius 决定圆角,ScrollbarWidth 设置滚动条宽度。在 macOS 上,圆角——控件的和你的元素的——以连续曲线呈现,如同 AppKit 和 SwiftUI;在其他平台上则按四分之一圆弧绘制,如同 Windows 和 GTK 那样。也用主题来度量你自己的元素,它们就会跟随主题:t.Space(3) 是三个间距单位,t.Rem(2) 是字号的两倍,如同 CSS 的 rem。
工具提示和提示条使用反转的主题色,以便与其下方的内容形成对比:以 Inverse 填充,上面用 InverseText;若保持为零,则分别为主题中的 Text 和 Background。深色应用若希望它们保持深色,可同时设置两者:
go
t.Inverse, t.InverseText = ui.Hex("#3f3f46"), ui.Hex("#fafafa")桌面偏好设置
c.Preferences() 返回桌面的设置,默认主题遵循它们,帧也会跟随其变化:
Accent。 用户选择的强调色(macOS、Windows,以及通过 portal 提供强调色的桌面环境,如 GNOME 47 和 KDE),用于为主要按钮、选中项和焦点环着色,其上的文本保证清晰醒目。HighContrast。 macOS 的"增强对比度"、Windows 的对比度主题、portal 的高对比度:边框和次要文本更深(深色模式下更浅),焦点环不透明。TextScale。 Windows 和 GNOME 的文本大小:FontSize相应放大该倍数。ReduceMotion。 macOS 的"减弱动态效果"、Windows 的动画效果关闭、GNOME 的动画关闭:Animate立即到达目标值。