Skip to content

Commit 7b3c9ef

Browse files
authored
Fall back to image if hardware acceleration is disabled (codesandbox#3161)
* Fall back to image if hardware acceleration is disabled We now fall back to an image instead on an animation in the hero if we see 3 frames of less than 5fps consecutively. * Use styled-components for the elements
1 parent 519633c commit 7b3c9ef

File tree

4 files changed

+65
-12
lines changed

4 files changed

+65
-12
lines changed
146 KB
Loading
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import styled from 'styled-components';
2+
3+
export const AnimationContainer = styled.div`
4+
position: absolute;
5+
top: 0;
6+
left: 0;
7+
right: 0;
8+
bottom: 0;
9+
z-index: 0;
10+
`;
11+
12+
export const FallbackImageBackground = styled.div`
13+
background-image: url(${props => props.fallback});
14+
width: 100%;
15+
height: 100%;
16+
background-size: cover;
17+
background-position: 50% 50%;
18+
`;

packages/homepage/src/screens/home/hero/BoxAnimation/index.js

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,37 @@
1313
import * as THREE from 'three';
1414
import * as CANNON from 'cannon';
1515
import React, { useEffect, useState, useRef } from 'react';
16-
import { Canvas, useThree } from 'react-three-fiber';
16+
import { Canvas, useThree, useFrame } from 'react-three-fiber';
1717
import { useDrag } from 'react-use-gesture';
1818
import { useSpring, a } from 'react-spring/three';
1919
import ResizeObserver from '@juggle/resize-observer';
2020

21+
import fallback from '../../../../assets/images/hero-fallback.png';
2122
import { useCannon, Provider } from './useCannon';
2223

23-
function Plane({ position }) {
24+
import { AnimationContainer, FallbackImageBackground } from './elements';
25+
26+
function Plane({ position, disableAnimation }) {
2427
const bodyRef = useRef();
28+
const fpsBelow10 = useRef(0);
29+
const lastCall = useRef(Date.now());
30+
31+
// If we have 3 consecutive frames that are below 5fps it's most likely that
32+
// hardware acceleration has been disabled and we'll disable the whole animation
33+
useFrame(() => {
34+
const currentTime = Date.now();
35+
const delta = currentTime - lastCall.current;
36+
lastCall.current = currentTime;
37+
if (delta > (1 / 5) * 1000 && document.hasFocus()) {
38+
fpsBelow10.current++;
39+
40+
if (fpsBelow10.current > 3) {
41+
disableAnimation();
42+
}
43+
} else {
44+
fpsBelow10.current = 0;
45+
}
46+
});
2547

2648
const fn = React.useCallback(
2749
body => {
@@ -107,6 +129,7 @@ function Box({ position, rotation, onDrag, onDragStop }) {
107129

108130
export default function App({ boxes, showPlane }) {
109131
const [prop, set] = useSpring(() => ({ intensity: 0.6, color: '#fff' }));
132+
const [animationDisabled, setAnimationDisabled] = React.useState(false);
110133
const [dragging, setDragging] = React.useState(false);
111134

112135
const setDraggingTrue = React.useCallback(() => {
@@ -129,15 +152,20 @@ export default function App({ boxes, showPlane }) {
129152
}, 300);
130153
}, [boxes, set]);
131154

155+
if (animationDisabled) {
156+
return (
157+
<AnimationContainer>
158+
<FallbackImageBackground
159+
fallback={fallback}
160+
alt="boxes falling on the ground"
161+
/>
162+
</AnimationContainer>
163+
);
164+
}
165+
132166
return (
133-
<div
167+
<AnimationContainer
134168
style={{
135-
position: 'absolute',
136-
top: 0,
137-
left: 0,
138-
right: 0,
139-
bottom: 0,
140-
zIndex: 0,
141169
touchAction: dragging ? 'none' : 'initial',
142170
}}
143171
>
@@ -160,7 +188,14 @@ export default function App({ boxes, showPlane }) {
160188
/>
161189

162190
<Provider>
163-
{showPlane && <Plane position={[0, 0, 0]} />}
191+
{showPlane && (
192+
<Plane
193+
disableAnimation={() => {
194+
setAnimationDisabled(true);
195+
}}
196+
position={[0, 0, 0]}
197+
/>
198+
)}
164199

165200
{boxes.map(pos => (
166201
<Box
@@ -173,6 +208,6 @@ export default function App({ boxes, showPlane }) {
173208
))}
174209
</Provider>
175210
</Canvas>
176-
</div>
211+
</AnimationContainer>
177212
);
178213
}

packages/homepage/src/screens/home/hero/BoxAnimation/useCannon.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export function useCannon({ ...props }, fn) {
4242

4343
useRender(() => {
4444
const { current } = ref;
45-
if (current !== undefined) {
45+
if (current != null && body != null) {
4646
// Transport cannon physics into the referenced threejs object
4747
current.position.copy(body.position);
4848
current.quaternion.copy(body.quaternion);

0 commit comments

Comments
 (0)