Skip to content

Высокопроизводительная библиотека для создания интерактивных fluid-симуляций в React-приложениях с использованием WebGL.

Notifications You must be signed in to change notification settings

gladunvv/react-webgl-fluid

Repository files navigation

React WebGL Fluid Simulation

npm version npm downloads GitHub stars License: MIT

Высокопроизводительная библиотека для создания интерактивных 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.

About

Высокопроизводительная библиотека для создания интерактивных fluid-симуляций в React-приложениях с использованием WebGL.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published