Three.js реализует вращение восьми планет Солнечной системы.

three.js
Three.js реализует вращение восьми планет Солнечной системы.

1. Введение в фреймворк Three.js

Three.js — это сторонняя библиотека WebGL, написанная на javascript.Использование фреймворка three.js для написания 3D-программ похоже на наблюдение за 3D-сценой в реальной жизни, позволяющее людям чувствовать себя в ней. Представляя three.js, необходимо упомянуть три его компонента: сцена, камера, рендеринг. Они являются основой всего фреймворка.С помощью этих трех компонентов можно отображать объекты на веб-странице и создавать всю сцену.

место действия

Как следует из названия, он используется для размещения всех элементов.

var scene = new THREE.Scene();  //建立场景

камера

Камера, где мы хотим быть, как мы видим эти элементы. Есть много типов камер, и мы не будем их представлять.Здесь мы используемперспективная камера.

var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 10000); //设置相机为 角度60度,宽高比,最近端Z轴为1,最远端Z轴为10000

Мы можем понять эти свойства с помощью изображения из документации three.js.

визуализатор

Когда все в сцене готово, сцену можно отрендерить, указав, как мы будем рисовать эти элементы. Рендереры также делятся на различные типы, здесь используютсяWebGLRenderer;

var renderer = new THREE.WebGLRenderer();

Конкретные шаги: создать элемент -> определить камеру -> создать сцену -> поместить элемент и камеру в сцену -> визуализировать сцену. Мы представим конкретный код позже, а затем давайте взглянем на визуализацию.

2. Базовая инициализация

Здесь мы напрямую вводим three.js в CDN<script src="https://cdn.bootcss.com/three.js/r83/three.min.js"></script>

Примечание. Были внесены некоторые корректировки дисбаланса, поскольку размер, скорость вращения и расстояние до некоторых планет слишком велики.Далее будет проанализировано, как вставляются эти элементы.

1.canvas

Вместо того, чтобы монтировать сцену прямо в тело, мы помещаем холст в тело и отображаем его на нем.

2. Фон

Мы не делали трехмерный вращающийся фон, а сразу помещали фоновое изображение в качестве фона маленькой Солнечной системы. Это фоновое изображение размещается непосредственно на холсте.

<canvas id="webglcanvas"></canvas>
renderer = new THREE.WebGLRenderer({    //定义渲染器
            alpha: true,    //让背景透明,默认是黑色,以显示我们自己的背景图
        });
renderer.setClearAlpha(0);
//css文件
#webglcanvas {
            background: url(./images/bg4.jpg) no-repeat;
            background-size: cover;
        }

Но если просто эта простая операция бесполезна, потому что после добавления рендерера он по умолчанию добавит черный цвет фона. Итак, чтобы установить свойство альфа в рендерере(средство визуализации WebGL и методы свойств), сделайте фон прозрачным, чтобы показать наше собственное фоновое изображение

3. Определите основные компоненты

Определить сцену

scene = new THREE.Scene(), //建立场景

Определите положение камеры

camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1,10000); //设置相机为 角度60度,宽高比,最近端Z轴为1,最远端Z轴为10000
        camera.position.z = 2000;   //调整相机位置
        camera.position.y = 500;

создать группу

Группу можно рассматривать как контейнер для некоторых элементов, помещая некоторые элементы с общими характеристиками в группу.

group = new THREE.Group(), //建立一个组

Я объясню, почему создаются дополнительные 16 групп, в разделе 3.

 //下面这些组用来建立每个星球的父元素,以实现 八大行星不同速度的公转与自转
        var group1 = new THREE.Group();
            groupParent1 = new THREE.Group();
            group2 = new THREE.Group();
            groupParent2 = new THREE.Group();
            group3 = new THREE.Group();
            groupParent3 = new THREE.Group();
            group4 = new THREE.Group();
            groupParent4 = new THREE.Group();
            group5 = new THREE.Group();
            groupParent5 = new THREE.Group();
            group6 = new THREE.Group();
            groupParent6 = new THREE.Group();
            group7 = new THREE.Group();
            groupParent7 = new THREE.Group();
            group8 = new THREE.Group();
            groupParent8 = new THREE.Group();

определить визуализатор

В WebGLRenderer есть объект холста для рисования, теперь получите заданный холст и поместите его в объект холста в нашем рендерере.

var canvas = document.getElementById('webglcanvas'),
renderer = new THREE.WebGLRenderer({    //定义渲染器
            alpha: true,    //让背景透明,默认是黑色  以显示我们自己的背景图
            canvas: canvas, //一个用来绘制输出的Canvas对象
            antialias: true //抗锯齿
        });
renderer.setSize(window.innerWidth, window.innerHeight);    //设置渲染器的宽高

4. Функция инициализации

В этой функции выполняется ряд операций инициализации.

