Skip to content

Instantly share code, notes, and snippets.

@YusukeHosonuma
Created August 29, 2023 04:41
Show Gist options
  • Save YusukeHosonuma/60a6fa04f2303f18035f847c0b65d4e9 to your computer and use it in GitHub Desktop.
Save YusukeHosonuma/60a6fa04f2303f18035f847c0b65d4e9 to your computer and use it in GitHub Desktop.
SwiftUI: 某エディタの透明度アイコン的な
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
OpacityIcons(content: OpacityIcon1.init)
OpacityIcons(content: OpacityIcon2.init)
}
.padding()
}
}
struct OpacityIcons<Content: View>: View {
@ViewBuilder var content: (_ opacity: CGFloat) -> Content
var body: some View {
HStack {
ForEach([1, 0.75, 0.5, 0.25, 0], id: \.self) { opacity in
content(opacity)
.scaledToFit()
}
}
}
}
// `scaleEffect`で三角形を縮小するバージョン。
struct OpacityIcon1: View {
var opacity: CGFloat
private let path = RoundedRectangle(cornerRadius: 4)
var body: some View {
ZStack {
// ■
path.fill(.controlBackgroundColor)
path.strokeBorder(.gridColor, lineWidth: 1)
// ▲
Triangle()
.fill(.labelColor.opacity(opacity))
.scaleEffect(0.7)
}
}
}
// `inset(by:)`で三角形を縮小するバージョン。
struct OpacityIcon2: View {
var opacity: CGFloat
private let path = RoundedRectangle(cornerRadius: 4)
var body: some View {
GeometryReader { geometry in
ZStack {
// ■
path.fill(.controlBackgroundColor)
path.strokeBorder(.gridColor, lineWidth: 1)
// ▲
Triangle()
.inset(by: geometry.size.width * 0.15) // 70%
.fill(.labelColor.opacity(opacity))
}
}
}
}
// 三角形
struct Triangle: InsettableShape {
var inset: CGFloat = 0
func path(in rect: CGRect) -> Path {
let rect = rect.insetBy(dx: inset, dy: inset)
return Path { path in
path.move(to: rect.bottomLeading)
path.addLine(to: rect.bottomTrailing)
path.addLine(to: rect.topTrailing)
}
}
func inset(by amount: CGFloat) -> Self {
var new = self
new.inset = amount
return new
}
}
// MARK: - Alias
extension CGRect {
var bottomLeading: CGPoint { .init(x: minX, y: maxY) }
var bottomTrailing: CGPoint { .init(x: maxX, y: maxY) }
var topTrailing: CGPoint { .init(x: maxX, y: minY) }
}
#if os(macOS)
extension ShapeStyle where Self == Color {
static var controlBackgroundColor: Color { .controlBackgroundColor }
static var gridColor: Color { .gridColor }
static var labelColor: Color { .labelColor }
}
extension Color {
static var controlBackgroundColor: Self { .init(nsColor: .controlBackgroundColor) }
static var gridColor: Self { .init(nsColor: .gridColor) }
static var labelColor: Self { .init(nsColor: .labelColor) }
}
#endif
// MARK: - Preview
#Preview {
ContentView()
.padding()
}
@YusukeHosonuma
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment