react-webgl-fluid
v1.1.0
Published
A WebGL fluid simulation library for React.
Maintainers
Readme
React WebGL Fluid Simulation
Высокопроизводительная библиотека для создания интерактивных fluid-симуляций в React-приложениях с использованием WebGL.
Основано на проекте Pavel Dobryakov’s WebGL Fluid Simulation.
🚀 Установка
Высокопроизводительная библиотека для создания интерактивных fluid симуляций в React приложениях с использованием WebGL.
Установка
npm install react-webgl-fluidБыстрый старт
import React from 'react';
import { useFluidSimulation } from 'react-webgl-fluid';
function FluidCanvas() {
const { canvasRef } = useFluidSimulation({
BLOOM: true,
SUNRAYS: true,
COLORFUL: true,
});
return <canvas ref={canvasRef} style={{ width: '100%', height: '100vh' }} />;
}
export default FluidCanvas;API
useFluidSimulation
Основной React хук для создания fluid симуляции.
const {
canvasRef,
simulation,
splat,
randomSplats,
updateConfig,
start,
stop,
pause,
resume,
captureScreenshot,
} = useFluidSimulation(config, enableEventListeners);Параметры
config(optional): Объект конфигурации симуляцииenableEventListeners(optional, default:true): Включить автоматическую обработку событий мыши и касаний
Возвращаемые значения
canvasRef: React ref для canvas элементаsimulation: Экземпляр FluidSimulation для прямого управленияsplat: Функция для создания всплеска в определенной точкеrandomSplats: Функция для создания случайных всплесковupdateConfig: Функция для обновления конфигурацииstart/stop/pause/resume: Функции управления анимациейcaptureScreenshot: Функция для создания скриншота
Конфигурация
interface SimulationConfig {
// 🎯 ОСНОВНЫЕ НАСТРОЙКИ ДЛЯ ВИХРЕЙ, РАЗМЕРА И СКОРОСТИ
CURL?: number; // Размер вихрей (0-50, больше = больше вихрей)
SPLAT_RADIUS?: number; // Размер начальной точки (0.01-1.0)
DENSITY_DISSIPATION?: number; // Скорость исчезновения дыма (0-1, меньше = дольше)
VELOCITY_DISSIPATION?: number; // Скорость распространения (0-1, меньше = быстрее)
// Разрешение и качество
SIM_RESOLUTION?: number; // Разрешение симуляции (32-256)
DYE_RESOLUTION?: number; // Разрешение красителя (128-1024)
// Физика
PRESSURE?: number; // Давление жидкости (0-1)
PRESSURE_ITERATIONS?: number; // Точность расчетов (5-50)
SPLAT_FORCE?: number; // Сила всплеска (1000-10000)
// Визуальные эффекты
SHADING?: boolean; // Затенение
COLORFUL?: boolean; // Цветные всплески
COLOR_UPDATE_SPEED?: number; // Скорость смены цветов (1-20)
BLOOM?: boolean; // Эффект свечения
SUNRAYS?: boolean; // Эффект солнечных лучей
TRANSPARENT?: boolean; // Прозрачный фон
}🎛️ Ключевые параметры для настройки эффекта:
| Параметр | Что контролирует | Диапазон | Эффект |
| ---------------------- | ------------------------------ | ---------- | ------------------------- |
| CURL | Размер вихрей | 0-50 | Больше = крупнее вихри |
| SPLAT_RADIUS | Размер начальной точки | 0.01-1.0 | Больше = крупнее всплеск |
| DENSITY_DISSIPATION | Скорость исчезновения дыма | 0-1 | Меньше = дольше держится |
| VELOCITY_DISSIPATION | Скорость распространения | 0-1 | Меньше = быстрее движется |
| SPLAT_FORCE | Сила всплеска | 1000-10000 | Больше = сильнее толчок |
Примеры использования
Базовая симуляция
import { useFluidSimulation } from 'react-webgl-fluid';
function BasicFluid() {
const { canvasRef } = useFluidSimulation();
return <canvas ref={canvasRef} width={800} height={600} />;
}Кастомная конфигурация
function CustomFluid() {
const { canvasRef, updateConfig } = useFluidSimulation({
BLOOM: true,
BLOOM_INTENSITY: 0.5,
SUNRAYS: false,
COLORFUL: true,
SPLAT_RADIUS: 0.3,
});
const handleConfigChange = () => {
updateConfig({
BLOOM_INTENSITY: 1.0,
CURL: 40,
});
};
return (
<div>
<canvas ref={canvasRef} width={800} height={600} />
<button onClick={handleConfigChange}>Изменить настройки</button>
</div>
);
}Программные всплески
function InteractiveFluid() {
const { canvasRef, splat, randomSplats } = useFluidSimulation();
const handleClick = (e: React.MouseEvent) => {
const rect = e.currentTarget.getBoundingClientRect();
const x = (e.clientX - rect.left) / rect.width;
const y = 1 - (e.clientY - rect.top) / rect.height;
splat(x, y, 1000, 1000, { r: 1, g: 0, b: 0 });
};
return (
<div>
<canvas ref={canvasRef} width={800} height={600} onClick={handleClick} />
<button onClick={() => randomSplats(5)}>Случайные всплески</button>
</div>
);
}Управление анимацией
function ControlledFluid() {
const { canvasRef, start, stop, pause, resume, captureScreenshot } = useFluidSimulation();
const handleScreenshot = () => {
const dataUrl = captureScreenshot();
if (dataUrl) {
const link = document.createElement('a');
link.download = 'fluid-screenshot.png';
link.href = dataUrl;
link.click();
}
};
return (
<div>
<canvas ref={canvasRef} width={800} height={600} />
<div>
<button onClick={start}>Старт</button>
<button onClick={stop}>Стоп</button>
<button onClick={pause}>Пауза</button>
<button onClick={resume}>Продолжить</button>
<button onClick={handleScreenshot}>Скриншот</button>
</div>
</div>
);
}function HoverFluid() {
const { canvasRef, updateConfig } = useFluidSimulation({
SIM_RESOLUTION: 128,
DYE_RESOLUTION: 512,
DENSITY_DISSIPATION: 0.97,
VELOCITY_DISSIPATION: 0.98,
PRESSURE_ITERATIONS: 10,
CURL: 5,
SPLAT_RADIUS: 0.2,
SHADING: true,
COLORFUL: true,
BACK_COLOR: { r: 15, g: 15, b: 15 },
BLOOM: false, // Отключить для лучшей производительности
TRIGGER_ON_HOVER: true, // Включить hover эффект
HOVER_FORCE_MULTIPLIER: 1, // Базовый множитель (настраивайте от 0.1 до 10)
});
const toggleHover = (enabled: boolean) => {
updateConfig({ TRIGGER_ON_HOVER: enabled });
};
return (
<div>
<canvas
ref={canvasRef}
width={800}
height={600}
style={{ cursor: 'none' }} // Скрыть курсор для лучшего эффекта
/>
<button onClick={() => toggleHover(false)}>Переключить в режим клика</button>
</div>
);
}Настройка размера вихрей и скорости
// Крупные медленные вихри
function LargeVorticesFluid() {
const { canvasRef } = useFluidSimulation({
CURL: 30, // Крупные вихри
SPLAT_RADIUS: 0.5, // Большая начальная точка
DENSITY_DISSIPATION: 0.99, // Дым держится очень долго
VELOCITY_DISSIPATION: 0.95, // Медленное затухание движения
SPLAT_FORCE: 3000, // Умеренная сила
});
return <canvas ref={canvasRef} width={800} height={600} />;
}
// Мелкие быстрые вихри
function SmallFastFluid() {
const { canvasRef } = useFluidSimulation({
CURL: 5, // Мелкие вихри
SPLAT_RADIUS: 0.1, // Маленькая точка
DENSITY_DISSIPATION: 0.9, // Быстро исчезает
VELOCITY_DISSIPATION: 0.8, // Быстро затухает
SPLAT_FORCE: 8000, // Сильный толчок
});
return <canvas ref={canvasRef} width={800} height={600} />;
}Настройка силы взаимодействия
function CustomForceFluid() {
const { canvasRef } = useFluidSimulation({
TRIGGER_ON_HOVER: true,
HOVER_FORCE_MULTIPLIER: 3, // Слабый hover эффект
CLICK_FORCE_MULTIPLIER: 2, // Усиленные клики
TOUCH_FORCE_MULTIPLIER: 10, // Очень сильные касания
});
return <canvas ref={canvasRef} width={800} height={600} />;
}Без автоматических событий
function ManualFluid() {
const { canvasRef, splat } = useFluidSimulation({}, false);
// Ваша собственная логика обработки событий
const handleMouseMove = (e: React.MouseEvent) => {
// Кастомная логика
};
return <canvas ref={canvasRef} width={800} height={600} onMouseMove={handleMouseMove} />;
}Производительность
Рекомендации для мобильных устройств:
{
SIM_RESOLUTION: 128, // Средняя детализация
DYE_RESOLUTION: 512, // Экономия памяти
BLOOM: false, // Отключить для производительности
SUNRAYS: false, // Отключить для производительности
}Советы по оптимизации:
- Уменьшите
SIM_RESOLUTIONиDYE_RESOLUTIONна слабых устройствах - Отключите
BLOOMиSUNRAYSдля лучшей производительности - Используйте
PRESSURE_ITERATIONS: 10-15вместо 20 для ускорения
Совместимость
- React 16.8+
- Современные браузеры с поддержкой WebGL
- TypeScript поддержка из коробки
Лицензия
MIT
Благодарности
Основано на WebGL Fluid Simulation от Pavel Dobryakov.
