不能将屏幕外画布与反应三纤维一起使用



我正在使用offcreencinvas(https://threejs.org/manual/#en/offscreencanvas)以在单独的线程上呈现react三个纤维元素。互联网上没有太多关于这方面的资源(但我发现了这个问题:https://github.com/pmndrs/react-three-fiber/issues/280)。我试着把它复制出来,但出了一个错误。

主线程创建画布:

// main.jsx (main thread)
import React from "react";
export const Main = () => {
const canvasRef = React.useRef();
React.useEffect(() => {
const offscreen = canvasRef.current.transferControlToOffscreen();
const worker = new Worker('worker.js');
worker.postMessage({
canvas: offscreen,
}, [offscreen])
}, []);
return (
<canvas ref={canvasRef} />
);
}

独立螺纹:

// worker.jsx (worker thread)
import { render } from 'react-three-fiber';
import { WebGLRenderer, Scene, PerspectiveCamera } from 'three';
self.onmessage = (event) => {
const { canvas } = event.data;
const scene = new Scene();
const renderer = new WebGLRenderer({ canvas });
const camera = new PerspectiveCamera( 75, canvas.width / canvas.height, 0.1, 1000 );
render(<gridHelper scale={[10, 10, 10]}/>, scene);
renderer.render(scene, camera);
}

当我呈现这个时,我得到一个错误,说";无法读取未定义的"的属性;。有人能帮我确定为什么会出现这个错误吗?或者提供一个使用具有反应三纤维的offscreencanvas的演示?

演示:https://f-loat.github.io/offscreen-canvas-demo

GitHub:https://github.com/F-loat/offscreen-canvas-demo

// main.js
import React, { useEffect } from 'react';
const App = () => {
const canvasRef = React.useRef();
useEffect(() => {
const canvas = canvasRef.current;
const offscreen = canvasRef.current.transferControlToOffscreen();
const worker = new Worker(new URL('./worker.js', import.meta.url));
worker.postMessage( {
drawingSurface: offscreen,
width: canvas.clientWidth,
height: canvas.clientHeight,
pixelRatio: window.devicePixelRatio,
}, [ offscreen ] );
}, []);
return (
<canvas ref={canvasRef} />
);
}
export default App
// worker.js
import React, { useRef, useState } from 'react'
import * as THREE from 'three'
import { extend, useFrame, createRoot, events } from '@react-three/fiber'
extend(THREE)
function Cube(props) {
// This reference will give us direct access to the mesh
const mesh = useRef()
// Set up state for the hovered and active state
const [hovered, setHover] = useState(false)
const [active, setActive] = useState(false)
// Subscribe this component to the render-loop, rotate the mesh every frame
useFrame((state, delta) => {
mesh.current.rotation.x += 0.01
mesh.current.rotation.y += 0.01
})
// Return view, these are regular three.js elements expressed in JSX
return (
<mesh
{...props}
ref={mesh}
scale={active ? 1.5 : 1}
onClick={() => setActive(!active)}
onPointerOver={() => setHover(true)}
onPointerOut={() => setHover(false)}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
</mesh>
)
}
const App = () => {
return (
<>
<ambientLight />
<pointLight position={[10, 10, 10]} />
<Cube position={[0, 0, 0]} />
</>
);
}
self.onmessage = (event) => {
const { drawingSurface: canvas, width, height, pixelRatio } = event.data;
const root = createRoot(canvas)
root.configure({
events,
size: {
width,
height,
},
dpr: pixelRatio, // important
})
root.render(<App />)
}
// @react-three/fiber/dist/index-1e2a4313.esm.js
+ var window = self || window
- gl.setSize(size.width, size.height);
+ gl.setSize(size.width, size.height, false);

最新更新