1

I have created a iFrame on my 3D website in which renders a path from my portfolio. I have been attempting to scroll or touch (mobile) this iFrame for a while now, the desktop version works fine, you can scroll, access pages, etc although on mobile, the touch event does not seem to happens.
I have searched several posts and fixes, but none of them made the touch event, or touch scroll from this iframe to work.
You can access my website through https://niltonsf.dev and on the top right select viewWebpage to focus on the html screen.
Here is the component in which renders the iframe:

import { Html } from "@react-three/drei";
import { Dispatch, SetStateAction } from "react";
import { isMobile } from "react-device-detect";
import * as THREE from "three";

interface MonitorProps {
  geometry: THREE.BufferGeometry;
  screen: THREE.Mesh;
  bakedTexture: THREE.Texture;
  setIsPointerOnHtml: Dispatch<SetStateAction<boolean>>;
  isFocusOnHtml: boolean;
}

export default function Monitor({
  geometry,
  screen,
  bakedTexture,
  setIsPointerOnHtml,
  isFocusOnHtml,
}: MonitorProps) {
  return (
    <>
      <primitive object={screen}>
        <group position={[-2.57, 1.8, -0.01]} rotation-y={1.565}>
          <Html
            transform
            prepend
            wrapperClass="htmlScreen"
            scale={0.35}
            distanceFactor={1.17}
            zIndexRange={[0, 0]}
          >
            <div
              onClick={(e) => {
                if (!isFocusOnHtml) e.preventDefault();
              }}
              onPointerEnter={(e) => {
                if (isFocusOnHtml) setIsPointerOnHtml(true);
              }}
              onPointerLeave={(e) => {
                if (isFocusOnHtml) setIsPointerOnHtml(false);
              }}
            >
              <iframe
                id="iframe"
                src="https://niltonsf.dev/static"
                // src="http://192.168.1.13:3000/static"
                title="myStaticWebsite"
                style={{
                  width: isMobile ? 1200 : 1500,
                }}
              />
            </div>
          </Html>

          <mesh>
            <planeGeometry args={[1.535, 0.69]} />
            <meshPhysicalMaterial
              blending={THREE.NoBlending}
              opacity={0}
              color={"black"}
              side={THREE.DoubleSide}
            />
          </mesh>
        </group>
      </primitive>
      <mesh geometry={geometry}>
        <meshBasicMaterial map={bakedTexture} />
      </mesh>
    </>
  );
}

This is the main css file:

#root {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: white;
  -webkit-overflow-scrolling: touch;
}

.htmlScreen iframe {
  height: 700px;
  border: none;
  background: #000;
  overflow-y: scroll;
  touch-action: touch;
}

canvas {
  touch-action: touch;
}

EDIT: It seems to be something with iPhones, Android devices work correctly

Nilton Schumacher F
  • 814
  • 3
  • 13
  • 43
  • Hard to tell for sure since its pretty hard debugging compiled JS but, There seems to be a stacking context issue in mobile. Safari mobile debugger shows composite layers for the canvas element on top of the iframe, making it impossible to select or click or scroll on the contents of the iframe (try to select the text, links, etc.). If I understand your code correctly.. My guess is your event listeners to onPointerEnter/Leave are not firing because of this on mobile. Could you try debugging those to discard that option? – Cato Jan 12 '23 at 03:35
  • I think your event listeners are not firing in mobile. – Cato Jan 12 '23 at 04:25
  • It seems to be something with iPhones – Nilton Schumacher F Jan 12 '23 at 23:47

0 Answers0