Skip to content

Commit 2b2a376

Browse files
committed
fix: invert browser check
1 parent 286b38f commit 2b2a376

File tree

2 files changed

+90
-77
lines changed

2 files changed

+90
-77
lines changed

lib/LayeredImage.tsx

Lines changed: 74 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -125,103 +125,101 @@ export const LayeredImage: React.FC<ILayeredImageProps> = ({
125125
pageY?: number,
126126
preventDefault = false,
127127
) => {
128-
if (!isBrowser) {
129-
return
130-
}
131-
132-
const { width, height } = _interaction === Interaction.Resize ? getDimensions() : size
128+
if (isBrowser) {
129+
const { width, height } = _interaction === Interaction.Resize ? getDimensions() : size
133130

134-
const bodyScrollTop =
135-
document.body.scrollTop ||
136-
document.documentElement.scrollTop ||
137-
document.scrollingElement.scrollTop ||
138-
window.scrollY ||
139-
window.pageYOffset
140-
const bodyScrollLeft =
141-
document.body.scrollLeft ||
142-
document.documentElement.scrollLeft ||
143-
document.scrollingElement.scrollLeft ||
144-
window.scrollX ||
145-
window.pageXOffset
146-
const containerRect = elementsRef.current.container.current.getBoundingClientRect()
131+
const bodyScrollTop =
132+
document.body.scrollTop ||
133+
document.documentElement.scrollTop ||
134+
document.scrollingElement.scrollTop ||
135+
window.scrollY ||
136+
window.pageYOffset
137+
const bodyScrollLeft =
138+
document.body.scrollLeft ||
139+
document.documentElement.scrollLeft ||
140+
document.scrollingElement.scrollLeft ||
141+
window.scrollX ||
142+
window.pageXOffset
143+
const containerRect = elementsRef.current.container.current.getBoundingClientRect()
147144

148-
const offsetX = (pageX - containerRect.left - bodyScrollLeft) / width
149-
const offsetY = (pageY - containerRect.top - bodyScrollTop) / height
150-
const containerCenterX = pageX - containerRect.left - bodyScrollLeft - width / 2
151-
const containerCenterY = pageY - containerRect.top - bodyScrollTop - height / 2
145+
const offsetX = (pageX - containerRect.left - bodyScrollLeft) / width
146+
const offsetY = (pageY - containerRect.top - bodyScrollTop) / height
147+
const containerCenterX = pageX - containerRect.left - bodyScrollLeft - width / 2
148+
const containerCenterY = pageY - containerRect.top - bodyScrollTop - height / 2
152149

153-
const containerRotationX = ((offsetY - containerCenterY) / (height / 2)) * 8
154-
const containerRotationY = ((containerCenterX - offsetX) / (width / 2)) * 8
155-
const layerTranslationX = (offsetX - containerCenterX) * 0.01
156-
const layerTranslationY = (offsetY - containerCenterY) * 0.01
157-
const lightAngle = (Math.atan2(containerCenterY, containerCenterX) * 180) / Math.PI - 90
150+
const containerRotationX = ((offsetY - containerCenterY) / (height / 2)) * 8
151+
const containerRotationY = ((containerCenterX - offsetX) / (width / 2)) * 8
152+
const layerTranslationX = (offsetX - containerCenterX) * 0.01
153+
const layerTranslationY = (offsetY - containerCenterY) * 0.01
154+
const lightAngle = (Math.atan2(containerCenterY, containerCenterX) * 180) / Math.PI - 90
158155

159-
const computedStyles: ILayeredImageStyles = {
160-
[Interaction.None]: defaultStyles,
161-
[Interaction.Resize]: {
162-
root: {
163-
height: `${height}px`,
164-
transform: `perspective(${width * 3}px)`,
156+
const computedStyles: ILayeredImageStyles = {
157+
[Interaction.None]: defaultStyles,
158+
[Interaction.Resize]: {
159+
root: {
160+
height: `${height}px`,
161+
transform: `perspective(${width * 3}px)`,
162+
},
165163
},
166-
},
167-
[Interaction.Hover]: {
168-
container: {
169-
transform: `rotateX(${-clamp(containerRotationX, -8, 8)}deg)
164+
[Interaction.Hover]: {
165+
container: {
166+
transform: `rotateX(${-clamp(containerRotationX, -8, 8)}deg)
170167
rotateY(${-clamp(containerRotationY, -8, 8)}deg)
171168
translateX(${-layerTranslationX * 5}px)
172169
translateY(${-layerTranslationY * 5}px)
173170
scale(1.1)`,
174-
},
175-
layer: (index: number) => ({
176-
transform: `translateX(${clamp(layerTranslationX, -2, 2) * 1.4 * index}px)
171+
},
172+
layer: (index: number) => ({
173+
transform: `translateX(${clamp(layerTranslationX, -2, 2) * 1.4 * index}px)
177174
translateY(${clamp(layerTranslationY, -2, 2) * 1.4 * index}px)
178175
scale(1.04)`,
179-
}),
180-
light: {
181-
backgroundImage: `linear-gradient(${lightAngle}deg, ${lightColor} 0%, transparent 80%)`,
176+
}),
177+
light: {
178+
backgroundImage: `linear-gradient(${lightAngle}deg, ${lightColor} 0%, transparent 80%)`,
179+
},
180+
shadow: {
181+
boxShadow: `0 40px 100px ${shadowColor}, 0 10px 20px ${shadowColor}`,
182+
},
182183
},
183-
shadow: {
184-
boxShadow: `0 40px 100px ${shadowColor}, 0 10px 20px ${shadowColor}`,
185-
},
186-
},
187-
[Interaction.Active]: {
188-
container: {
189-
transitionDuration: "0.075s",
190-
transform: `rotateX(${containerRotationX / 1.4}deg)
184+
[Interaction.Active]: {
185+
container: {
186+
transitionDuration: "0.075s",
187+
transform: `rotateX(${containerRotationX / 1.4}deg)
191188
rotateY(${containerRotationY / 1.4}deg)
192189
scale(1)`,
193-
},
194-
layer: (index: number) => ({
195-
transform: `translateX(${-layerTranslationX * index}px)
190+
},
191+
layer: (index: number) => ({
192+
transform: `translateX(${-layerTranslationX * index}px)
196193
translateY(${-layerTranslationY * index}px)
197194
scale(1.02)`,
198-
}),
199-
light: {
200-
backgroundImage: `linear-gradient(${lightAngle}deg, ${lightColor} 0%, transparent 80%)`,
195+
}),
196+
light: {
197+
backgroundImage: `linear-gradient(${lightAngle}deg, ${lightColor} 0%, transparent 80%)`,
198+
},
199+
shadow: {
200+
...defaultStyles.shadow,
201+
transitionDuration: "0.075s",
202+
},
201203
},
202-
shadow: {
203-
...defaultStyles.shadow,
204-
transitionDuration: "0.075s",
205-
},
206-
},
207-
}[_interaction]
204+
}[_interaction]
208205

