feat(store): stretch cover image on pull-down overscroll
- Remove max(0) clamp in ScrollOffsetReader to allow negative values during bounce - Add stretchAmount computed var (max(0, -scrollOffset)) - Hero image frame grows by stretchAmount and offsets upward on overscroll - isCategoryTabsPinned still uses max(0, scrollOffset) via >= check
This commit is contained in:
@@ -37,7 +37,7 @@ struct ScrollOffsetReader: View {
|
|||||||
)
|
)
|
||||||
.onPreferenceChange(ScrollOffsetPreferenceKey.self) { minY in
|
.onPreferenceChange(ScrollOffsetPreferenceKey.self) { minY in
|
||||||
if baseline == nil { baseline = minY }
|
if baseline == nil { baseline = minY }
|
||||||
let offset = max(0, (baseline ?? 0) - minY)
|
let offset = (baseline ?? 0) - minY
|
||||||
if abs(offsetY - offset) > 0.5 {
|
if abs(offsetY - offset) > 0.5 {
|
||||||
offsetY = offset
|
offsetY = offset
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ extension StoreDetailView {
|
|||||||
var heroSection: some View {
|
var heroSection: some View {
|
||||||
ZStack(alignment: .top) {
|
ZStack(alignment: .top) {
|
||||||
AsyncStoreImage(imageURL: resolvedURL(storeCoverURL))
|
AsyncStoreImage(imageURL: resolvedURL(storeCoverURL))
|
||||||
.frame(height: topSectionHeight)
|
.frame(height: topSectionHeight + stretchAmount)
|
||||||
.overlay(
|
.overlay(
|
||||||
LinearGradient(
|
LinearGradient(
|
||||||
colors: [Color.black.opacity(0.32), Color.black.opacity(0.05)],
|
colors: [Color.black.opacity(0.32), Color.black.opacity(0.05)],
|
||||||
@@ -34,6 +34,7 @@ extension StoreDetailView {
|
|||||||
endPoint: .bottom
|
endPoint: .bottom
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
.offset(y: -stretchAmount)
|
||||||
.ignoresSafeArea(.container, edges: .top)
|
.ignoresSafeArea(.container, edges: .top)
|
||||||
|
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ struct StoreDetailView: View {
|
|||||||
@State var scrollOffset: CGFloat = 0
|
@State var scrollOffset: CGFloat = 0
|
||||||
|
|
||||||
var isCategoryTabsPinned: Bool { scrollOffset >= topSectionHeight }
|
var isCategoryTabsPinned: Bool { scrollOffset >= topSectionHeight }
|
||||||
|
var stretchAmount: CGFloat { max(0, -scrollOffset) }
|
||||||
|
|
||||||
let cardTopInset: CGFloat = 180
|
let cardTopInset: CGFloat = 180
|
||||||
let summaryCardBaseHeight: CGFloat = 212
|
let summaryCardBaseHeight: CGFloat = 212
|
||||||
|
|||||||
Reference in New Issue
Block a user