Skip to content

Commit c5cf0e1

Browse files
committed
✨ Refine radial menu glass
1 parent 604753e commit c5cf0e1

2 files changed

Lines changed: 40 additions & 18 deletions

File tree

Loop/Window Action Indicators/Preview Window/PreviewController.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ final class PreviewController {
4646
panel.level = NSWindow.Level(NSWindow.Level.screenSaver.rawValue - 1)
4747
panel.contentView = NSHostingView(rootView: PreviewView(viewModel: viewModel))
4848
panel.collectionBehavior = .canJoinAllSpaces
49+
panel.hasShadow = false
4950
panel.ignoresMouseEvents = true
5051
panel.orderFrontRegardless()
5152
controller = .init(window: panel)

Loop/Window Action Indicators/Radial Menu/RadialMenuView.swift

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import SwiftUI
1212
struct RadialMenuView: View {
1313
@Environment(\.luminareAnimation) private var luminareAnimation
1414
@Environment(\.appearsActive) private var appearsActive
15+
@Environment(\.colorScheme) private var colorScheme
1516
@ObservedObject private var accentColorController: AccentColorController = .shared
1617
@ObservedObject private var viewModel: RadialMenuViewModel
1718
private let radialMenuSize: CGFloat = 100
@@ -53,24 +54,44 @@ struct RadialMenuView: View {
5354
/// but for now, we have disabled the materialization Liquid Glass transition.
5455
ZStack {
5556
if viewModel.isShown {
56-
radialMenuFill()
57-
.mask(directionSelectorMask)
58-
.mask(radialMenuMask)
59-
.glassEffect(
60-
.regular.tint(accentColorController.color1.opacity(0.025)),
61-
in: .rect(cornerRadius: radialMenuCornerRadius)
62-
.inset(by: radialMenuThickness / 2)
63-
.stroke(lineWidth: radialMenuThickness)
64-
)
65-
.transition(.scale(scale: 1.25).combined(with: .opacity))
66-
}
67-
}
68-
.overlay {
69-
if viewModel.isShown {
70-
overlayImage()
71-
.transition(.scale(scale: 1.25).combined(with: .opacity))
57+
ZStack {
58+
radialMenuFill()
59+
.mask(directionSelectorMask)
60+
.glassEffect(
61+
.regular.tint(accentColorController.color1.opacity(0.025)),
62+
in: .rect(cornerRadius: radialMenuCornerRadius) // Using the radial menu thickness here causes a seam in the middle
63+
)
64+
.mask(radialMenuMask)
65+
66+
if appearsActive {
67+
let borderColor: Color = colorScheme == .dark ? .white.opacity(0.25).mix(with: accentColorController.color1, by: 0.25) : .white
68+
69+
// Since the glass is just masked to the radial menu shape, it will be missing its inner border.
70+
// This emulates a liquid glass inner border.
71+
let innerBorderThickness: CGFloat = 0.5
72+
RoundedRectangle(cornerRadius: radialMenuCornerRadius)
73+
.inset(by: radialMenuThickness - innerBorderThickness)
74+
.strokeBorder(lineWidth: innerBorderThickness)
75+
.foregroundStyle(borderColor)
76+
.mask {
77+
LinearGradient(
78+
colors: [
79+
.white,
80+
.clear,
81+
.white
82+
],
83+
startPoint: .topLeading,
84+
endPoint: .bottomTrailing
85+
)
86+
}
87+
}
88+
89+
overlayImage()
90+
}
91+
.transition(.scale(scale: 1.25).combined(with: .opacity))
7292
}
7393
}
94+
.compositingGroup()
7495
.frame(width: radialMenuSize, height: radialMenuSize)
7596
.shadow(color: .black.opacity(viewModel.isShadowShown ? 0.2 : 0), radius: 10)
7697
.scaleEffect(viewModel.shouldFillRadialMenu ? 0.85 : 1.0)
@@ -103,8 +124,8 @@ struct RadialMenuView: View {
103124
LinearGradient(
104125
gradient: Gradient(
105126
colors: [
106-
shouldAppearActive ? accentColorController.color1 : .systemGray,
107-
shouldAppearActive ? accentColorController.color2 : .systemGray
127+
accentColorController.color1,
128+
accentColorController.color2
108129
]
109130
),
110131
startPoint: .topLeading,

0 commit comments

Comments
 (0)