209-
if (preventDefault) {
210-
event.preventDefault()
211-
}
206+
if (preventDefault) {
207+
event.preventDefault()
208+
}
212209

213-
for (const [element, styles] of Object.entries(computedStyles)) {
214-
if (element === "layer") {
215-
layers.forEach((_, index) =>
216-
applyStyles(elementsRef.current.layers[index].current, isFunction(styles) ? styles(index) : styles),
217-
)
218-
} else {
219-
applyStyles(elementsRef.current[element].current, styles)
210+
for (const [element, styles] of Object.entries(computedStyles)) {
211+
if (element === "layer") {
212+
layers.forEach((_, index) =>
213+
applyStyles(elementsRef.current.layers[index].current, isFunction(styles) ? styles(index) : styles),
214+
)
215+
} else {
216+
applyStyles(elementsRef.current[element].current, styles)
217+
}
220218
}
221-
}
222219

223-
setSize({ width, height })
224-
setInteraction(_interaction)
220+
setSize({ width, height })
221+
setInteraction(_interaction)
222+
}
225223
}
226224

227225
// prettier-ignore

lib/utils.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@
33
*/
44
export const applyStyles = (element: HTMLDivElement, styles: React.CSSProperties) => {
55
for (const [style, value] of Object.entries(styles)) {
6-
element.style[style] = value
6+
if (isSafariDesktop()) {
7+
element.style[style] = value
8+
} else {
9+
requestAnimationFrame(() => {
10+
element.style[style] = value
11+
})
12+
}
713
}
814
}
915

@@ -26,3 +32,12 @@ export const isBrowser = typeof window !== "undefined" && typeof window.document
2632
*/
2733
// eslint-disable-next-line @typescript-eslint/ban-types
2834
export const isFunction = (value: unknown): value is Function => typeof value === "function"
35+
36+
/**
37+
* Detect whether the current browser is a desktop version of Safari.
38+
*/
39+
export const isSafariDesktop = () => {
40+
const { userAgent, vendor } = navigator
41+
42+
return /Safari/i.test(userAgent) && /Apple Computer/.test(vendor) && !/Mobi|Android/i.test(userAgent)
43+
}

0 commit comments

Comments
 (0)