function init() {       //用来初始化的函数
            scene.add(group);   //把组都添加到场景里

            scene.add(groupParent1);
            scene.add(groupParent2);
            scene.add(groupParent3);
            scene.add(groupParent4);
            scene.add(groupParent5);
            scene.add(groupParent6);
            scene.add(groupParent7);
            scene.add(groupParent8);
            
            var loader = new THREE.TextureLoader();/*材质  纹理加载器*/
            // 太阳
            loader.load('./images/sun1.jpg', function (texture) {     
                var geometry = new THREE.SphereGeometry(250, 20, 20)  //球体模型   
                var material = new THREE.MeshBasicMaterial({ map: texture })  //材质  将图片解构成THREE能理解的材质
                var mesh = new THREE.Mesh(geometry, material);        //网孔对象    第一个参数是几何模型(结构),第二参数是材料(外观)
                group.add(mesh);//添加到组里
            })
            // 水星
            loader.load('./images/water.jpg', function (texture) {
                var geometry = new THREE.SphereGeometry(25, 20, 20)  //球型   
                var material = new THREE.MeshBasicMaterial({ map: texture })  //材质  将图片解构成THREE能理解的材质
                var mesh = new THREE.Mesh(geometry, material);
                group1.position.x -= 300;
                group1.add(mesh);
                groupParent1.add(group1);
            })
            //其它7颗行星参数因为太长了在这里就不给出了,但参数的设置原理都是一样的
            }

Кратко объясните:

var loader = new THREE.TextureLoader() определяетЗагрузчик текстур материала.

var геометрия = новый THREE.SphereGeometry(250, 20, 20); создаетсферическая модель, радиус сферы равен 250, количество горизонтальных разделительных граней равно 20, а количество вертикальных разделительных граней равно 20.

var mesh = new THREE.Mesh(geometry, material);сетчатый объект.

Конкретная функция состоит в том, чтобы создать элемент сферы, сначала построить рамку, обернуть ее плоскостью планеты и сформировать планету, затем добавить планету в группу, а затем добавить группу в сцену. Вот процесс построения одного элемента.

Так почему же Солнце добавляется непосредственно в группу, а Меркурий добавляется в два групповых уровня со смещением относительно его положения. Подходим к третьей четверти.

3. Вращение и переворот одновременно

Вращение: Мы хотим реализовать функцию вращения тремя способами. 1. Вращение камеры 2. Вращение всей сцены (Scene) 3. Вращение отдельного элемента.

Потому что скорость вращения и скорость обращения каждой планеты здесь разные. Таким образом, установка общего поворота невозможна, поэтому задайте разные свойства поворота для каждого элемента.

механизм вращения: Это вводит свойство вращения объекта, который вращается относительно самого себя.

Например:scene.rotation.y += 0.04; //整个场景绕自身的Y轴逆时针旋转

В заголовок

Все элементы в сцене используют свойство rotate.y, осью вращения по умолчанию является эта ось Y, потому что они инициализируют ось Y этой осью. Так пусть вращается солнце и пусть его группа вращается прямоgroup.rotation.y += 0.04;

Другим планетам необходимо установить позиционное смещение, чтобы заставить их вращаться вокруг Солнца. Например Меркурий:group1.position.x -= 300;во время настройкиgroup1.rotation.yсобственности, он будет осуществлять вращение. Потому что его положение по оси Y изменилось.

Затем, если вы хотите снова реализовать вращение в это время, вы не можете найти линию оси Y по умолчанию в этом объекте. Поэтому мы устанавливаем другой «родительский элемент» groupParent1 в группу1.groupParent1.add(group1);

Когда мы перемещаем group1, положение groupParent1 не меняется, и, естественно, ее ось Y не меняется, а поскольку groupParent1 содержит group1, при повороте groupParent1 группа1 также будет вращаться вокруг исходной оси Y по умолчанию. Таким образом, создание стольких групп означает одновременное вращение каждой планеты с разными скоростями и оборотами.

4. Другие функции реализации

        function render() {
            renderer.render(scene, camera);
            camera.lookAt(scene.position);  //让相机盯着场景的位置 场景始终在中间
        }
        //设置公转
        function revolution(){
            groupParent1.rotation.y += 0.15;
            groupParent2.rotation.y += 0.065;
            groupParent3.rotation.y += 0.05;
            groupParent4.rotation.y += 0.03;
            groupParent5.rotation.y += 0.001; 
            groupParent6.rotation.y += 0.02;
            groupParent7.rotation.y += 0.0005;
            groupParent8.rotation.y += 0.003;
        }
        //设置自转
        function selfRotation(){
            group.rotation.y += 0.04;
            group1.rotation.y += 0.02;
            group2.rotation.y -= 0.005;
            group3.rotation.y += 1;
            group4.rotation.y += 1;
            group5.rotation.y += 1.5;
            group6.rotation.y += 1.5;
            group7.rotation.y -= 1.5;
            group8.rotation.y += 1.2;
        }
        function Animation() {
            render();
            selfRotation();
            revolution();
            requestAnimationFrame(Animation);   
        }

Наконец, снова вызовите функции init() и Animation(), и все будет в порядке.

Если вы считаете, что это интересно, просто нажмите 👍8.