0

我正在尝试为我的投资组合制作一个 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>
  );
}

该组件渲染得很好,看起来很清晰,但是当我使用控件移动字符时,所有字符都变得模糊了。这个问题只发生在台式电脑上,一切都适用于移动设备。 搬家前

搬家后

任何想法如何解决?谢谢

4

0 回答 0