国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

帝國(guó)cms做笑話網(wǎng)站宣傳渠道和宣傳方式有哪些

帝國(guó)cms做笑話網(wǎng)站,宣傳渠道和宣傳方式有哪些,做網(wǎng)站自己買服務(wù)器,web服務(wù)器端技術(shù)主要包括最近在看three.js相關(guān)的東西,想著學(xué)習(xí)一下threejs給的examples。源碼是用html結(jié)合js寫的,恰好最近也在學(xué)習(xí)react,就用react框架學(xué)習(xí)一下。 本文參考的是threeJs給的第一個(gè)示例 three.js examples (threejs.org) 一、下載threeJS源碼 通常我們…

最近在看three.js相關(guān)的東西,想著學(xué)習(xí)一下threejs給的examples。源碼是用html結(jié)合js寫的,恰好最近也在學(xué)習(xí)react,就用react框架學(xué)習(xí)一下。

本文參考的是threeJs給的第一個(gè)示例

?three.js examples (threejs.org)

?一、下載threeJS源碼

通常我們只用通過npm引入threejs的包就可以使用threejs了。為什么這里需要下載源碼呢?因?yàn)槲覀円獜?fù)刻源碼給的示例,相關(guān)的模型我們是沒有的,需要使用源碼里用到的模型及解析工具

GitHub - mrdoob/three.js: JavaScript 3D Library.

?從git上拉取代碼后可以找到示例一的源碼

?閱讀源碼可以發(fā)現(xiàn),完成示例需要引入jsm/libs/draco/gltf/路徑以及models/gltf/LittlestTokyo.glb模型。

拷貝threeJS的必要的模型和方法

為了方便后續(xù)學(xué)習(xí),我們直接將這兩個(gè)文件夾jsm和models拷貝到react項(xiàng)目中;注意路徑最好是public下,public是默認(rèn)的靜態(tài)資源加載入口

?

?二、功能解析與改寫

react搭建及threejs引入可以參考我的之前的博客,這里不多贅述

Three.js機(jī)器人與星系動(dòng)態(tài)場(chǎng)景:實(shí)現(xiàn)3D渲染與交互式控制-CSDN博客

?引入必要信息

import { useEffect, useRef } from "react";
import * as THREE from "three";
import Stats from "three/examples/jsm/libs/stats.module.js";
import { GLTF, GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { RoomEnvironment } from "three/examples/jsm/environments/RoomEnvironment.js";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js";

初始化Render渲染器/Scene場(chǎng)景/?camer相機(jī)/controls軌道控制器


// 初始化渲染器的函數(shù)
/*** 初始化 WebGL 渲染器* @returns {THREE.WebGLRenderer} 創(chuàng)建并配置好的渲染器實(shí)例*/
// 初始化渲染
function initRender(): THREE.WebGLRenderer {// 創(chuàng)建一個(gè)WebGL渲染器const renderer = new THREE.WebGLRenderer({ antialias: true });// 根據(jù)設(shè)備像素比設(shè)置渲染器像素比renderer.setPixelRatio(window.devicePixelRatio);// 設(shè)置渲染器大小renderer.setSize(window.innerWidth, window.innerHeight);return renderer;
}// 初始化場(chǎng)景的函數(shù)
/*** 初始化場(chǎng)景* @param {THREE.WebGLRenderer} renderer - 渲染器實(shí)例* @returns {THREE.Scene} 創(chuàng)建并配置好的場(chǎng)景實(shí)例*/
function initScene(renderer: THREE.WebGLRenderer) {// 創(chuàng)建 PMREM 生成器const pmremGenerator = new THREE.PMREMGenerator(renderer);// 創(chuàng)建場(chǎng)景const scene = new THREE.Scene();// 設(shè)置場(chǎng)景背景scene.background = new THREE.Color(0xbfe3dd);// 設(shè)置場(chǎng)景環(huán)境scene.environment = pmremGenerator.fromScene(new RoomEnvironment(renderer), 0.04).texture;return scene;
}// 初始化相機(jī)的函數(shù)
/*** 初始化相機(jī)* @param {number} x - 相機(jī)在 x 軸的位置* @param {number} y - 相機(jī)在 y 軸的位置* @param {number} z - 相機(jī)在 z 軸的位置* @returns {THREE.PerspectiveCamera} 創(chuàng)建并配置好位置的相機(jī)實(shí)例*/
function initCamera(x: number, y: number, z: number) {const camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 100);camera.position.set(x, y, z);return camera;
}// 初始化控制器的函數(shù)
/*** 初始化軌道控制器* @param {THREE.PerspectiveCamera} camera - 相機(jī)實(shí)例* @param {THREE.WebGLRenderer} renderer - 渲染器實(shí)例* @returns {OrbitControls} 創(chuàng)建并配置好的軌道控制器實(shí)例*/
function initControls(camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer) {const controls = new OrbitControls(camera, renderer.domElement);controls.update();controls.enablePan = false;controls.enableDamping = true;return controls;
}

?組件核心方法Keyframes

采用react的函數(shù)式組件寫法,首字母大寫作為組件名,并導(dǎo)出

整個(gè)流程是初始化渲染器、scene場(chǎng)景、camera相機(jī)、controls軌道控制器;在場(chǎng)景中引入模型,并使用dracoLoader解壓GLTFLoader引入的模型,開啟模型上的動(dòng)畫,設(shè)置場(chǎng)景動(dòng)畫。

/*** Keyframes 組件函數(shù)*/
function Keyframes() {const containerRef = useRef<HTMLDivElement>(null); // 創(chuàng)建用于引用 HTML 元素的 refconst clock = new THREE.Clock(); // 創(chuàng)建時(shí)鐘實(shí)例const statsRef = useRef<Stats>(); // 創(chuàng)建用于引用統(tǒng)計(jì)信息的 refconst mixerRef = useRef<THREE.AnimationMixer>(); // 創(chuàng)建用于引用動(dòng)畫混合器的 refconst renderer = initRender(); // 初始化渲染器const scene = initScene(renderer); // 初始化場(chǎng)景const camera = initCamera(5, 2, 10); // 初始化相機(jī)const controls = initControls(camera, renderer); // 初始化控制器controls.target.set(0, 0.5, 0); // 設(shè)置控制器的目標(biāo)const dracoLoader = new DRACOLoader(); // 創(chuàng)建 Draco 加載器dracoLoader.setDecoderPath("jsm/libs/draco/gltf/"); // 設(shè)置 Draco 解碼器路徑const loader = new GLTFLoader(); // 創(chuàng)建 GLTF 加載器loader.setDRACOLoader(dracoLoader); // 為 GLTF 加載器設(shè)置 Draco 加載器// 加載 GLTF 模型loader.load("models/gltf/LittlestTokyo.glb",(gltf: GLTF) => {const model = gltf.scene; // 獲取模型的場(chǎng)景model.position.set(1, 1, 0); // 設(shè)置模型的位置model.scale.set(0.01, 0.01, 0.01); // 設(shè)置模型的縮放scene.add(model); // 將模型添加到場(chǎng)景mixerRef.current = new THREE.AnimationMixer(model); // 創(chuàng)建動(dòng)畫混合器mixerRef.current.clipAction(gltf.animations[0]).play(); // 播放動(dòng)畫renderer.setAnimationLoop(animate); // 設(shè)置渲染循環(huán)},undefined,(e) => {console.error(e); // 處理加載錯(cuò)誤},);// 渲染循環(huán)函數(shù)/*** 每一幀的更新和渲染邏輯*/function animate() {const delta = clock.getDelta(); // 獲取時(shí)間間隔mixerRef.current && mixerRef.current.update(delta); // 更新動(dòng)畫混合器controls.update(); // 更新控制器statsRef.current && statsRef.current.update(); // 更新統(tǒng)計(jì)信息renderer.render(scene, camera); // 渲染場(chǎng)景和相機(jī)}// 處理窗口大小改變的函數(shù)/*** 處理窗口大小改變時(shí)的相機(jī)和渲染器更新*/function onWindowResize() {camera.aspect = window.innerWidth / window.innerHeight; // 更新相機(jī)的寬高比camera.updateProjectionMatrix(); // 更新相機(jī)的投影矩陣controls.update(); // 更新控制器renderer.setSize(window.innerWidth, window.innerHeight); // 更新渲染器的大小}// 使用 useEffect 鉤子useEffect(() => {if (!containerRef.current) return;containerRef.current.appendChild(renderer.domElement); // 將渲染器的 DOM 元素添加到引用的元素中statsRef.current = new Stats(); // 創(chuàng)建統(tǒng)計(jì)信息實(shí)例containerRef.current.appendChild(statsRef.current.dom); // 將統(tǒng)計(jì)信息的 DOM 元素添加到引用的元素中window.addEventListener("resize", onWindowResize); // 添加窗口大小改變的監(jiān)聽事件return () => {window.removeEventListener("resize", onWindowResize); // 清除窗口大小改變的監(jiān)聽事件renderer.setAnimationLoop(null); // 清除渲染循環(huán)};}, []);return <div ref={containerRef}></div>; // 返回一個(gè)帶有 ref 的 div 元素
}
export default Keyframes; // 導(dǎo)出 Keyframes 組件

