Skip to content

Instantly share code, notes, and snippets.

@samsonjs
Forked from chriseidhof/FavoriteButton.swift
Created April 15, 2022 15:38
Show Gist options
  • Save samsonjs/810dad0f09094198c192aac6666cbf17 to your computer and use it in GitHub Desktop.
Save samsonjs/810dad0f09094198c192aac6666cbf17 to your computer and use it in GitHub Desktop.
import SwiftUI
extension CGPoint {
static func *(lhs: Self, rhs: CGFloat) -> Self {
.init(x: lhs.x * rhs, y: lhs.y * rhs)
}
}
// Idea: https://www.framer.com/showcase/project/lo2Qka8jtPXrjzZaPZdB/
struct MoveToModifier: ViewModifier & Animatable {
init(offset: CGFloat, active: Bool) {
self.offset = offset
self.progress = active ? 1 : 0
}
var offset: CGFloat = .zero
var maxYOffset: CGFloat = 40
var progress: CGFloat
var animatableData: CGFloat {
get { progress }
set { progress = newValue }
}
func body(content: Content) -> some View {
let amount = sin(.pi * progress) * maxYOffset
content.offset(x: offset * progress, y: amount)
}
}
struct StarButton: View {
@State var selected = false
@ViewBuilder var body: some View {
let moveTo = AnyTransition.modifier(active: MoveToModifier(offset: 70, active: true), identity: MoveToModifier(offset: 70, active: false))
let star = AnyTransition.asymmetric(insertion: .identity, removal: moveTo).combined(with: .opacity)
HStack {
if !selected {
Image(systemName: "star")
.symbolRenderingMode(.multicolor)
.symbolVariant(.fill)
.transition(star)
}
Text(selected ? "Starred" : "Star")
Divider()
.frame(idealHeight: 10)
Text(selected ? "39" : "38")
.monospacedDigit()
.id(selected)
.transition(.scale(scale: 0).combined(with: .opacity))
}
.frame(width: 100)
.animation(.default.speed(0.5), value: selected)
.foregroundColor(.primary)
.padding()
.background(
RoundedRectangle(cornerRadius: 5)
.fill(Color.init(white: 0.87))
.shadow(color: .gray.opacity(0.3), radius: 5, x: 5, y: 5)
)
.contentShape(RoundedRectangle(cornerRadius: 5))
.onTapGesture {
selected.toggle()
}
}
}
struct ContentView: View {
var body: some View {
StarButton()
.fixedSize()
.padding(100)
.background(Color.white)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.preferredColorScheme(.light)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment