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 изменилось.
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.