I have a Screen FC defined as
import React, { useRef, useEffect } from "react";
import * as THREE from 'three';
import { CSS3DRenderer, CSS3DObject } from 'three/addons/renderers/CSS3DRenderer.js';
interface ScreenProps {
position: [number, number, number];
}
const Screen: React.FC<ScreenProps> = ({ position }) => {
const screenRef = useRef<THREE.Group | null>(null);
const cssRenderer = new CSS3DRenderer();
cssRenderer.setSize(window.innerWidth, window.innerHeight);
useEffect(() => {
const myElement = document.createElement("div");
myElement.innerHTML = "Hello, World!";
myElement.style.width = "200px";
myElement.style.height = "100px";
myElement.style.background = "black";
myElement.style.color = "black";
myElement.style.textAlign = "center";
myElement.style.lineHeight = "100px";
const object = new CSS3DObject(myElement);
object.position.set(position[0], position[1], position[2]);
if (screenRef.current) {
screenRef.current.add(object);
}
return () => {
if (screenRef.current) {
screenRef.current.remove(object);
}
};
}, [position]);
return <group ref={screenRef}/>;
};
export default Screen;
Which I want to display flat on a screen defined in an Office FC:
import React, { useRef } from 'react';
import { useGLTF, Html } from '@react-three/drei';
import { a } from '@react-spring/three';
import Hitbox from '../Hitbox';
import Screen from '../Screen';
import officeDraco from '../../assets/3d/office_draco.glb';
// Path to Draco decoder files
const dracoDecoderPath = '/path_to_draco_decoder/';
export const Office: React.FC<{ onDeskClick: () => void }> = ({ onDeskClick }) => {
const { nodes, materials } = useGLTF(officeDraco) as any;
const monitorPosition = nodes.Cube009_2?.position || [0, 0, 0];
console.log(monitorPosition)
return (
{/* ...... */}
{/* Monitor 1 Screen */}
<group position={[-0.195, 0.355, -0.036]} scale={[0.091, 0.012, 0.406]}>
<mesh
castShadow
receiveShadow
geometry={nodes.Cube008.geometry}
material={materials['Material.019']}
/>
<mesh
castShadow
receiveShadow
geometry={nodes.Cube008_1.geometry}
material={materials['Material.020']}>
<Html transform>
<iframe
src="www.google.com"
width="100%"
height="100%"
style={{ border: 'none'}}
/>
</Html>
</mesh>
</group>
<group
position={[-0.188, 0.389, 0.269]}
rotation={[0, 0.08, 0]}
scale={[0.091, 0.012, 0.406]}>
<mesh
castShadow
receiveShadow
geometry={nodes.Cube009_1.geometry}
material={materials['Material.019']}
/>
{/* Monitor 2 Screen */}
<mesh
castShadow
receiveShadow
geometry={nodes.Cube009_2.geometry}
material={materials['Material.020']}
/>
<Screen position={[-0.936, 43.282, -0.183]} />
</group>
<mesh
castShadow
receiveShadow
geometry={nodes.Background.geometry}
material={materials['Material.012']}
position={[-0.936, 43.282, -0.183]}
rotation={[-3.12, 0.004, -0.018]}
scale={[1.001, 2.307, 1.001]}
/>
{/* ...... */}
)
}
useGLTF.preload('/office_draco.glb')
export default Office
Currently, the screen both does not display the 'Hello World' message (instead showing a copy of what is visible in the window) but is also perpendicular to the mesh it's meant to sit on? How can I correct this?
I have tried both using my Screen component and a Html component as well as adjusting the rotation of the Screen with rotation={[-Math.PI/4, 0, 0]}, however it is not sat in the right place. I am expecting the screen to be overlayed on the corresponding mesh representing a computer screen.