Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion TrackWeight.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 9ZRLG6277G;
DEVELOPMENT_TEAM = BQ65WXL7J3;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
Expand Down Expand Up @@ -365,6 +365,7 @@
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 9ZRLG6277G;
"DEVELOPMENT_TEAM[sdk=macosx*]" = BQ65WXL7J3;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
Expand Down
178 changes: 116 additions & 62 deletions TrackWeight/HomeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,22 @@
import SwiftUI

struct HomeView: View {
let onBegin: () -> Void

@State private var isHovering: Bool = false
@State private var isPressing: Bool = false

let onBegin: () -> Void

var body: some View {
VStack(spacing: 40) {
Spacer()

// Title section
VStack(spacing: 15) {
Image(systemName: "scalemass")
Image(systemName: "scalemass.fill")
.font(.system(size: 80, weight: .ultraLight))
.foregroundStyle(Color.blue)

Text("TrackWeight")
.font(.system(size: 48, weight: .bold, design: .rounded))
.foregroundStyle(
Expand All @@ -28,78 +32,100 @@ struct HomeView: View {
)
)
}
// Description section
VStack(spacing: 20) {

// Description and Limitations section
VStack(spacing: 30) {
Text("Transform your MacBook trackpad into a precision scale using Apple's private MultitouchSupport framework to read pressure values with gram-level accuracy.")
.font(.system(size: 18, weight: .medium))
.font(.system(size: 19, weight: .medium))
.foregroundStyle(Color.primary)
.multilineTextAlignment(.center)
.frame(maxWidth: 550)

// Limitations section
VStack(spacing: 12) {
.frame(maxWidth: 600)
.padding(.horizontal, 20)

// Limitations section container but with glassmorphism effect this do not work as i thought
VStack(spacing: 15) {
Text("Important Limitations")
.font(.system(size: 16, weight: .semibold))
.font(.system(size: 17, weight: .semibold))
.foregroundStyle(Color.orange)
VStack(spacing: 8) {

VStack(alignment: .leading, spacing: 10) {
LimitationRow(
icon: "hand.point.up.left",
text: "Requires finger contact for capacitive detection"
text: "Requires finger contact for capacitive detection. Objects must be non-conductive and have sufficient surface area."
)
LimitationRow(
icon: "chart.line.downtrend.xyaxis",
text: "May experience pressure drift when placing objects"
text: "May experience slight pressure drift when placing objects due to temperature or contact changes. Calibration is recommended."
)
LimitationRow(
icon: "cube.fill",
text: "Metal/magnetic objects may not work"
icon: "cube.box.fill",
text: "Metal or magnetic objects may interfere with the trackpad's sensors and may not register accurately or at all."
)
}
.padding(.top, 5)
}
.padding(.horizontal, 30)
.padding(.vertical, 20)
.padding(.vertical, 25)
.background(
RoundedRectangle(cornerRadius: 15)
.foregroundColor(Color.orange.opacity(0.05))
.overlay(
RoundedRectangle(cornerRadius: 15)
.stroke(Color.orange.opacity(0.2), lineWidth: 1)
)
RoundedRectangle(cornerRadius: 20)
.fill(.ultraThinMaterial)
)
.frame(maxWidth: 500)
}

Spacer()

// Begin button
Button(action: onBegin) {
HStack(spacing: 10) {
Text("Begin")
.font(.system(size: 18, weight: .semibold))
Image(systemName: "arrow.right")
.font(.system(size: 16, weight: .semibold))
}
.foregroundStyle(Color.white)
.frame(width: 140, height: 50)
.background(
.overlay(
RoundedRectangle(cornerRadius: 25)
.fill(
LinearGradient(
colors: [.blue, .teal],
startPoint: .leading,
endPoint: .trailing
)
)
.shadow(color: .blue.opacity(0.3), radius: 10, x: 0, y: 5)
.stroke(Color.white.opacity(0.1), lineWidth: 1)
)
.shadow(color: Color.black.opacity(0.1), radius: 10, x: 0, y: 5)
.frame(maxWidth: 550)
.padding(.horizontal, 20)
}
.buttonStyle(.plain)
.scaleEffect(1.0)
.animation(.spring(response: 0.3, dampingFraction: 0.8), value: true)
.padding(.vertical, 10)


// Begin button
Button(action: {
self.isPressing = true
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.isPressing = false
onBegin()
}
}) {
HStack(spacing: 10) {
Text("Begin")
.font(.system(size: 18, weight: .semibold))
Image(systemName: "scalemass.fill")
.font(.system(size: 16, weight: .semibold))
// Icon movement on hover
.offset(x: isHovering ? 3 : 0)
}
.foregroundStyle(.white)
.frame(width: 140, height: 50)
.background(
RoundedRectangle(cornerRadius: 20)
.fill(
LinearGradient(

colors: isPressing ? [.init(red: 0.35, green: 0.13, blue: 0.71), .init(red: 0.49, green: 0.23, blue: 0.98)] : // Darker on press
(isHovering ? [.init(red: 0.49, green: 0.23, blue: 0.98), .init(red: 0.65, green: 0.54, blue: 0.98)] : // Brighter on hover
[.blue, .teal]),
startPoint: .leading,
endPoint: .trailing
)
)
)

.shadow(color: Color.black.opacity(isPressing ? 0.15 : (isHovering ? 0.35 : 0.2)),
radius: isPressing ? 8 : (isHovering ? 25 : 15),
x: 0,
y: isPressing ? 2 : (isHovering ? 8 : 4))
}
.buttonStyle(.plain)
.padding(.vertical, 10)
.scaleEffect(isPressing ? 0.98 : (isHovering ? 1.02 : 1.0))
.offset(y: isHovering ? -3 : 0)
.animation(.spring(response: 0.3, dampingFraction: 0.8), value: isHovering)
.animation(.easeOut(duration: 0.1), value: isPressing)
.onHover { hover in
self.isHovering = hover
}
Spacer()
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
Expand All @@ -110,24 +136,52 @@ struct HomeView: View {
struct LimitationRow: View {
let icon: String
let text: String


@State private var isRowHovering: Bool = false

var body: some View {
HStack(spacing: 12) {
HStack(alignment: .top, spacing: 10) {

Image(systemName: icon)
.font(.system(size: 14, weight: .medium))
.font(.system(size: 18, weight: .medium))
.foregroundStyle(Color.orange)
.frame(width: 20)
.frame(width: 25)


Text(text)
.font(.system(size: 14, weight: .medium))
.font(.system(size: 15, weight: .regular))
.foregroundStyle(Color.secondary)
.multilineTextAlignment(.leading)

Spacer()
.lineLimit(nil)
.fixedSize(horizontal: false, vertical: true)
}
.padding(.vertical, 5)
.padding(.horizontal, 10)
.background(
RoundedRectangle(cornerRadius: 10)
.fill(isRowHovering ? Color.white.opacity(0.08) : Color.clear)
)
.cornerRadius(10)
.scaleEffect(isRowHovering ? 1.01 : 1.0)
.shadow(color: Color.black.opacity(isRowHovering ? 0.1 : 0),
radius: isRowHovering ? 5 : 0,
x: 0,
y: isRowHovering ? 2 : 0)

.animation(.easeOut(duration: 0.2), value: isRowHovering)
.onHover { hover in
isRowHovering = hover
}
}
}

#Preview {
HomeView(onBegin: {})
ZStack {
LinearGradient(gradient: Gradient(colors: [.purple, .blue, .green]), startPoint: .topLeading, endPoint: .bottomTrailing)
.edgesIgnoringSafeArea(.all)

HomeView(onBegin: {
print("Begin button tapped from preview!")
})
}
}
Loading