Skip to content

Instantly share code, notes, and snippets.

@Shubham0812
Last active July 9, 2026 10:16
Show Gist options
  • Select an option

  • Save Shubham0812/91ad7903eaaa92feeb8adf10833aa43c to your computer and use it in GitHub Desktop.

Select an option

Save Shubham0812/91ad7903eaaa92feeb8adf10833aa43c to your computer and use it in GitHub Desktop.
//
// BlobView.swift
// Prototypes
//
// Created by Shubham on 07/07/26.
//
import SwiftUI
struct BlobView: View {
// MARK: - Variables
@State private var dragOffset: CGSize = .zero
@State private var blobColor: Color = .red
let colors: [Color] = [.red, .orange, .yellow, .green, .blue, .purple, .pink]
let circleSize: CGFloat = 120
let blurRadius: CGFloat = 25
// MARK: - Views
var body: some View {
NavigationStack {
ZStack {
Canvas { context, size in
context.addFilter(.alphaThreshold(min: 0.5, color: .white))
context.addFilter(.blur(radius: blurRadius))
context.drawLayer { ctx in
let center = CGPoint(x: size.width / 2, y: size.height / 2 - 24)
if let staticCircle = context.resolveSymbol(id: 1) {
ctx.draw(staticCircle, at: center)
}
if let draggableCircle = context.resolveSymbol(id: 2) {
ctx.draw(draggableCircle, at: center)
}
}
} symbols: {
// Make sure the base symbols are also white
Circle()
.fill(.white)
.frame(width: circleSize, height: circleSize)
.tag(1)
Circle()
.fill(.white)
.frame(width: circleSize, height: circleSize)
.offset(dragOffset)
.tag(2)
}
.ignoresSafeArea()
// 2. Apply the color to the final canvas output!
// This modifier smoothly animates 100% of the time in SwiftUI.
.colorMultiply(blobColor)
.animation(.smooth(duration: 0.5), value: blobColor)
// Invisible layer for drag gesture
Color.clear
.contentShape(Rectangle())
.ignoresSafeArea()
.gesture(
DragGesture()
.onChanged { value in
dragOffset = value.translation
}
.onEnded { _ in
withAnimation(.spring(response: 0.4, dampingFraction: 0.6)) {
dragOffset = .zero
}
}
)
}
.onAppear {
// Safely randomize on launch
blobColor = colors.randomElement() ?? .red
}
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button {
// The .colorMultiply modifier will catch this state change
// and animate it perfectly.
blobColor = colors.randomElement() ?? .red
} label: {
Image(systemName: "shuffle")
}
}
}
}
}
}
#Preview {
BlobView()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment