Hello friends, i was having problems with showing all the canvas elements on my mobile device, reading the other issues it became apparent mobile supports a certain number of canvases, the individual balls was taking up majority of those allotted canvases.
I tested this out by removing all the balls, and yeah the page does seem to render the other canvases, also has a faster page rendering
My solution was to group all the balls in one canvas. While i lose the control of each ball, i think it looks slightly better this way. the page is much faster at rendering too.
import React, { Suspense, useMemo } from "react";
import { Canvas } from "@react-three/fiber";
import {
Decal,
Float,
OrbitControls,
Preload,
useTexture,
} from "@react-three/drei";
import CanvasLoader from "../Loader";
import * as THREE from 'three';
const Ball = ({ icon, position, rotation }) => {
const decal = useMemo(() => new THREE.TextureLoader().load(icon), [icon]);
return (
<Float speed={1.75} rotationIntensity={1} floatIntensity={2}>
<ambientLight intensity={0.03} />
<directionalLight position={[10, 5, -5]} />
<mesh castShadow receiveShadow scale={1} position={position}>
<icosahedronGeometry args={[1, 10]} />
<meshStandardMaterial
color='#fff8eb'
flatShading
/>
<Decal
position={[0, 0, 1]}
rotation={[2 * Math.PI, 0, 6.25]}
scale={1.2}
map={decal}
flatShading
/>
</mesh>
</Float>
);
};
const BallCanvas = ({ icons }) => {
return (
<Canvas frameloop='always'
shadows
dpr={[1, 1]}
camera={{ position: [0, 0, 5], fov: 75 }}
gl={{ preserveDrawingBuffer: true }}>
<Suspense fallback={<CanvasLoader />}>
<OrbitControls enableZoom={false} />
<group>
{icons.map((icon, index) => {
const row = Math.floor(index / 3);
const col = index % 3;
return (
<Ball key={icon} icon={icon} position={[col * 3 - 4, row * 3 + -2, -9]} />
);
})}
</group>
</Suspense>
<Preload all />
</Canvas>
);
};
export default BallCanvas;
Now on your Tech.jsx component create a const variable storing all the icons in an array and pass it into the BallCanvas
<div className='w-full h-[75vh] mx-auto'>
<BallCanvas icons={icons} />
</div>