前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用Three.Js制作3D相册

使用Three.Js制作3D相册

原创
作者头像
查拉图斯特拉说
发布2024-04-26 00:12:21
1790
发布2024-04-26 00:12:21

前言

ThreeJS是一个用JavaScript写的开源3D图形库,它有个简单但是功能强大的3D渲染引擎,可以在网页浏览器里快速创建和展示3D图形。ThreeJS是一个功能强大、使用简单的3D图形库,提供了一个强大的3D渲染工具,大大降低了创建3D应用程序的难度。

效果图

解析

安装

代码包可以到网上去找一些迷你版本的包,先放在本地用一下,然后跑终端可以从终端运行:npx vite

插件

Three.js 开箱即用,包含 3D 引擎的基础知识。其他 Three.js 组件(例如控件、加载器和后处理效果)是addons/目录的一部分。插件不需要单独安装,但需要单独导入

轨道控制

轨道控制允许相机围绕目标旋转。 要使用此功能,与 /examples 目录中的所有文件一样,您必须将该文件单独包含在 HTML 中。

OrbitControls 是一个附加组件,必须显式导入。请参阅安装/插件

import{OrbitControls}from'three/addons/controls/OrbitControls.js';

创建场景

为了真正能够用 Three.js 显示任何东西,我们需要三样东西:场景、相机和渲染器,这样我们就可以用相机渲染场景。

代码语言:javascript
复制
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

渲染场景

如果您将上面的代码复制到我们之前创建的 HTML 文件中,您将看不到任何内容。这是因为我们实际上还没有渲染任何东西。

代码语言:javascript
复制
function animate() {
    requestAnimationFrame(animate);
    controls.update();
    renderer.render(scene, camera);
}
animate();

添加轨道

代码语言:javascript
复制
var controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.minPolarAngle = Math.PI / 2 - 0.6;
controls.maxPolarAngle = Math.PI / 2 + 0.1;
controls.target.y = 2;

添加照片

代码语言:javascript
复制
function addBox(imageUrl) {
    const texture = textureLoader.load(imageUrl);
    const geometry = new THREE.BoxGeometry(5, 5, 0.2);
    const material = new THREE.MeshLambertMaterial({ color: 0xffffff, map: texture });
    const cube = new THREE.Mesh(geometry, material);
    //cube.position.y = 2.5;
    cube.position.setFromCylindricalCoords(random(15, 25), random(-Math.PI * 2, Math.PI * 2), 2.5);
    cube.lookAt(0, 2, 0);
    scene.add(cube);

    const lookAtPosition = new THREE.Vector3(0, 2, 0);
    lookAtPosition.lerp(cube.position, 0.3);
    controls.target.copy(lookAtPosition);
}

代码

index.html

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Three js</title>
    <style>
        html,
        body {
            height: 100%;
            overflow: hidden;
            margin: 0;
        }

        input {
            position: fixed;
            top: 90vh;
            left: 50vw;
            transform: translate(-50%, -50%);
            background: transparent;
            border: 1px solid #fff;
            padding: 10px 20px;
            font-size: 24px;
            color: #fff;
            opacity: 0.2;
            outline: none;
            transition: 0.5s;
            border-radius: 5px;
        }

        input:focus {
            opacity: 1;
        }
    </style>
</head>

<body>
    <input type="text" id="caption" placeholder="Type a caption">
    <script src="third_party/three.min.js"></script>
    <script src="third_party/OrbitControls.js"></script>
    <script src="js/index.js"></script>

</body>

</html>

index.js

代码语言:javascript
复制
function random(min, max) {
    return min + Math.random() * (max - min);
}

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

const renderer = new THREE.WebGLRenderer({
    antialias: true,
    powerPreference: 'high-performance'
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.outputEncoding = THREE.sRGBEncoding;
document.body.appendChild(renderer.domElement);

var controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.minPolarAngle = Math.PI / 2 - 0.6;
controls.maxPolarAngle = Math.PI / 2 + 0.1;
controls.target.y = 2;

const ambientLight = new THREE.AmbientLight(0x202020);
scene.add(ambientLight);

const hemiLight = new THREE.HemisphereLight(0xffffbb, 0x080820, 1);
hemiLight.color.setHSL(0.6, 1, 0.1);
hemiLight.groundColor.setHSL(0.1, 0.2, 0.1);
scene.add(hemiLight);

const gridHelper = new THREE.GridHelper(100, 20);
scene.add(gridHelper);

const pointLight = new THREE.PointLight(0xffffff, 1, 100);
pointLight.position.set(0, 10, 5);
scene.add(pointLight);

const groundGeo = new THREE.PlaneBufferGeometry(105, 105);
const groundMat = new THREE.MeshLambertMaterial({ side: THREE.DoubleSide });
groundMat.color.setHSL(0.095, 1, 0.75);
const ground = new THREE.Mesh(groundGeo, groundMat);
ground.rotation.x = -Math.PI / 2;
scene.add(ground);

const textureLoader = new THREE.TextureLoader();

function addBox(imageUrl) {
    const texture = textureLoader.load(imageUrl);
    const geometry = new THREE.BoxGeometry(5, 5, 0.2);
    const material = new THREE.MeshLambertMaterial({ color: 0xffffff, map: texture });
    const cube = new THREE.Mesh(geometry, material);
    //cube.position.y = 2.5;
    cube.position.setFromCylindricalCoords(random(15, 25), random(-Math.PI * 2, Math.PI * 2), 2.5);
    cube.lookAt(0, 2, 0);
    scene.add(cube);

    const lookAtPosition = new THREE.Vector3(0, 2, 0);
    lookAtPosition.lerp(cube.position, 0.3);
    controls.target.copy(lookAtPosition);
}

for (let i = 0; i < 10; i++) {
    addBox('img/641.jpg')
}

camera.position.z = 5;

function generateImage(caption) {
    const inputs = {
        "caption": caption
    };

    fetch('http://localhost:8001/query', {
        method: 'POST',
        headers: {
            Accept: 'application/json',
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(inputs)
    })
        .then(response => response.json())
        .then(outputs => {
            const { result } = outputs;
            console.log(result);
            addBox(result);
        })
}

function animate() {
    requestAnimationFrame(animate);
    controls.update();
    renderer.render(scene, camera);
}
animate();

document.getElementById('caption').addEventListener('keydown', (e) => {
    if (e.key === 'Enter') {
        const caption = e.currentTarget.value;
        generateImage(caption);
        e.currentTarget.value = '';
    }
})

generateImage('a boat');

引用

https://threejs.org/

https://github.com/mrdoob/three.js

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 效果图
  • 解析
    • 安装
      • 插件
    • 创建场景
      • 渲染场景
        • 添加轨道
          • 添加照片
          • 代码
            • index.html
              • index.js
              • 引用
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档