предисловие
Предыдущий Xiaobao реализовал классный эффект использования частиц для формирования «Пакета поля битвы», который открыл дверь в мир частиц для Xiaobao. Мир частиц действительно классный. Простая комбинация и преобразование могут создавать суперкрасочные эффекты. Сегодня Xiaobao будет показать вам, как реализовать частицы Эффект всасывания и отталкивания, вы можете попробовать, супер декомпрессия и счастье.
Адрес опыта:Гравитация и отталкивание частиц
частица реализации
Во-первых, для достижения полноэкранного случайного распределения частиц в этой статье генерируется в общей сложности2500частица, положение(x,y)Генерируется случайными числами, форма частицы передается черезfillRectрисовать.
// 创建粒子类
class Particle {
constructor() {
// rand 是封装的生成 (n,m) 之间随机数的函数
// x, y 粒子位置
this.x = rand(0, canvas.width);
this.y = rand(0, canvas.height);
// vx, vy 粒子在x, y 轴的移动速度
this.vx = rand(-1, 1);
this.vy = rand(-1, 1);
// 粒子大小
this.r = rand(1, 3);
// 粒子颜色
this.col = `rgba(${Math.round(rand(150, 200))}, ${Math.round(
rand(100, 255)
)}, ${Math.round(rand(180, 255))},${Math.random() + 0.2})`;
}
}
// 生成粒子
function initParticle() {
for (var i = 0; i < part_num; i++) {
P.push(new Particle());
}
}
После того, как частицы, заполняющие экран, сгенерированы, давайте займемся эффектами частиц.
гравитационный эффект
Для достижения эффекта всемирного тяготения сначала нужен центр тяжести, начальное положение — центральное положение, а когда мышь начинает двигаться, положение мыши — центр тяжести. Чтобы сделать это более очевидным, передайтеcanvasНарисуйте крест в центре тяжести.
// X, Y 为引力中心位置
// X, Y 初始化
X = window.innerWidth / 2;
Y = window.innerHeight / 2;
// 绘制十字架
ctx.beginPath();
ctx.moveTo(X, Y - 10);
ctx.lineTo(X, Y + 10);
ctx.moveTo(X - 10, Y);
ctx.lineTo(X + 10, Y);
ctx.stroke();
// 移动鼠标时,修改引力中心位置
window.onmousemove = function (e) {
X = e.clientX;
Y = e.clientY;
};
После определения центра тяжести уточняется, что частица движется в направлении, радиально приближающемся к центру тяжести, и чем он ближе, тем больше скорость. При инициализации частиц укажитеvx,vyсвойства частиц вдольx,yСкорость, с которой движется ось, и поэтому может быть измененаvx,vyСвойство заставляет частицы постоянно закрывают гравитационный центр.
Прежде чем реализовать вышеупомянутые эффекты, давайте рассмотрим какие знания тригонометрические функции:
Из приведенного выше рисунка видно, чтоr*cos, r*sinдляrСоответственноx,yпроекция на ось, еслиrзаменена очень маленькой длиной,r*cos, r*sinТо есть частица в единицу времениx,yРасстояние, которое необходимо переместить по оси, то есть скоростьvx,vy. Итак, нам нужно найти угол частицы к центру тяжести.angle.
var dx = p.x - X, // 水平距离
dy = p.y - Y, // 垂直距离
dist = Math.sqrt(dx * dx + dy * dy), // 到引力中心的距离
angle = Math.atan2(dy, dx); // 角度
Система координат в интерфейсе немного отличается от системы координат в математике,xПоложительное направление оси такое же, ноyПоложительное направление оси направлено вниз, а косинус и синус каждого квадранта следующие:
Следующим шагом после рассмотрения вышеизложенных знаний является вычисление того, как движутся частицы. (Чем ближе частица к центру тяжести, тем быстрее она движется)
Возьмем три частицы в системе координат, потренируемся:
| частица |
cos/sin
|
dx/dy
|
len*cos/len*sin
|
|---|---|---|---|
| A | позитивный негативный | позитивный негативный | позитивный негативный |
| C | отрицательный/отрицательный | отрицательный/отрицательный | отрицательный/отрицательный |
| D | положительный / положительный | положительный / положительный | положительный / положительный |
dxа такжеdy- длина частицы от центра тяжести вx,yВ проекции на ось есть положительные и отрицательные значения, например точка А,dxA > 0, dyA < 0, так что если частица A хочет быть близко к центру тяжести B , ей нужно установитьvx < 0, vy > 0, чтобы уменьшить расстояние между A и B.
Из таблицы мы видим, чтоlen*cosа такжеlen*sinточно сdxа такжеdyтот же знак, поэтому установите-len*cosа также-len*sin- скорость движения частицы частицы, которая может заставить частицу A продолжать приближаться к гравитационному центру B (lenна любую длину)
// 粒子越靠近引力中心,dist越小,一方面可以保证粒子速度越来越快,另一方面也达成len不断修改的要求
p.vx -= (20 / (p.r * dist)) * Math.cos(angle);
p.vy -= (20 / (p.r * dist)) * Math.sin(angle);
p.x += p.vx;
p.y += p.vy;
Эффект отталкивания
Если свет имеет гравитационный эффект, большая часть частиц будет притягиваться к середине после игры в течение некоторого времени, а окружающая область будет казаться пустой, и после долгой игры она будет несколько монотонной. Тогда давайте добавим эффект отталкивания, есть всасывание, есть отталкивание и эффект живой.
Эффект эффекта отталкиванияЩелкните мышью, частицы будут распространяться по кругу, чтобы обеспечить эффективность диффузии, установите большой радиус диффузии..
При реализации основы гравитации частице нужно только обеспечить, чтобы окружающиеlen*cosа такжеlen*sinточно сdxа такжеdyОдин и тот же номер может быть.
p.vx += (250 / (p.r * dist)) * Math.cos(angle);
p.vy += (250 / (p.r * dist)) * Math.sin(angle);
Эффект отталкивания частиц не очень распаковывается, но можно найти относительно очевидную проблему.Многие частицы отталкиваются от страницы, а частиц на странице становится все меньше и меньше.Это не весело, поэтому добавляйте логику для обработки границ .
Граничная обработка
Логику обработки границы реализовать несложно: когда частица достигает границы, например, достигает верхней границы в вертикальном направлении, это означает, что частицаvyЕсли это отрицательное значение, измените его на противоположный знак, тогда частица сможет отскакивать назад, а остальные направления обрабатываются аналогично.
function bounce(b) {
// 左边界
if (b.x < b.r) {
b.x = b.r;
b.vx *= -1;
}
// 右边界
if (b.x > canvas.width - b.r) {
b.x = canvas.width - b.r;
b.vx *= -1;
}
// 上边界
if (b.y - b.r < 0) {
b.y = b.r;
b.vy *= -1;
}
// 下边界
if (b.y > canvas.height - b.r) {
b.y = canvas.height - b.r;
b.vy *= -1;
}
}
Репозиторий исходного кода
Адрес источника:Гравитация и отталкивание частиц
Адрес опыта:Гравитация и отталкивание частиц
Не забудьте поставить пакету ⭐, если вы считаете его полезным.
Замечательные статьи в прошлом
- Последний письменный тест Nioke по интерфейсу JS, 100 вопросов
- Резюме последних предварительных вопросов интервью Ниуке (включая анализ)
- CSS реализует свободно летящую птицу 🐦
- Получите последние предварительные вопросы интервью Niuke и 500 горячих точек интервью JS для анализа данных.
- Примите кошку для VSCode и веб-сайта
- Душевная пытка родного JavaScript (1), сколько вы можете ответить?
- Глубокое понимание прототипа и цепочки прототипов в JavaScript
- Глубокое понимание EventLoop в JavaScript
- «2w Word Big Chapter 38 Interview Questions» подробно разъясняет эту проблему указания в JS.
послесловие
Друзья, если вы чувствуете, что эта статья вам полезна, ставьте лайк Абао👍 или подписывайтесь➕ — это самая большая поддержка для меня.
Кроме того, если есть какие-либо проблемы с этой статьей или если вы не понимаете часть статьи, вы можете ответить мне в области комментариев, давайте обсудим, изучим и добьемся успеха вместе!