通過<div ref={containerRef}></div>?創(chuàng)建一個(gè)dom元素,用于3D場(chǎng)景掛載

?模型加載與Draco解碼

示例模型提供的是壓縮后的模型,在頁面加載時(shí)需要進(jìn)行解壓,必須使用dracoLoader方法,設(shè)置解碼方法所在路徑。在通過GLTFLoader導(dǎo)入。示例如下:

const dracoLoader = new DRACOLoader(); // 創(chuàng)建 Draco 加載器dracoLoader.setDecoderPath("jsm/libs/draco/gltf/"); // 設(shè)置 Draco 解碼器路徑const loader = new GLTFLoader(); // 創(chuàng)建 GLTF 加載器loader.setDRACOLoader(dracoLoader); // 為 GLTF 加載器設(shè)置 Draco 加載器// 加載 GLTF 模型loader.load("models/gltf/LittlestTokyo.glb",(gltf: GLTF) => {//處理模型},undefined,(e) => {console.error(e); // 處理加載錯(cuò)誤},);

AnimationMixer 動(dòng)畫混合器?

AnimationMixer動(dòng)畫混合器是用于場(chǎng)景中特定對(duì)象的動(dòng)畫的播放器。當(dāng)場(chǎng)景中的多個(gè)對(duì)象獨(dú)立動(dòng)畫時(shí),每個(gè)對(duì)象都可以使用同一個(gè)動(dòng)畫混合器。

  • 參數(shù):rootObject 混合器播放的動(dòng)畫所屬的對(duì)象。就是包含動(dòng)畫模型的場(chǎng)景對(duì)象。
  • 常用參數(shù)和屬性:
  1. .time 全局的混合器時(shí)間。
  2. .clipAction(AnimationClip) 返回所傳入的剪輯參數(shù)的AnimationAction對(duì)象。AnimationAction用來調(diào)度存儲(chǔ)在AnimationClip中的動(dòng)畫。
  • AnimationClip 動(dòng)畫剪輯,是一個(gè)可重用的關(guān)鍵幀軌道集,它代表動(dòng)畫。
  1. .getRoot() 返回混合器的根對(duì)象。
  2. .update() 推進(jìn)混合器時(shí)間并更新動(dòng)畫。在渲染函數(shù)中調(diào)用更新動(dòng)畫。

?在我們的示例中模型加載到場(chǎng)景時(shí)默認(rèn)時(shí)沒有動(dòng)畫的,也就是模型自身的動(dòng)畫比如小火車和風(fēng)扇小人都是不動(dòng)的。

?在模型加載的時(shí)候通過AnimationMixer開啟模型動(dòng)畫

  // 加載 GLTF 模型loader.load("models/gltf/LittlestTokyo.glb",(gltf: GLTF) => {const model = gltf.scene; // 獲取模型的場(chǎng)景model.position.set(1, 1, 0); // 設(shè)置模型的位置model.scale.set(0.01, 0.01, 0.01); // 設(shè)置模型的縮放scene.add(model); // 將模型添加到場(chǎng)景mixerRef.current = new THREE.AnimationMixer(model); // 創(chuàng)建動(dòng)畫混合器mixerRef.current.clipAction(gltf.animations[0]).play(); // 播放動(dòng)畫renderer.setAnimationLoop(animate); // 設(shè)置渲染循環(huán)},undefined,(e) => {console.error(e); // 處理加載錯(cuò)誤},);
setAnimationLoop動(dòng)畫循環(huán)??

在Three.js中,setAnimationLoop?方法是用來設(shè)置一個(gè)函數(shù),這個(gè)函數(shù)會(huì)在每一幀被調(diào)用來進(jìn)行渲染。這是必須的,因?yàn)樵赥hree.js中,渲染循環(huán)不是自動(dòng)開始的,你需要告訴渲染器何時(shí)以及如何進(jìn)行渲染。

以下是為什么加載模型時(shí)必須使用?setAnimationLoop?的一些原因:

  1. 渲染控制:通過?setAnimationLoop,你可以控制渲染循環(huán)的開始和結(jié)束。如果你不設(shè)置它,即使模型加載完成,也不會(huì)自動(dòng)開始渲染過程。

  2. 動(dòng)畫播放:在你的代碼中,你使用了?AnimationMixer?來播放模型中的動(dòng)畫。這個(gè)動(dòng)畫需要在每一幀更新,以確保動(dòng)畫的連貫性和流暢性。setAnimationLoop?允許你在每一幀更新動(dòng)畫狀態(tài)。

  3. 性能優(yōu)化:使用?setAnimationLoop?可以讓你在不需要渲染的時(shí)候停止渲染,比如在瀏覽器標(biāo)簽頁不可見時(shí),這樣可以節(jié)省資源并提高性能。

  4. 邏輯更新:在?animate?函數(shù)中,你可以執(zhí)行除了渲染之外的其他邏輯,比如更新動(dòng)畫、控制器和統(tǒng)計(jì)信息等。這些更新是渲染過程的一部分,需要在每一幀進(jìn)行。

如果你不使用?setAnimationLoop,你需要自己手動(dòng)創(chuàng)建一個(gè)循環(huán)來不斷調(diào)用?renderer.render(scene, camera),并且確保在合適的時(shí)機(jī)更新動(dòng)畫和其他邏輯。這通常是通過?requestAnimationFrame?函數(shù)來實(shí)現(xiàn)的,但Three.js提供了?setAnimationLoop?來簡(jiǎn)化這一過程。

總之,setAnimationLoop?是Three.js中用來啟動(dòng)和維持渲染循環(huán)的關(guān)鍵方法,特別是在涉及到動(dòng)畫的情況下,它是必須的。

?可以看到模型自身的多個(gè)動(dòng)畫都動(dòng)起來了

Stats.js幀檢測(cè)工具?

不管是做游戲還是做普通網(wǎng)頁,在這個(gè)時(shí)代基本都離不開動(dòng)畫。說到動(dòng)畫,第一個(gè)聯(lián)想到的概念就是“幀”。這是用來衡量和描述動(dòng)畫是否流暢的一個(gè)單位。

示例程序的左上角有個(gè)工具窗口持續(xù)監(jiān)測(cè)FPS數(shù)值?

FPS是“Frames Per Second”的縮寫,意為“每秒幀數(shù)”。在視頻游戲和計(jì)算機(jī)圖形學(xué)中,FPS用來衡量顯示設(shè)備每秒鐘能夠顯示的靜止圖像(幀)的數(shù)量。這個(gè)數(shù)值越高,表示圖像更新得越快,視覺效果就越流暢。

在游戲領(lǐng)域,高FPS通常意味著更平滑的游戲體驗(yàn),尤其是在快速移動(dòng)或復(fù)雜場(chǎng)景中。然而,FPS并不是唯一影響游戲體驗(yàn)的因素,圖像質(zhì)量、響應(yīng)時(shí)間和系統(tǒng)穩(wěn)定性也同樣重要。

一般來說,人眼能夠感知到的流暢動(dòng)畫大約需要30FPS以上,而60FPS或更高則被認(rèn)為是高質(zhì)量游戲體驗(yàn)的標(biāo)準(zhǔn)。不過,這也取決于個(gè)人的視覺感知能力和對(duì)流暢度的要求。

用法?

在使用?npm install three?下載的依賴包中已經(jīng)包含了?Stats.js?了

可以這樣引入到項(xiàng)目中

import Stats from "three/examples/jsm/libs/stats.module.js";

通過new Stats()方法創(chuàng)建一個(gè)stats實(shí)例?。默認(rèn)showPanel是0,顯示FPS面板。

?通過showPanel方法切換顯示方式;可以根據(jù)dom改變stats面板的位置,使用示例如下

    const statsRef = useRef<Stats>(); // 創(chuàng)建用于引用統(tǒng)計(jì)信息的 refstatsRef.current = new Stats(); // 創(chuàng)建統(tǒng)計(jì)信息實(shí)例statsRef.current.showPanel(1);statsRef.current.dom.style.position = "absolute"; // 設(shè)置統(tǒng)計(jì)信息的 DOM 元素的位置statsRef.current.dom.style.top = "0px"; // 設(shè)置統(tǒng)計(jì)信息的 DOM 元素的位置statsRef.current.dom.style.left = "0px"; // 設(shè)置統(tǒng)計(jì)信息的 DOM 元素的位置

通過操作dom的方式將stats節(jié)點(diǎn)追加到3D場(chǎng)景中

    containerRef.current.appendChild(statsRef.current.dom); // 將統(tǒng)計(jì)信息的 DOM 元素添加到引用的元素中

?默認(rèn)就顯示在屏幕的左上角

當(dāng)點(diǎn)擊該面板時(shí)還可以切換監(jiān)聽的類型

?響應(yīng)式窗口

頁面加載時(shí)給了初始的renderer的寬高,但是如果用戶使用過程中可視區(qū)域發(fā)生了變化renderer無法自動(dòng)使用屏幕

?可以在useEffect里通過事件監(jiān)聽瀏覽器的resize事件,當(dāng)瀏覽器尺寸變化時(shí)重新以最新的寬高設(shè)為renderer的尺寸信息

  // 處理窗口大小改變的函數(shù)/*** 處理窗口大小改變時(shí)的相機(jī)和渲染器更新*/function onWindowResize() {camera.aspect = window.innerWidth / window.innerHeight; // 更新相機(jī)的寬高比camera.updateProjectionMatrix(); // 更新相機(jī)的投影矩陣controls.update(); // 更新控制器renderer.setSize(window.innerWidth, window.innerHeight); // 更新渲染器的大小}// 使用 useEffect 鉤子useEffect(() => {if (!containerRef.current) return;containerRef.current.appendChild(renderer.domElement); // 將渲染器的 DOM 元素添加到引用的元素中statsRef.current = new Stats(); // 創(chuàng)建統(tǒng)計(jì)信息實(shí)例containerRef.current.appendChild(statsRef.current.dom); // 將統(tǒng)計(jì)信息的 DOM 元素添加到引用的元素中window.addEventListener("resize", onWindowResize); // 添加窗口大小改變的監(jiān)聽事件return () => {window.removeEventListener("resize", onWindowResize); // 清除窗口大小改變的監(jiān)聽事件renderer.setAnimationLoop(null); // 清除渲染循環(huán)};}, []);

完整代碼?

import { useEffect, useRef } from "react";
import * as THREE from "three";
import Stats from "three/examples/jsm/libs/stats.module.js";
import { GLTF, GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { RoomEnvironment } from "three/examples/jsm/environments/RoomEnvironment.js";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js";// 初始化渲染器的函數(shù)
/*** 初始化 WebGL 渲染器* @returns {THREE.WebGLRenderer} 創(chuàng)建并配置好的渲染器實(shí)例*/
// 初始化渲染
function initRender(): THREE.WebGLRenderer {// 創(chuàng)建一個(gè)WebGL渲染器const renderer = new THREE.WebGLRenderer({ antialias: true });// 根據(jù)設(shè)備像素比設(shè)置渲染器像素比renderer.setPixelRatio(window.devicePixelRatio);// 設(shè)置渲染器大小renderer.setSize(window.innerWidth, window.innerHeight);return renderer;
}// 初始化場(chǎng)景的函數(shù)
/*** 初始化場(chǎng)景* @param {THREE.WebGLRenderer} renderer - 渲染器實(shí)例* @returns {THREE.Scene} 創(chuàng)建并配置好的場(chǎng)景實(shí)例*/
function initScene(renderer: THREE.WebGLRenderer) {// 創(chuàng)建 PMREM 生成器const pmremGenerator = new THREE.PMREMGenerator(renderer);// 創(chuàng)建場(chǎng)景const scene = new THREE.Scene();// 設(shè)置場(chǎng)景背景scene.background = new THREE.Color(0xbfe3dd);// 設(shè)置場(chǎng)景環(huán)境scene.environment = pmremGenerator.fromScene(new RoomEnvironment(renderer), 0.04).texture;return scene;
}// 初始化相機(jī)的函數(shù)
/*** 初始化相機(jī)* @param {number} x - 相機(jī)在 x 軸的位置* @param {number} y - 相機(jī)在 y 軸的位置* @param {number} z - 相機(jī)在 z 軸的位置* @returns {THREE.PerspectiveCamera} 創(chuàng)建并配置好位置的相機(jī)實(shí)例*/
function initCamera(x: number, y: number, z: number) {const camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 100);camera.position.set(x, y, z);return camera;
}// 初始化控制器的函數(shù)
/*** 初始化軌道控制器* @param {THREE.PerspectiveCamera} camera - 相機(jī)實(shí)例* @param {THREE.WebGLRenderer} renderer - 渲染器實(shí)例* @returns {OrbitControls} 創(chuàng)建并配置好的軌道控制器實(shí)例*/
function initControls(camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer) {const controls = new OrbitControls(camera, renderer.domElement);controls.update();controls.enablePan = false;controls.enableDamping = true;return controls;
}/*** Keyframes 組件函數(shù)*/
function Keyframes() {const containerRef = useRef<HTMLDivElement>(null); // 創(chuàng)建用于引用 HTML 元素的 refconst clock = new THREE.Clock(); // 創(chuàng)建時(shí)鐘實(shí)例const statsRef = useRef<Stats>(); // 創(chuàng)建用于引用統(tǒng)計(jì)信息的 refconst mixerRef = useRef<THREE.AnimationMixer>(); // 創(chuàng)建用于引用動(dòng)畫混合器的 refconst renderer = initRender(); // 初始化渲染器const scene = initScene(renderer); // 初始化場(chǎng)景const camera = initCamera(5, 2, 10); // 初始化相機(jī)const controls = initControls(camera, renderer); // 初始化控制器controls.target.set(0, 0.5, 0); // 設(shè)置控制器的目標(biāo)const dracoLoader = new DRACOLoader(); // 創(chuàng)建 Draco 加載器dracoLoader.setDecoderPath("jsm/libs/draco/gltf/"); // 設(shè)置 Draco 解碼器路徑const loader = new GLTFLoader(); // 創(chuàng)建 GLTF 加載器loader.setDRACOLoader(dracoLoader); // 為 GLTF 加載器設(shè)置 Draco 加載器// 加載 GLTF 模型loader.load("models/gltf/LittlestTokyo.glb",(gltf: GLTF) => {const model = gltf.scene; // 獲取模型的場(chǎng)景model.position.set(1, 1, 0); // 設(shè)置模型的位置model.scale.set(0.01, 0.01, 0.01); // 設(shè)置模型的縮放scene.add(model); // 將模型添加到場(chǎng)景mixerRef.current = new THREE.AnimationMixer(model); // 創(chuàng)建動(dòng)畫混合器mixerRef.current.clipAction(gltf.animations[0]).play(); // 播放動(dòng)畫renderer.setAnimationLoop(animate); // 設(shè)置渲染循環(huán)},undefined,(e) => {console.error(e); // 處理加載錯(cuò)誤},);// 渲染循環(huán)函數(shù)/*** 每一幀的更新和渲染邏輯*/function animate() {const delta = clock.getDelta(); // 獲取時(shí)間間隔mixerRef.current && mixerRef.current.update(delta); // 更新動(dòng)畫混合器controls.update(); // 更新控制器statsRef.current && statsRef.current.update(); // 更新統(tǒng)計(jì)信息renderer.render(scene, camera); // 渲染場(chǎng)景和相機(jī)}// 處理窗口大小改變的函數(shù)/*** 處理窗口大小改變時(shí)的相機(jī)和渲染器更新*/function onWindowResize() {camera.aspect = window.innerWidth / window.innerHeight; // 更新相機(jī)的寬高比camera.updateProjectionMatrix(); // 更新相機(jī)的投影矩陣controls.update(); // 更新控制器renderer.setSize(window.innerWidth, window.innerHeight); // 更新渲染器的大小}// 使用 useEffect 鉤子useEffect(() => {if (!containerRef.current) return;containerRef.current.appendChild(renderer.domElement); // 將渲染器的 DOM 元素添加到引用的元素中statsRef.current = new Stats(); // 創(chuàng)建統(tǒng)計(jì)信息實(shí)例containerRef.current.appendChild(statsRef.current.dom); // 將統(tǒng)計(jì)信息的 DOM 元素添加到引用的元素中window.addEventListener("resize", onWindowResize); // 添加窗口大小改變的監(jiān)聽事件return () => {window.removeEventListener("resize", onWindowResize); // 清除窗口大小改變的監(jiān)聽事件renderer.setAnimationLoop(null); // 清除渲染循環(huán)};}, []);return <div ref={containerRef}></div>; // 返回一個(gè)帶有 ref 的 div 元素
}export default Keyframes; // 導(dǎo)出 Keyframes 組件

http://m.aloenet.com.cn/news/33022.html

相關(guān)文章:

  • 湘潭關(guān)鍵詞優(yōu)化報(bào)價(jià)成都網(wǎng)站建設(shè)方案優(yōu)化
  • 廣州專業(yè)網(wǎng)站建設(shè)seo是啥意思
  • 徐州建設(shè)安全監(jiān)督網(wǎng)站搜索引擎seo
  • 做軟件的公司網(wǎng)站有哪些百度站長(zhǎng)工具
  • 江蘇省工程建設(shè)信息網(wǎng)連云港seo優(yōu)化公司
  • 做網(wǎng)站改變圖片位置百度一下你就知道官網(wǎng)網(wǎng)址
  • frontpage做的網(wǎng)站好不好關(guān)鍵詞在線聽免費(fèi)
  • 空間租用網(wǎng)站模板情感營(yíng)銷的十大案例
  • 個(gè)人交互式網(wǎng)站備案鄭州百度推廣公司電話
  • c語言 做網(wǎng)站瀏覽器網(wǎng)站大全
  • 深圳網(wǎng)站建設(shè)微信開發(fā)長(zhǎng)沙做搜索引擎的公司
  • 廣州做網(wǎng)站技術(shù)seo公司培訓(xùn)課程
  • 科技創(chuàng)新網(wǎng)站建設(shè)策劃書溫州seo網(wǎng)站建設(shè)
  • 做網(wǎng)站用服務(wù)器軟文發(fā)布平臺(tái)媒體
  • 做網(wǎng)站到底需要什么it培訓(xùn)班出來現(xiàn)狀
  • 綠色環(huán)保企業(yè)網(wǎng)站模板鄭州seo公司
  • wordpress私人建站主題百度極速版客服人工在線咨詢
  • 網(wǎng)站策劃模版百度廣告銷售
  • 提高網(wǎng)站速度如何建立自己的網(wǎng)頁
  • 網(wǎng)站空間不支持php5.4關(guān)鍵詞查詢網(wǎng)站的工具
  • 網(wǎng)站建設(shè)seo運(yùn)營(yíng)規(guī)劃優(yōu)就業(yè)seo課程學(xué)多久
  • 可以做網(wǎng)站的行業(yè)手機(jī)網(wǎng)站排名優(yōu)化
  • 做網(wǎng)站的企劃書谷歌關(guān)鍵詞推廣怎么做
  • 建立自己的平臺(tái)網(wǎng)站嗎哪家公司做推廣優(yōu)化好
  • 國(guó)內(nèi)做任務(wù)得數(shù)字貨幣的網(wǎng)站關(guān)鍵詞歌詞表達(dá)的意思
  • 網(wǎng)頁設(shè)計(jì)與網(wǎng)站建設(shè)實(shí)戰(zhàn)大全競(jìng)價(jià)賬戶托管哪家好
  • 網(wǎng)站客服模板免費(fèi)二級(jí)域名注冊(cè)申請(qǐng)
  • 學(xué)校網(wǎng)站建設(shè)介紹騰訊朋友圈廣告怎么投放
  • 網(wǎng)站建設(shè) 開發(fā)的團(tuán)隊(duì)需要幾個(gè)人網(wǎng)絡(luò)營(yíng)銷的方式有幾種
  • 南橋做網(wǎng)站百度問答首頁