Skip to content

Instantly share code, notes, and snippets.

@boraseoksoon
Created September 1, 2023 00:18
Show Gist options
  • Save boraseoksoon/24077d16773e9967e5d2e3c56682f435 to your computer and use it in GitHub Desktop.
Save boraseoksoon/24077d16773e9967e5d2e3c56682f435 to your computer and use it in GitHub Desktop.
HighlightView
//
// HighlightView.swift
// DemoScreen
//
// Created by seoksoon jang on 2023-08-31.
//
import SwiftUI
enum Light: Hashable, CaseIterable {
case red
case yellow
case green
var color: Color {
switch self {
case .red: return .red
case .yellow: return .yellow
case .green: return .green
}
}
}
struct LightsView: View {
let namespace: Namespace.ID
var body: some View {
VStack(spacing: 20) {
ForEach(Light.allCases, id: \.self) { light in
Circle()
.foregroundColor(light.color)
.matchedGeometryEffect(
id: light, in: namespace,
properties: .frame, anchor: .center,
isSource: true
)
}
}
.padding(20)
}
}
struct HighlightingView: View {
var spotlitLight: Light
var isSpotlighting: Bool
@Namespace private var namespace
var body: some View {
ZStack {
LightsView(namespace: namespace)
SpotlightView(
spotlitLight: spotlitLight,
namespace: namespace
)
.opacity(isSpotlighting ? 0.5 : 0)
.animation(
.easeOut,
value: isSpotlighting ? spotlitLight : nil
)
}
}
}
struct SpotlightView: View {
var spotlitLight: Light
var namespace: Namespace.ID
var body: some View {
ZStack {
Color.black
Circle()
.foregroundColor(.white)
.blur(radius: 4)
.padding(-10)
.matchedGeometryEffect(
id: spotlitLight, in: namespace,
properties: .frame, anchor: .center,
isSource: false
)
.blendMode(.destinationOut)
}
.compositingGroup()
}
}
struct HighlightTestView: View {
@State var isSpotlighting = false
@State var spotlitLight: Light = .red
private var selection: Binding<Light?> {
Binding(
get: { isSpotlighting ? spotlitLight : nil },
set: {
if let light = $0 {
isSpotlighting = true
spotlitLight = light
} else {
isSpotlighting = false
}
}
)
}
var body: some View {
VStack {
HighlightingView(
spotlitLight: spotlitLight,
isSpotlighting: isSpotlighting
)
Picker("Light", selection: selection) {
Text("none").tag(Light?.none)
ForEach(Light.allCases, id: \.self) {
Text("\($0)" as String)
.tag(Optional($0))
}
}
.pickerStyle(.segmented)
}
.padding()
}
}
// https://stackoverflow.com/a/75263911/3426053
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment