Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Safari Scrolling List of Views Jittery #1890

Open
rossrossp opened this issue Mar 22, 2024 · 4 comments
Open

Safari Scrolling List of Views Jittery #1890

rossrossp opened this issue Mar 22, 2024 · 4 comments
Labels
bug Something isn't working

Comments

@rossrossp
Copy link

rossrossp commented Mar 22, 2024

  • three version: 0.162.0
  • @react-three/fiber version: 8.15.19
  • @react-three/drei version: 9.102.3
  • node version: v20.11.1
  • npm (or yarn) version: 10.2.4

Problem description:

Scrolling a list of Views and letting go so that the inertia continues, on Safari (iPhone or macOS), results in jittering of the Views, and a slight difference in offset between the View elements and the normal UI elements.

RPReplay_Final1711138263.mov

Relevant code:

import React from 'react'
import { Link } from 'react-router-dom';
import { Canvas, useFrame, ThreeElements } from '@react-three/fiber'
import { View, PerspectiveCamera } from '@react-three/drei';

import { motion } from 'framer-motion';

const ScrollingList: React.FC = () => {

  return (
    <motion.div initial={{opacity: 0}} animate={{opacity: 1, transition: {duration: 1 }}} exit={{opacity: 0, transition: {duration: 1 }}} className="w-screen h-screen flex flex-col overflow-y-scroll overflow-x-hidden bg-white">
      <h1 className="text-2xl font-black text-yellow-500 mt-12 ml-8">My Boxes</h1>
      <div className="flex-grow">
        {Array.apply(null, Array(20)).map(function(x, i) {
          return (
            <div className="h-48" key={"a"+i}>
              <div className="flex flex-row pb-10 justify-center">
                  {Array.apply(null, Array(3)).map(function(xx, ii) {
                    return (
                      <div className="flex flex-col" key={"b"+ii}>
                        <div className="w-32 h-36 overflow-hidden">
                          <View className="w-full h-full inline-block overflow-hidden">
                            <PerspectiveCamera makeDefault fov={40} position={[0, 5, 20]} />
                            <mesh position={[0, 0, 0]} scale={[3, 3, 3]}>
                              <boxGeometry />
                              <meshStandardMaterial color="#adadad" />
                            </mesh>
                          </View>
                        </div>
                        <div className="text-center">
                          <Link to={"/bla/"+i+"-"+ii} className="m-auto">
                            <h1 className="text-xl font-black text-yellow-500">Box</h1>
                            <h1 className="text-sm font-black text-gray-500">500</h1>
                          </Link>
                        </div>
                      </div>
                    )
                  })}
              </div>
            </div>
          )
        })}
        <Canvas
          style={{ position: 'fixed', top: 0, bottom: 0, left: 0, right: 0, overflow: 'hidden' }}
          eventSource={document.getElementById('root')!}>
          <View.Port />
        </Canvas>
      </div>
    </motion.div>
  );
};

export default ScrollingList;

Suggested solution:

The effect isn't as pronounced in Chrome and Firefox, so perhaps analysis could start with the difference between them.
Edit: Chrome on an iPhone has some jitter, where chrome in macOS doesn't.

@rossrossp rossrossp added the bug Something isn't working label Mar 22, 2024
@benhylak
Copy link

Just found this as well. ScrollControls is super noticeable.

@rossrossp
Copy link
Author

@benhylak
Copy link

benhylak commented Mar 24, 2024

fwiw on ScrollControls I'm only seeing this jitter on iOS

@mrcleandean
Copy link

mrcleandean commented May 17, 2024

Just discovered this as well. I was getting jitter in Safari and inertia in Chrome. After doing some digging and looking at a few examples I noticed something. Have a look at the following Code Sandbox:

https://codesandbox.io/s/bp6tmc

Notice the App.js uses a smooth scrolling package called @studio-freight/lenis, and it calls addEffect from @react-three/fiber to implement the Lenis instance. Also notice that the Lenis instance has { syncTouch: true } set.

The example has no jitter and no inertia, but as soon as you comment the two lines out with the Lenis instance and the addEffect, the jitter/inertia then become visible. I'm not sure why Lenis makes the jitter go away, but it's a fix for anyone looking.

I managed to fix the jitter and inertia in my own application by using ReactLenis with the useLenis hook instead of regular lenis. Hopefully this gets you further!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants