我正在尝试为我的投资组合制作一个 3D 终端。目前在 Next.js 中开发项目。这个想法是使用现有的包(https://www.npmjs.com/package/crt-terminal)并将Drei库的标签放入react-three-fiber。这是模型组件的代码:
import React, { useState, useEffect } from "react";
import { Canvas } from "@react-three/fiber";
import { OrbitControls, Stats } from "@react-three/drei";
import { useTheme } from "next-themes";
import TestComponent from "./TestComponent";
import { motion } from "framer-motion";
function Model() {
const { theme, setTheme } = useTheme();
const [initialZoom, setInitialZoom] = useState(null);
useEffect(() => {
if (window.innerWidth < 1000) {
setInitialZoom(0.5);
} else {
setInitialZoom(1);
}
}, []);
return (
<motion.div
id="canvas-container"
initial={{ y: 50 }}
animate={{ y: 0 }}
transition={{ duration: 0.5 }}
>
{initialZoom && (
<Canvas
camera={{ zoom: initialZoom }}
style={{ width: "100%", height: 700 }}
>
<OrbitControls
enablePan={true}
enableZoom={true}
enableRotate={true}
minPolarAngle={Math.PI / 2.2}
maxPolarAngle={Math.PI / 1.8}
minAzimuthAngle={-Math.PI / 12}
maxAzimuthAngle={Math.PI / 12}
/>
<TestComponent />
<Stats />
</Canvas>
)}
</motion.div>
);
}
export default Model;
这是要渲染的 Html 组件。
import React, { useEffect, useState, useRef } from "react";
import { Terminal, useEventQueue, textLine, textWord } from "crt-terminal";
import { IoTerminal } from "react-icons/io5";
import { VscChromeMaximize, VscChromeMinimize } from "react-icons/vsc";
import { CgClose } from "react-icons/cg";
import { OrbitControls, Html, Icosahedron } from "@react-three/drei";
import { Canvas, useFrame } from "react-three-fiber";
import { useThree } from "@react-three/fiber";
const bannerText = `
Welcome to my CLI. Kind of
`;
export default function TestComponent(props) {
const eventQueue = useEventQueue();
const [screenDimensions, setScreenDimensions] = useState([]);
const { print } = eventQueue.handlers;
const { size } = useThree();
useEffect(() => {
const currentDim = [size.width, size.height];
setScreenDimensions(currentDim);
}, []);
return (
<group>
<mesh position={[0, 0, 0]}>
<Html transform position={[0, 0, 0]}>
<div
style={{
width: screenDimensions[0] * 0.5,
height: screenDimensions[1] * 0.3,
display: "flex",
flexDirection: "column",
overflow: "hidden",
}}
className="html-transform-div"
>
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
<IoTerminal style={{ fontSize: 8, color: "black" }} />
<h1 style={{ fontSize: 6, marginLeft: 3, color: "black" }}>
Command Line
</h1>
</div>
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
<div className="canvas-minimize-div">
<VscChromeMinimize
style={{ fontSize: 8, marginTop: 4, color: "black" }}
/>
</div>
<div className="canvas-maximize-div">
<VscChromeMaximize style={{ fontSize: 8, color: "black" }} />
</div>
<div className="canvas-close-div">
<CgClose
style={{
fontSize: 8,
color: "#010308",
}}
/>
</div>
</div>
<Terminal
queue={eventQueue}
banner={[
textLine({ words: [textWord({ characters: bannerText })] }),
]}
className="Terminal"
onCommand={(command) =>
print([
textLine({
words: [
textWord({ characters: "You entered command: " }),
commandWord({ characters: command, prompt: ">" }),
],
}),
])
}
/>
</div>
</Html>
</mesh>
</group>
);
}
该组件渲染得很好,看起来很清晰,但是当我使用控件移动字符时,所有字符都变得模糊了。这个问题只发生在台式电脑上,一切都适用于移动设备。 搬家前
任何想法如何解决?谢谢