Мало знаний, большой вызов! Эта статья участвует в "Необходимые знания для программистов«Творческая деятельность.
задний план
недавно узналWebGL
а такжеThree.js
Некоторые базовые знания, поэтому я хочу объединить популярный в последнее время стиль кислотного дизайна, украсить личную домашнюю страницу и обобщить некоторые полученные знания. Содержание этой статьи в основном представлено с помощьюReact + three.js
стек технологий, загружен3D模型
,Добавить к3D文字
, добавить анимацию, взаимодействие с кликом и т. д., используя дизайн стиля, чтобы добиться ощущения дизайна.🤢
Страница в кислотном стиле.
Базовые знания
Three.js
Three.js
является уроженцемWebGL
Инкапсулирует запуск в браузере3D引擎
, вы можете использовать его для создания различных 3D-сцен, включая камеры, источники света, материалы и другие объекты. Это очень широко используемый 3D-движок. допустимыйОфициальная китайская документация three.jsУзнать больше.
Кислотный дизайн
酸性设计
слово, переведенное сAcid Graphics
, начинается в上世纪90年代
эйсид-хаус, электронная танцевальная музыка и культура хиппи. В области дизайна эта кислотная эстетика имеет большое значение.自由的主张
, гротескная графика, смелые и яркие цветовые схемы, особые фактуры материалов и разнообразие шрифтов формируют уникальный кислотный стиль дизайна.
Вкратце,鲜艳高饱和度
сочетание цветов; темно-серая основа с высокой насыщенностью荧光色
украшение экрана五彩斑斓的黑
;Полный футуристический, крутой, полный технологического смысла液态金属
,玻璃
,铝箔塑料
и другие материалы;随机
элементы, макет графики;重复
, резать, комбинировать几何图形
и т. д. — это все кислотные стили дизайна. Кислотные стили также набирают популярность в обложках музыкальных альбомов, визуальных плакатах, обложках книг и фильмов, а также в веб-дизайне.
добиться эффекта
онлайн просмотр:tricell.fun
выполнить
3D модель
инициализация сцены
🌏
Создать сцену
scene = new THREE.Scene();
📷
Инициализировать камеру
透视相机 PerspectiveCamera
из4个
Параметры относятся к: полю зрения, соотношению сторон, ближней плоскости, дальней плоскости.
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 1000);
// 设置相机位置
camera.position.set(600, 20, -200);
// 相机聚焦到屏幕中央
camera.lookAt(new THREE.Vector3(0, 0, 0));
💡
Инициализировать источник света
Добавить к半球光源 HemisphereLight
: Создает более естественный источник света для наружных эффектов.
light = new THREE.HemisphereLight(0xffffff, 0x444444);
light.position.set(0, 20, 0);
scene.add(light);
light = new THREE.DirectionalLight(0xffffff);
light.position.set(0, 20, 10);
light.castShadow = true;
scene.add(light);
Добавить к环境光 AmbientLight
:
var ambiColor = '#0C0C0C';
var ambientLight = new THREE.AmbientLight(ambiColor);
scene.add(ambientLight);
Добавьте вспомогательные инструменты (необязательно)
📦
Добавить вспомогательную сетку
GridHelper
Может использоваться для добавления направляющих сетки, а также может использоваться для украшения черезGridHelper(size, divisions, colorCenterLine, colorGrid)
выполнить.
-
size
: ширина сетки, по умолчанию10
. -
divisions
: равная дробь, значение по умолчанию10
. -
colorCenterLine
: цвет центральной линии, по умолчанию0x444444
. -
colorGrid
: цвет линии сетки, по умолчанию0x888888
.
var grid = new THREE.GridHelper(1000, 100, 0x000000, 0x000000);
grid.material.opacity = 0.1;
grid.material.transparent = true;
grid.position.set(0, -240, 0);
scene.add(grid);
📦
Добавьте элементы управления камерой
Через управление камеройOrbitControls
Трехмерную сцену можно масштабировать, перемещать и вращать, причем существенно меняется не сама сцена, а параметры камеры. при разработкеOrbitControls.js
необходимо импортировать отдельно.
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.target.set(0, 0, 0);
controls.update();
📦
Добавить плагин просмотра производительности
stats
ЯвляетсяThree.js
Разработка вспомогательной библиотеки в основном используется для определения количества кадров при работе.stats.js
Его также необходимо импортировать отдельно.
stats = new Stats();
container.appendChild(stats.dom);
модель нагрузки
используется в этом примере扔铁饼的人
статуя3D
Модель происходит отthreedscans.com
,Могу免费😄
Скачивайте и пользуйтесь, в конце этой статьи приведено несколько бесплатных сайтов для скачивания моделей, в том числе200多页
Бесплатная модель, если вы заинтересованы, вы можете выбрать понравившуюся модель для загрузки и использования. Конечно, учащиеся со способностями к моделированию также могут использоватьblender
,3dmax
и другое профессиональное программное обеспечение для моделирования для создания ваших любимых моделей.
нагрузкаobj
илиfbx
Модель
необходимо представить отдельноFBXLoader.js
илиOBJLoader.js
,.fbx
а также.obj
Метод загрузки модели для формата такой же.
// var loader = new THREE.FBXLoader();
var loader = new THREE.OBJLoader();
loader.load(model, function (object) {
object.traverse(function (child) {
if (child.isMesh) {
child.castShadow = true;
child.receiveShadow = true;
}
});
object.rotation.y = Math.PI / 2;
object.position.set(0, -200, 0);
object.scale.set(0.32, 0.32, 0.32);
model = object;
scene.add(object);
});
нагрузкаgltf
Модель
необходимо представить отдельноGLTFLoader.js
,нагрузка.gltf
Метод форматной модели немного отличается, следует отметить, что объект обхода модели и финальное дополнение к сценеobject.scene
вместоobject
.
var loader = new THREE.GLTFLoader();
loader.load(model, function (object) {
object.scene.traverse(function (child) {
if (child.isMesh) {
child.castShadow = true;
child.receiveShadow = true;
}
});
object.scene.rotation.y = Math.PI / 2;
object.scene.position.set(0, -240, 0);
object.scene.scale.set(0.33, 0.33, 0.33);
model = object.scene;
scene.add(object.scene);
});
Эффект после добавления сетки и загрузки модели показан на рисунке ниже.
Добавить анимацию поворотного стола
пройти черезrequestAnimationFrame
Метод обновления страницы добавляет эффект анимации поворотного стола.window.requestAnimationFrame()
Сообщите браузеру, что вы хотите выполнить анимацию, и попросите браузер вызвать указанную функцию обратного вызова, чтобы обновить анимацию перед следующей перерисовкой. Этот метод должен передать функцию обратного вызова в качестве параметра, функция обратного вызова будет выполнена до следующей перерисовки браузера.
function animate () {
requestAnimationFrame(animate);
// 随着页面重绘不断改变场景的rotation.y来实现旋转
scene.rotation.y -= 0.015;
renderer.render(scene, camera);
}
Добавить взаимодействие с кликом
существуетThree.js
В сцене мы хотим нажать на модель, чтобы получить информацию о ней, или выполнить какие-то другие операции, нам нужно использоватьRaycaster(光线投射)
, принцип заключается в том, чтобы испускать пучок лучей в том месте, где вы щелкаете мышью, и записываются объекты в лучах. Основной синтаксисRaycaster(origin, direction, near, far)
,в:
-
origin
: Вектор начальной точки луча. -
direction
: Вектор направления луча. -
near
: Все возвращаемые результаты должны быть меньшеnear
Далеко. Значение не может быть отрицательным, значение по умолчанию равно0
. -
far
: Все возвращаемые результаты должны быть меньшеfar
близко. не может быть меньшеnear
, значение по умолчанию无穷大
.
Основные шаги реализации кода: получить координаты мыши на экране→
Преобразование координат экрана в стандартные координаты устройства→
Преобразование стандартных координат устройства в мировые координаты→
Получить мировые координаты мыши в сцене→
Сгенерируйте единичный вектор направления raycast из мировых координат и камеры→
Создает объект raycaster из единичного вектора направления raycast.
//声明raycaster和mouse变量
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
onMouseClick = event => {
// 将鼠标点击位置的屏幕坐标转成threejs中的标准坐标,以屏幕中心为原点,值的范围为-1到1.
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
// 通过鼠标点的位置和当前相机的矩阵计算出raycaster
raycaster.setFromCamera(mouse, camera);
// 获取raycaster直线和所有模型相交的数组集合
let intersects = raycaster.intersectObjects(scene.children);
if (intersects.length > 0) {
alert('HELLO WORLD')
// 可以通过遍历实现点击不同mesh触发不同交互,如:
let selectedObj = intersects[0].object;
if (selectedObj.name === 'car') {
alert('汽车🚗')
}
}
}
window.addEventListener('click', onMouseClick, false);
Добавить 3D-текст
использоватьTextGeometry(text : String, parameters : Object)
Добавить к3D文字
, ниже приводится описание устанавливаемых свойств:
-
size
: размер шрифта, обычно высота заглавных букв. -
height
: Толщина текста. -
weight
: значениеnormal
илиbold
, указывая, следует ли выделять жирным шрифтом или нет. -
font
: шрифт, по умолчаниюhelvetiker
, который должен соответствовать указанному файлу шрифта. -
style
: значениеnormal
илиitalics
, указывая, выделено ли оно курсивом -
bevelThickness
: Толщина фаски. -
bevelSize
: Ширина фаски. -
curveSegments
: количество сегментов дуги, чтобы сделать изгиб текста более плавным. -
bevelEnabled
: логическое значение, используется ли фаска, что означает скос на краю.
var loader = new THREE.FontLoader();
loader.load('gentilis_regular.typeface.json', function (font) {
var textGeo = new THREE.TextGeometry('HELLO WORLD', {
font: font,
size: .8,
height: .8,
curveSegments: .05,
bevelThickness: .05,
bevelSize: .05,
bevelEnabled: true
});
var textMaterial = new THREE.MeshPhongMaterial({ color: 0x03c03c });
var mesh = new THREE.Mesh(textGeo, textMaterial);
mesh.position.set(0, 3.8, 0);
scene.add(mesh);
});
оптимизация
Теперь загрузка модели в основном завершена, но3D
Размер модели, как правило, относительно велик. После развертывания я обнаружил, что загрузка веб-страницы очень медленная, что влияет на взаимодействие с пользователем. Крайне необходимо уменьшить размер модели.3D建模软件
случае, использоватьobj2gltf
может быть большеOBJ
Модель формата преобразуется вgltf
Моделируйте, эффективно оптимизируйте объем модели и улучшите скорость загрузки веб-страниц.
Установить
npm install obj2gltf --save
Скопируйте модель obj в следующий каталог
node_modules\obj2gltf\bin
Выполнение инструкций по транскодированию
node obj2gltf.js -i demo.obj -o demo.gltf
Как показано на рисунке, аналогично предыдущему, перекодирование завершено, и сравнивается объем файла до и после преобразования.В этом примереkas.obj
Начальный размер файла9.7M
преобразованный файлkas.gltf
Только4.6M
, объем уменьшен вдвое, в это время на страницу загружается сконвертированная модель, при этом эффект изменения модели практически незаметен невооруженным глазом, а скорость загрузки страницы значительно повышается.
obj2gltf
Также доступен в виде библиотеки черезnode服务
Модель преобразования в реальном времени, заинтересованные студенты могут узнать больше по ссылке в конце статьи. также можно использовать3D
программное обеспечение для моделирования, такое какblender
и т.д. вручную путем уменьшения модели面数
а также缩小体积
Сжатие и оптимизация модели осуществляются другими способами, и эффект оптимизации более очевиден.
полный код
var model = require('@/assets/models/kas.gltf');
var container, stats, controls;
var camera, scene, renderer, light, model;
class Kas extends React.Component {
render () {
return (
<div id="kas"></div>
)
}
componentDidMount () {
this.initThree();
}
initThree () {
init();
animate();
function init () {
container = document.getElementById('kas');
scene = new THREE.Scene();
scene.fog = new THREE.Fog(0xa0a0a0, 200, 1000);
// 透视相机:视场、长宽比、近面、远面
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(600, 20, -200);
camera.lookAt(new THREE.Vector3(0, 0, 0));
// 半球光源:创建室外效果更加自然的光源
light = new THREE.HemisphereLight(0xffffff, 0x444444);
light.position.set(0, 20, 0);
scene.add(light);
light = new THREE.DirectionalLight(0xffffff);
light.position.set(0, 20, 10);
light.castShadow = true;
scene.add(light);
// 环境光
var ambiColor = '#0C0C0C';
var ambientLight = new THREE.AmbientLight(ambiColor);
scene.add(ambientLight);
// 网格
var grid = new THREE.GridHelper(1000, 100, 0x000000, 0x000000);
grid.material.opacity = 0.1;
grid.material.transparent = true;
grid.position.set(0, -240, 0);
scene.add(grid);
// 加载gltf模型
var loader = new THREE.GLTFLoader();
loader.load(model, function (object) {
object.scene.traverse(function (child) {
if (child.isMesh) {
child.castShadow = true;
child.receiveShadow = true;
}
});
object.scene.rotation.y = Math.PI / 2;
object.scene.position.set(0, -240, 0);
object.scene.scale.set(0.33, 0.33, 0.33);
model = object.scene;
scene.add(object.scene);
});
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearAlpha(0);
renderer.shadowMap.enabled = true;
container.appendChild(renderer.domElement);
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}, false);
stats = new Stats();
container.appendChild(stats.dom);
}
function animate () {
var clock = new THREE.Clock()
requestAnimationFrame(animate);
var delta = clock.getDelta();
scene.rotation.y -= 0.015;
renderer.render(scene, camera);
stats.update();
}
// 增加点击事件
//声明raycaster和mouse变量
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
function onMouseClick(event) {
// 通过鼠标点击位置计算出raycaster所需要点的位置,以屏幕中心为原点,值的范围为-1到1.
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
// 通过鼠标点的位置和当前相机的矩阵计算出raycaster
raycaster.setFromCamera(mouse, camera);
// 获取raycaster直线和所有模型相交的数组集合
var intersects = raycaster.intersectObjects(scene.children);
if (intersects.length > 0) {
alert('HELLO WORLD')
}
}
window.addEventListener('click', onMouseClick, false);
}
}
другие элементы дизайна
Эта статья в основном знакомит3D元素
загрузка, в связи с ограниченностью места и времени статьи (博主太懒😂
) Реализация остальных элементов подробно объясняться не буду (может будет время подытожить позжеmaybe
) Заинтересованные студенты могут прочитать следующие превосходные статьи других великих богов.
жидкий фон
静态
Жидкие фоновые изображения могут бытьSVG filter
реализовано, можно читать«Создание шаблонов с фильтрами SVG»,выполнить动态
Жидкий фон можно реализовать с помощью Three.js в сочетании с собственным GLSL, см.《Шадер шейдера CodePen》пример для реализации.
Шрифты с кислотным эффектом, такие как металлик, неон, эффект глюка, можно прочитать в другой моей статье.«Визуальные эффекты в стиле Cyberpunk 2077 всего за несколько шагов CSS», вы также можете использовать создание дизайна. Из-за нехватки времени текст с металлическим эффектом в этом проекте и текст на изображении заголовка баннера этой статьи используютсяОнлайн-сайт для создания художественных шрифтовОн создается, и заинтересованные студенты могут попытаться разработать его самостоятельно.
Дальнейшая оптимизация в будущем
-
#todo
Реализация жидкого фона в кислотном стиле. -
#todo
3D模型
Эффект жидкого металла.
three.js
Отличная рекомендация кейса
Наконец, я рекомендую несколько очень удивительныхthree.js
Приходите, чтобы испытать и извлечь уроки из проекта, будь то взаимодействие со страницей, визуальный дизайн или оптимизация производительности, мы достигли максимума и можем многому у него научиться.
-
домашняя страница гитхаба:
3D地球
Отображение в режиме реального времени популярных складов по всему миру. -
kodeclubs: мало лиц
3D城市
Мини-игры от третьего лица. -
Дисплей кроссовок:
720度
Динамическое отображение кроссовок. - танец скульптуры из песка: Танцовщица из песка.
-
Зенли Программное обеспечение:
Zenly App
Китайская домашняя страница.
использованная литература
- three.js: threejs.org
- obj2gltf: GitHub.com/цезий GS/OB…
- Более 200 страниц бесплатных 3D-моделейwww.turbosquid.com
- Бесплатные 3D-статуи:threedscans.com
- Бесплатные 3D модели:free3d.com
- Онлайн генерация художественных шрифтов:cooltext.com
- Что такое кислотный дизайн:www.shejipi.com/361258.html