Skip to content

Instantly share code, notes, and snippets.

@ivancantarino
Created February 26, 2025 23:17
Show Gist options
  • Save ivancantarino/ae08aedfc9838c6e7e9cd5f2c6634263 to your computer and use it in GitHub Desktop.
Save ivancantarino/ae08aedfc9838c6e7e9cd5f2c6634263 to your computer and use it in GitHub Desktop.
//
// ContentView.swift
// Boring
//
// Created by Ivan Cantarino on 26/02/2025.
//
import SwiftUI
struct ContentView: View {
var body: some View {
ZStack {
Text("! Boring")
.font(.system(size: 100, weight: .heavy, design: .default))
.foregroundColor(.white)
.stroke(color: .black, width: 3)
Text("! Boring")
.font(.system(size: 100, weight: .heavy, design: .default))
.foregroundColor(.white)
.stroke(color: .black, width: 3)
.offset(y: -6)
}
}
}
extension View {
func stroke(color: Color, width: CGFloat = 1) -> some View {
modifier(StrokeModifier(strokeSize: width, strokeColor: color))
}
}
struct StrokeModifier: ViewModifier {
private let id = UUID()
var strokeSize: CGFloat = 1
var strokeColor: Color = .blue
func body(content: Content) -> some View {
if strokeSize > 0 {
appliedStrokeBackground(content: content)
} else {
content
}
}
private func appliedStrokeBackground(content: Content) -> some View {
content
.padding(strokeSize*2)
.background(
Rectangle()
.foregroundColor(strokeColor)
.mask(alignment: .center) {
mask(content: content)
}
)
}
func mask(content: Content) -> some View {
Canvas { context, size in
context.addFilter(.alphaThreshold(min: 0.01))
if let resolvedView = context.resolveSymbol(id: id) {
context.draw(resolvedView, at: .init(x: size.width/2, y: size.height/2))
}
} symbols: {
content
.tag(id)
.blur(radius: strokeSize)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment