В этом уроке мы рассмотрим, как смещать точки в геометрии точек Three.js, когда мышь находится на определенном расстоянии от них. Затем мы будем анимировать эти точки обратно в их исходное положение, когда мышь выходит за пределы диапазона.

Шаг 1: Настройка сцены Three.js
— -
Давайте начнем с настройки базовой сцены с геометрией точек.

`
позволить сцене, камере, рендереру, частицам;

function init() {
// Создаем сцену и устанавливаем ее размер.
scene = new THREE.Scene();
let WIDTH = window.innerWidth,
HEIGHT = окно.внутренняя высота;

// Создаем средство визуализации и добавляем его в DOM.
renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize(WIDTH, HEIGHT);
document.body .appendChild(renderer.domElement);

// Создадим камеру, немного удалим ее от модели и добавим в сцену.
camera = new THREE.PerspectiveCamera(45, WIDTH / HEIGHT, 0.1, 20000);
camera. position.set(0,6,0);
scene.add(camera);

// Создаем прослушиватель событий, который изменяет размер средства визуализации вместе с окном браузера.
window.addEventListener('resize', function() {
let WIDTH = window.innerWidth,
HEIGHT = window. innerHeight;
renderer.setSize(WIDTH, HEIGHT);
camera.aspect = WIDTH / HEIGHT;
camera.updateProjectionMatrix();
});

// Установить цвет фона сцены.
renderer.setClearColor(0x333F47, 1);

let геометрия = new THREE.Geometry();

for (let i = 0; i ‹ 2000; i++) {
let vertex = new THREE.Vector3();
вершина.x = THREE.Math.randFloatSpread(2000); // случайный разброс от -1000 до 1000
vertex.y = THREE.Math.randFloatSpread(2000); // случайный разброс от -1000 до 1000
vertex.z = THREE.Math.randFloatSpread(2000); // случайный разброс от -1000 до 1000
Geometry.vertices.push(vertex);
}

let material = new THREE.PointsMaterial({color: 0x888888});
частицы = новые ТРИ.Точки(геометрия, материал);

scene.add(частицы);
}

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

init();
анимировать();
`

Шаг 2: Добавление события перемещения мыши
— -
Далее нам нужно добавить событие перемещения мыши, чтобы зафиксировать положение мыши в нормализованных координатах устройства (от -1 до +1).

`
let mouse = new THREE.Vector2();

window.addEventListener('mousemove', (event) =› {
// конвертируем в нормализованные координаты устройства
mouse.x = (event.clientX / window.innerWidth) * 2–1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}, false);
```

Извиняюсь за путаницу ранее. Похоже, в последовательности была ошибка. Вот исправленная версия:

Шаг 3: Добавьте Raycaster
— -
Чтобы определить, к каким точкам в системе частиц приближается мышь, нам нужно использовать Raycaster. «Raycaster» — это объект THREE.js, который проецирует луч на сцену, который мы можем использовать для поиска пересечений с другими объектами.

Давайте добавим Raycaster и Vector2, чтобы отслеживать положение мыши:

```javascript
let raycaster = new THREE.Raycaster();
let mouse = new THREE.Vector2();
```

Затем давайте добавим прослушиватель событий для обновления положения мыши при ее перемещении:

```javascript
function onMouseMove(event) {
// вычисляем позицию мыши в нормированных координатах устройства
// (от -1 до +1) для обоих компонентов
mouse.x = (event.clientX / window.innerWidth) * 2–1;
mouse.y = — (event.clientY / window.innerHeight) * 2 + 1;
}

window.addEventListener('mousemove', onMouseMove, false);
```

Теперь в функции анимации мы можем использовать raycaster, чтобы узнать, к каким точкам приближается мышь:

```javascript
function animate() {
requestAnimationFrame(animate);

// обновить луч выбора с помощью камеры и положения мыши
raycaster.setFromCamera(mouse, camera);

// вычисляем объекты, пересекающие луч выбора
let intersects = raycaster.intersectObjects([particles]);

// смещаем пересекающиеся объекты
for (let i = 0; i ‹ intersects.length; i++) {
let point = intersects[i].object.geometry.vertices[intersects[i].index ];
point.x += (Math.random() — 0,5) * 0,1;
point.y += (Math.random() — 0,5) * 0,1;
балл. z += (Math.random() — 0,5) * 0,1;
}

частицы.геометрия.вертикалиNeedUpdate = true;

renderer.render(сцена, камера);
}

анимировать();
```

В функции анимации мы обновляем рейкастер до текущей позиции мыши и находим все точки, которые пересекаются с лучом. Для всех точек, которые пересекаются, мы немного смещаем их. Флаг `verticesNeedUpdate` должен быть установлен в `true`, чтобы сообщить THREE.js, что вершины геометрии частиц изменились и должны быть повторно визуализированы.

Шаг 4: Анимация точек обратно в исходное положение
— -
Чтобы вернуть точки в исходное положение, когда указатель мыши находится вне досягаемости, нам нужно отслеживать исходное положение точек.

Давайте создадим карту для отслеживания исходных позиций:

`
let originalPositions = new Map();
```

Теперь, когда мы инициализируем частицы, давайте сохраним исходные позиции:

```javascript
for (let i = 0; i ‹ 2000; i++) {
let vertex = new THREE.Vector3();
vertex.x = THREE.Math.randFloatSpread( 2000 г.); // случайный разброс от -1000 до 1000
vertex.y = THREE.Math.randFloatSpread(2000); // случайный разброс от -1000 до 1000
vertex.z = THREE.Math.randFloatSpread(2000); // случайный разброс от -1000 до 1000
Geometry.vertices.push(vertex);
originalPositions.set(vertex, vertex.clone());
}
`

Теперь в функции анимации мы перемещаем точки, когда мышь находится в пределах досягаемости, и анимируем их обратно в исходное положение, когда мышь удаляется:

`
function animate() {
requestAnimationFrame(animate);

// обновить луч выбора с помощью камеры и положения мыши
raycaster.setFromCamera(mouse, camera);

// вычисляем объекты, пересекающие луч выбора
let intersects = raycaster.intersectObjects([particles]);

if (intersects.length › 0) {
пусть ближайший = пересекается[0];

// Если точка находится в пределах 100 единиц, смещаем ее
if (closest.distance ‹ 100) {
let point = ближайшая.объект.геометрия.вершины[closest.index];
точка .x += (Math.random() — 0,5) * 0,1;
point.y += (Math.random() — 0,5) * 0,1;
point.z += (Math.random () — 0,5) * 0,1;
}
}

// Анимация всех точек обратно в исходное положение
for (let vertex частиц.geometry.vertices) {
let original = originalPositions.get(vertex);
if (vertex.distanceTo( оригинал) › 0,01) {
vertex.lerp(оригинал, 0,05);
}
}

частицы.геометрия.вертикалиNeedUpdate = true;

renderer.render(сцена, камера);
}

init();
анимировать();
`

В приведенном выше коде мы используем функцию «lerp» (линейная интерполяция), чтобы вернуть точки в исходное положение. Это создаст плавную анимацию точек, возвращающихся на свое место при удалении мыши.

Вот и все! Теперь у вас должно быть поле 3D-частиц, которое реагирует на положение вашей мыши.