r3f
https://github.com/pmndrs/drei
box
import React from "react";
import { Canvas } from "@react-three/fiber";
export const BoxStory = () => (
<Canvas>
<mesh>
<boxGeometry />
</mesh>
</Canvas>
);
<Canvas>
の中が r3f の世界になる。
Canvas の chidren はもはや React のコンポーネントではなくて、
THREE.Scene を表現する感じになる。
Canvas の子孫の小文字タグは、
three.js の Object を示す規約のようだ。
https://threejs.org/docs/index.html?q=box#api/en/geometries/BoxGeometry
r3f
によって three.js
のプログラミングが必ずしも簡単になるわけではないけど、
React と組みあわせた HtmlCanvasElement の寿命管理や、
Resize, MouseEvent などのハンドリングなどは仕組みに乗るとよさそう。
Canvas の CSS は width, height: 100%
なので parent のwidth, heightをauto 以外にする必要あり。
ResizeObserver で width, height 指定
export default function GlCanvs() {
const ref = React.useRef<HTMLDivElement>(null);
const [size, setSize] = React.useState([300, 150]);
React.useEffect(() => {
resizeObserver = new ResizeObserver((entries) => {
for (const entry of entries) {
if (entry.contentBoxSize) {
const contentBoxSize = entry.contentBoxSize[0];
// console.log("box", contentBoxSize);
setSize([
Math.ceil(contentBoxSize.inlineSize),
Math.ceil(contentBoxSize.blockSize),
]);
} else {
// console.log(entry.contentRect);
setSize([
Math.ceil(entry.contentRect.width),
Math.ceil(entry.contentRect.height),
]);
}
break;
}
});
resizeObserver.observe(ref.current);
}, []);
return (
<Layout>
<div
ref={ref}
style={{
flexGrow: 1,
alignSelf: "stretch",
// background: "red",
}}
>
<Canvas
style={{
width: `${size[0]}px`, // 👈
height: `${size[1]}px`,
}}