国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

用Three.js打造酷炫3D個人網(wǎng)站(含源碼)

這篇具有很好參考價值的文章主要介紹了用Three.js打造酷炫3D個人網(wǎng)站(含源碼)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

引言

個人網(wǎng)站是程序員的第二張簡歷。如果你有酷炫的個人網(wǎng)頁,面試官對你的好感度會蹭蹭蹭往上漲。

在疫情隔離期間,我用Three.jsAmmo.js制作了一個可交互的3D個人網(wǎng)頁。

在線預覽地址: www.ryan-floyd.com/

Three.js的3D世界

當我在Google Experiments閑逛時,我發(fā)現(xiàn)非常多的作品都是用three.js寫的。

three.js是一個讓3D網(wǎng)頁應用開發(fā)變得簡單的庫。它誕生于2010年,作者是Ricardo Cabello (Mr.doob),,在github上有超過1300多的貢獻者,在所有倉庫中star數(shù)排行第38。

當看到Google Experiments上那些酷炫的3D效果后,我決定開始學習three.js。

Three.js的工作機制

(3D應用的組件結(jié)構(gòu),圖片來自discoverthreejs.com)

Three.js使得在瀏覽器展示3D圖像變得容易,它的底層是基于WebGL,它使瀏覽器能借助系統(tǒng)顯卡在canvas中繪制3D畫面。

WebGL自身只能繪制點(points)、線(lines)和三角形(triangles),而Three.jsWebGL進行了封裝,使我們能夠非常方便地創(chuàng)建 物體(objects), 紋理(textures), 進行 3D 計算等操作。

使用Three.js,我們將所有物體(objects)添加到場景(scene)中,然后將需要渲染的數(shù)據(jù)傳遞給渲染器(renderer),渲染器負責將場景在 <canvas> 畫布上繪制出來。

(Three.js 應用架構(gòu),圖片來自threejsfundamentals.org)

對于一個 Three.js 應用,最核心的就是場景(scene object),上面是一張場景圖(scene graph)。

在一個3D引擎中,場景圖是一個層級結(jié)構(gòu)的樹狀圖,樹中的每一個節(jié)點代表空間中的一部分。這種結(jié)構(gòu)有點像DOM樹,但Three.js的場景(scene)更像虛擬DOM,它只更新和渲染場景中有變化的部分。而這一切的基礎,是 Three.js 的 WebGLRenderer 類,它把我們的代碼轉(zhuǎn)換成 GPU 中的數(shù)據(jù),瀏覽器再將這些數(shù)據(jù)渲染出來。

場景中的物體,也叫Mesh。在 Three.js 的世界中,Mesh 是由 幾何體Geometry(決定物體形狀) + 材質(zhì)Material(決定物體外觀)構(gòu)成。

場景中的另一個重要元素,就是相機camera,它決定了場景中 哪些部分以怎樣的視覺效果 被繪制在canvas畫布上。

然后是動畫,為了實現(xiàn)動畫,渲染器(renderer)通常使用requestAnimationFrame()方法,以每秒60次的頻率將場景更新繪制在canvas上。requestAnimationFrame()方法的原理和使用可以參考MDN。

下面這個例子來自Three.js官方文檔,創(chuàng)建了一個旋轉(zhuǎn)的 3D 立方體。

<html>
  <head>
    <title>My first three.js app</title>
    <style>
      body {
        margin: 0;
      }
      canvas {
        display: block;
      }
    </style>
  </head>
  <body>
    <script src="https://unpkg.com/three@0.119.0/build/three.js"></script>
    <script>
      //創(chuàng)建場景和相機
      var scene = new THREE.Scene();
      var camera = new THREE.PerspectiveCamera(
        75,
        window.innerWidth / window.innerHeight,
        0.1,
        1000
      );

      //創(chuàng)建渲染器,設置尺寸為窗口尺寸,并將渲染后的元素添加到body
      var renderer = new THREE.WebGLRenderer();
      renderer.setSize(window.innerWidth, window.innerHeight);
      document.body.appendChild(renderer.domElement);

      //創(chuàng)建一個Mesh(綠色的3D立方體),并添加到場景中
      var geometry = new THREE.BoxGeometry();
      var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
      var cube = new THREE.Mesh(geometry, material);
      scene.add(cube);

      //設置照相機的位置
      camera.position.z = 5;

      //瀏覽器每次渲染的時候更新立方體的旋轉(zhuǎn)角度
      var animate = function () {
        requestAnimationFrame(animate);

        cube.rotation.x += 0.01;
        cube.rotation.y += 0.01;

        renderer.render(scene, camera);
      };

      animate();
    </script>
  </body>
</html>
復制代碼

效果如下:

轉(zhuǎn)存失敗重新上傳取消

Ammo.js物理引擎

Ammo.js 是將 Bullet物理引擎 直接移植到JavaScript的產(chǎn)物(Bullet Physics是一個開源的物理模擬引擎)。我對物理引擎底層的工作原理理解得不太深入,簡而言之,物理引擎根據(jù)你傳入的參數(shù)(比如重力),創(chuàng)建循環(huán),在每次循環(huán)中更新狀態(tài),從而模擬出自然的物理運動和碰撞等效果。

循環(huán)中的物體(通常也是剛體),具有力、質(zhì)量、慣性、摩擦力等物理屬性。每次循環(huán),通過不斷檢查所有物體的位置、狀態(tài)和運動來檢測碰撞和交互。如果發(fā)生交互,對象位置將根據(jù)經(jīng)過的時間和對象的物理屬性進行更新。下面是我代碼中的一個片段,顯示了如何創(chuàng)建物理引擎循環(huán)以及如何將它添加到Three.js的sphere球體中。

//引入庫
import * as THREE from "three";
import * as Ammo from "./builds/ammo";
import {scene} from "./resources/world";

//初始化 Ammo.js 物理引擎
Ammo().then((Ammo) => {

    // 創(chuàng)建物理世界
    function createPhysicsWorld() {

        //完全碰撞檢測算法
        let collisionConfiguration = new Ammo.btDefaultCollisionConfiguration();

        // 重疊對/碰撞的調(diào)度計算
        let dispatcher = new Ammo.btCollisionDispatcher(collisionConfiguration);

        // 所有可能碰撞對的寬相位碰撞檢測列表
        let overlappingPairCache = new Ammo.btDbvtBroadphase();

        // 使物體正確地交互,考慮重力、力、碰撞等
        let constraintSolver = new Ammo.btSequentialImpulseConstraintSolver();

        // 根據(jù)這些參數(shù)創(chuàng)建物理世界。 參考bullet physics文檔
        let physicsWorld = new Ammo.btDiscreteDynamicsWorld(
            dispatcher,
            overlappingPairCache,
            constraintSolver,
            collisionConfiguration
        );

        // 添加重力
        physicsWorld.setGravity(new Ammo.btVector3(0, -9.8, 0));
    }

    //創(chuàng)建球體
    function createBall(){
        //球體參數(shù)
        let pos = {x: 0, y: 0, z: 0};
        let radius = 2;
        let quat = {x: 0, y: 0, z: 0, w: 1};
        let mass = 3;

        //three.js相關(guān)代碼

        //創(chuàng)建球體并添加到場景中
        let ball = new THREE.Mesh(new THREE.SphereBufferGeometry(radius), new THREE.MeshStandardMaterial({color: 0xffffff}));
        ball.position.set(pos.x, pos.y, pos.z);
        scene.add(ball);

        //Ammo.js相關(guān)代碼

        //設置位置和旋轉(zhuǎn)
        let transform = new Ammo.btTransform();
        transform.setOrigin(new Ammo.btVector3(pos.x, pos.y, pos.z));
        transform.setRotation(
            new Ammo.btQuaternion(quat.x, quat.y, quat.z, quat.w)
        );

        //設置物體運動
        let motionState = new Ammo.btDefaultMotionState(transform);

        //設置碰撞邊界框
        let collisionShape = new Ammo.btSphereShape(radius);
        collisionShape.setMargin(0.05);

        //設置慣性
        let localInertia = new Ammo.btVector3(0, 0, 0);
        collisionShape.calculateLocalInertia(mass, localInertia);

        //生成創(chuàng)建剛體(物體)的結(jié)構(gòu)信息
        let rigidBodyStructure = new Ammo.btRigidBodyConstructionInfo(
            mass,
            motionState,
            collisionShape,
            localInertia
        );

        //基于上面的結(jié)構(gòu)信息創(chuàng)建物體
        let body = new Ammo.btRigidBody(rigidBodyStructure);

        //當物體運動時,為其添加摩擦力
        body.setFriction(10);
        body.setRollingFriction(10);

        // 將物體添加到物理世界,這樣Ammo.js引擎才能不斷更新物體的狀態(tài)
        physicsWorld.addRigidBody(body);
    }

    createPhysicsWorld();
    createBall()
}
復制代碼

運動和交互

在Ammo.js模擬的物理世界中,交互是基于屬性和力計算的。

每個對象有一個邊界框(bounding box)屬性,物理引擎會根據(jù)這個邊界框來檢測物體的位置。

在每個動畫循環(huán)中檢查所有對象的邊界框后,如果任意兩個對象的邊界框位于同一位置,引擎將記錄為“碰撞”,并相應地更新對象。 對于剛體來說,這意味著阻止兩個物體處于同一位置。

下面是我的代碼片段,顯示了渲染循環(huán)和世界物理是如何更新的。

//渲染框架
function renderFrame() {

    //記錄上一次渲染的時間
    let deltaTime = clock.getDelta();

    //基于用戶輸入,計算球會受到的力和產(chǎn)生的速度
    moveBall();

    //根據(jù)時間更新物理世界狀態(tài)
    updatePhysics(deltaTime);

    //進行渲染
    renderer.render(scene, camera);

    // 循環(huán)
    requestAnimationFrame(renderFrame);
}

//更新物理世界狀態(tài)的方法定義
function updatePhysics(deltaTime) {

    physicsWorld.stepSimulation(deltaTime, 10);

    //遍歷“剛體”列表,并更新物理世界中的所有剛體狀態(tài)
    for (let i = 0; i < rigidBodies.length; i++) {

        //變量定義:three.js需要的meshObject,和ammo.js需要的ammoObject
        let meshObject = rigidBodies[i];
        let ammoObject = meshObject.userData.physicsBody;

        //獲取物體當前運動狀態(tài)
        let objectMotion = ammoObject.getMotionState();

        //如果物體正在移動,則獲取物體的當前位置和旋轉(zhuǎn)信息
        if (objectMotion) {
            objectMotion.getWorldTransform(transform);
            let mPosition = transform.getOrigin();
            let mQuaternion = transform.getRotation();

            // 更新物體的位置和旋轉(zhuǎn)狀態(tài)
            meshObject.position.set(mPosition.x(), mPosition.y(), mPosition.z());
            meshObject.quaternion.set(mQuaternion.x(), mQuaternion.y(), mQuaternion.z(), mQuaternion.w());
        }
    }
}
復制代碼

用戶輸入

我們希望用戶在桌面和觸摸屏移動設備上都能夠在應用中移動球體。

對于鍵盤事件,當按下箭頭鍵時,通過監(jiān)聽“keydown”和“keyup”事件對球體添加相應方向的力。

對于觸摸屏,在屏幕上創(chuàng)建了一個操縱桿控制器。然后,我們將“touchstart”、“touchmove”和“touchend”事件監(jiān)聽器添加到用于控制的div元素(控制器)中。

控制器會跟蹤用戶手指移動的起始、當前和結(jié)束坐標,然后在每次渲染時相應地更新球的受力。

下面只是控制器代碼的一個片段,展示了一些大致的概念。有關(guān)完整代碼,請從本文底部的源代碼地址獲取。文章來源地址http://www.zghlxwxcb.cn/news/detail-418512.html

// 在坐標平面上保持對當前球體運動的跟蹤
let moveDirection = { left: 0, right: 0, forward: 0, back: 0 };

//控制器div在屏幕上的位置坐標
let coordinates = { x: 0, y: 0 };

//保存觸摸事件的起始坐標的變量
let dragStart = null;

//創(chuàng)建控制器div元素
const stick = document.createElement("div");

//監(jiān)聽用戶觸摸點的移動
function handleMove(event) {
    //沒有移動,返回
    if (dragStart === null) return;

    //有移動,獲取新的觸摸點的x、y坐標
    if (event.changedTouches) {
        event.clientX = event.changedTouches[0].clientX;
        event.clientY = event.changedTouches[0].clientY;
    }

    //根據(jù)觸摸點的移動,計算出控制器div的實時坐標
    const xDiff = event.clientX - dragStart.x;
    const yDiff = event.clientY - dragStart.y;
    const angle = Math.atan2(yDiff, xDiff);
    const distance = Math.min(maxDiff, Math.hypot(xDiff, yDiff));
    const xNew = distance * Math.cos(angle);
    const yNew = distance * Math.sin(angle);
    coordinates = { x: xNew, y: yNew };

    //根據(jù)實時坐標更新樣式
    stick.style.transform = `translate3d(${xNew}px, ${yNew}px, 0px)`;

    //根據(jù)坐標計算出球的運動方向
    touchEvent(coordinates);
}

//根據(jù)用戶的觸摸點移動坐標計算出球的運動方向
function touchEvent(coordinates) {

    // 向右運動
    if (coordinates.x > 30) {
        moveDirection.right = 1;
        moveDirection.left = 0;
    // 向左運動
    } else if (coordinates.x < -30) {
        moveDirection.left = 1;
        moveDirection.right = 0;
    } else {
        moveDirection.right = 0;
        moveDirection.left = 0;
    }

    //向前運動
    if (coordinates.y > 30) {
        moveDirection.back = 1;
        moveDirection.forward = 0;
    //向后運動
    } else if (coordinates.y < -30) {
        moveDirection.forward = 1;
        moveDirection.back = 0;
    } else {
        moveDirection.forward = 0;
        moveDirection.back = 0;
    }
}

到了這里,關(guān)于用Three.js打造酷炫3D個人網(wǎng)站(含源碼)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務器費用

相關(guān)文章

  • 2022最新個人發(fā)卡網(wǎng)站源碼+支持傻瓜式安裝/全開源的

    2022最新個人發(fā)卡網(wǎng)站源碼+支持傻瓜式安裝/全開源的

    2022最新個人發(fā)卡網(wǎng)站源碼+支持傻瓜式安裝/全開源的,這發(fā)卡網(wǎng)站源碼簡約大氣,看著還是挺不錯的。 安裝教程: 1.將源碼上傳至服務器根目錄 2.將源碼進行解壓 3.域名/install安裝程序 4.登錄后臺地址域名/admin 5.后臺admin 123456 whgwu.lanzouw.com/ieomn06gt5if

    2024年02月12日
    瀏覽(314)
  • 基于SSM+vue框架的個人博客網(wǎng)站源碼和論文

    基于SSM+vue框架的個人博客網(wǎng)站源碼和論文

    基于SSM+vue框架的個人博客網(wǎng)站源碼和論文061 ?開發(fā)工具:idea? ?數(shù)據(jù)庫mysql5.7+ ?數(shù)據(jù)庫鏈接工具:navcat,小海豚等 ? 技術(shù):ssm (設計)研究背景與意義 關(guān)于博客的未來:在創(chuàng)辦了博客中國(blogchina)、被譽為“博客教父”的方興東接受了記者的專訪。他認為,博客這一事物在中

    2024年02月11日
    瀏覽(22)
  • 大學生PHP個人博客網(wǎng)站源碼 簡單個人動態(tài)網(wǎng)站設計模板 PHP畢業(yè)設計成品 學生PHP MYSQL日志管理系統(tǒng)網(wǎng)頁

    大學生PHP個人博客網(wǎng)站源碼 簡單個人動態(tài)網(wǎng)站設計模板 PHP畢業(yè)設計成品 學生PHP MYSQL日志管理系統(tǒng)網(wǎng)頁

    PHP MYSQL個人博客網(wǎng)站作品使用php+mysql開發(fā),系統(tǒng)編碼簡單,大學生PHP畢業(yè)設計水平。系統(tǒng)隨處可見增刪改查等基本操作,有批量刪除之功能,涉及的知識點比較全面。 數(shù)據(jù)庫共6張數(shù)據(jù)表,表之間有關(guān)聯(lián),設計合理;系統(tǒng)具有管理員和會員兩種用戶角色,管理員(即日志的所

    2024年02月12日
    瀏覽(30)
  • 個人網(wǎng)站制作 Part 3 用JS添加高級交互(表單驗證、動態(tài)內(nèi)容更新) | Web開發(fā)項目

    個人網(wǎng)站制作 Part 3 用JS添加高級交互(表單驗證、動態(tài)內(nèi)容更新) | Web開發(fā)項目

    歡迎回到基礎Web開發(fā)練手項目系列! 在前兩篇博文中,我們創(chuàng)建了個人網(wǎng)站的基本結(jié)構(gòu)、樣式、導航欄、項目展示、聯(lián)系信息、表單交互和動畫效果。 本篇將繼續(xù)豐富你的網(wǎng)站,為其添加更高級的交互性功能,使用JavaScript進行操作。 ??表單驗證 ??步驟 1: 添加JavaScript文件

    2024年02月01日
    瀏覽(34)
  • 基于HTML5的個人網(wǎng)頁的網(wǎng)站設計與實現(xiàn) 畢業(yè)設計-附源碼031623

    基于HTML5的個人網(wǎng)頁的網(wǎng)站設計與實現(xiàn) 畢業(yè)設計-附源碼031623

    隨著互聯(lián)網(wǎng)的不斷發(fā)展和中國網(wǎng)絡人口的日益增長,建立個人網(wǎng)站,不但可以剛好的展示自己,而且可以提高自己在計算機應用方面的能力。故本次作業(yè),我選擇制作個人網(wǎng)頁的網(wǎng)站。個人在設計時考慮的多為個人的興趣喜好,而不注重商業(yè)的展示。內(nèi)容以反映個人為中心,

    2024年02月05日
    瀏覽(23)
  • Three.js--》穿越虛擬門檻打造的3D登錄界面

    Three.js--》穿越虛擬門檻打造的3D登錄界面

    今天簡單實現(xiàn)一個three.js的小Demo,加強自己對three知識的掌握與學習,只有在項目中才能靈活將所學知識運用起來,話不多說直接開始。 目錄 項目搭建 初始化three代碼 添加背景與地球 星星動畫效果 星云動畫效果 實現(xiàn)登錄框效果 項目搭建 本案例還是借助框架書寫three項目,

    2024年04月23日
    瀏覽(24)
  • 一篇從零開始、步驟完整的網(wǎng)站搭建教程(全篇7000字、102張截圖說明,力求每一個人都能看懂,附源碼)

    一篇從零開始、步驟完整的網(wǎng)站搭建教程(全篇7000字、102張截圖說明,力求每一個人都能看懂,附源碼)

    從今年八月開始到現(xiàn)在自己也是從0開始做了有兩個網(wǎng)站: 這中間也經(jīng)常有不了解的地方需要去查。其實網(wǎng)上的資料也不少 但可能相對比較零散,需要反復的查來查去,費時又累心 那這次有時間就想著說寫一篇從零開始、步驟完整的網(wǎng)站搭建教程 希望能幫助大家節(jié)省時間,不

    2023年04月09日
    瀏覽(23)
  • 如何用Three.js + Blender打造一個web 3D展覽館

    如何用Three.js + Blender打造一個web 3D展覽館

    作者:vivo 互聯(lián)網(wǎng)前端團隊- Wei Xing? 運營活動新玩法層出不窮,web 3D炙手可熱,本文將一步步帶大家了解如何利用Three.js和Blender來打造一個沉浸式web 3D展覽館。 3D展覽館是什么,先來預覽下效果: 看起來像個3D冒險類手游,用戶可以操縱屏幕中央的虛擬搖桿,以第一人稱視角

    2024年02月16日
    瀏覽(94)
  • 六步快速搭建個人網(wǎng)站

    目錄 第一步、選擇搭建平臺WordPress 第二步、選域名 1)域名在哪買? 2)域名怎么選? 3)以阿里云為例,講解怎么買域名 第三步、選擇服務器 第四步、申請主機、安裝WordPress 第五步、選擇WordPress模板 1. Blocksy(免費) 2. Astra(免費) 3. Kadence(免費) 第六步、安裝WordPres

    2024年02月08日
    瀏覽(27)
  • 3D沉浸式旅游網(wǎng)站開發(fā)案例復盤【Three.js】

    3D沉浸式旅游網(wǎng)站開發(fā)案例復盤【Three.js】

    Plongez dans Lyon網(wǎng)站終于上線了。 我們與 Danka 團隊和 Nico Icecream 共同努力,打造了一個令我們特別自豪的流暢的沉浸式網(wǎng)站。 這個網(wǎng)站是專為 ONLYON Tourism 和會議而建,旨在展示里昂最具標志性的活動場所。觀看簡短的介紹視頻后,用戶可以進入城市的交互式風景如畫的地圖,

    2024年02月12日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包