npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

webgl-fluid-enhanced

v0.8.0

Published

WebGL Fluid Simulation for modern webpages (works even on mobile)

Downloads

539

Readme

WebGL Fluid Enhanced

npm version npm dependencies minzipped size npm downloads conventional commits

[!IMPORTANT] The new documentation and playground can be found here.

Table of Contents

  1. WebGL Fluid Enhanced
  2. Documentation for Outdated Version (v0.6.1 and Prior)
  3. Want to contribute
  4. References
  5. License

Documentation for Outdated Version (v0.6.1 and Prior)

Install

  npm install webgl-fluid-enhanced

New Features

  • Ability to change config after simulation has started
  • Use hover to activate
  • Choose colors used in simulation
  • Set background image
  • Set if splats generate on initial load
  • Specify how many splats should generate initially and from keypress
  • Assign specific key to splats (Can be disabled)
  • Trigger splats method
  • Pause method
  • Brightness option
  • Method to splat at specific coordinates
  • TypeScript support

Config options

webGLFluidEnhanced.config({
  SIM_RESOLUTION: 128, // Resolution of the simulation grid
  DYE_RESOLUTION: 1024, // Resolution of the dye grid
  CAPTURE_RESOLUTION: 512, // Resolution of captured frames
  DENSITY_DISSIPATION: 1, // Rate at which density dissipates
  VELOCITY_DISSIPATION: 0.2, // Rate at which velocity dissipates
  PRESSURE: 0.8, // Pressure value used in the simulation
  PRESSURE_ITERATIONS: 20, // Number of pressure iterations
  CURL: 30, // Curl value used in the simulation
  INITIAL: true, // Enables splats on initial load
  SPLAT_AMOUNT: 5, // Number of initial splats (Random number between n and n * 5)
  SPLAT_RADIUS: 0.25, // Radius of the splats
  SPLAT_FORCE: 6000, // Force applied by the splats
  SPLAT_KEY: 'Space', // Keyboard key to spawn new splats (empty to disable)
  SHADING: true, // Enables shading in the visualization
  COLORFUL: true, // Enables rapid changing of colors
  COLOR_UPDATE_SPEED: 10, // Speed of color update
  COLOR_PALETTE: [], // Custom color palette (empty by default, uses hex colors)
  HOVER: true, // Enables interaction on hover
  BACK_COLOR: '#000000', // Background color of the canvas
  TRANSPARENT: false, // Makes the canvas transparent if true
  BRIGHTNESS: 0.5, // Color brightness (Recommend lower than 1.0 if BLOOM is true)
  BLOOM: true, // Enables bloom effect
  BLOOM_ITERATIONS: 8, // Number of bloom effect iterations
  BLOOM_RESOLUTION: 256, // Resolution of the bloom effect
  BLOOM_INTENSITY: 0.8, // Intensity of the bloom effect
  BLOOM_THRESHOLD: 0.6, // Threshold for the bloom effect
  BLOOM_SOFT_KNEE: 0.7, // Soft knee value for the bloom effect
  SUNRAYS: true, // Enables sunrays effect
  SUNRAYS_RESOLUTION: 196, // Resolution of the sunrays effect
  SUNRAYS_WEIGHT: 1.0, // Weight of the sunrays effect
});

General info

Usage

Initialise:

webGLFluidEnhanced.simulation(document.querySelector('canvas'), {
  // Optional options
});

Edit config:

webGLFluidEnhanced.config({
  // Options
});

Trigger splats:

webGLFluidEnhanced.splats();

Splat at specific coordinates:

// x and y are the coordinates in the HTML document where the splat should occur.
// They represent the position of the center of the splat.
webGLFluidEnhanced.splat(
  x,
  y,

  // dx and dy represent the directional components of the splat's force.
  // They determine the direction of the fluid movement caused by the splat.
  // These values are best in the range from -1000 to 1000, with 0 representing no force.
  dx,
  dy,

  // color is the color of the fluid added by the splat as a string in hexadecimal format.
  // This parameter is optional. If not provided, colors from the palette or then a random color may be used.
  color,
);

Pause/resume the simulation:

// drawWhilePaused is an optional boolean that determines whether it is possible to stil draw while the simulation is paused.
webGLFluidEnhanced.pause(drawWhilePaused);

Download a screenshot:

webGLFluidEnhanced.screenshot();

Set background image

To set background image make sure the TRANSPARENT option is set to true, and in the CSS you can set background-image: url('<PHOTO-URL>'); and background-size: 100% 100%; to fill the whole canvas.

Background color

When using the BACK_COLOR option, the color you provided will be whitened when the BLOOM option is set to true.

Examples

HTML

<!doctype html>
<html>
  <body>
    <canvas style="width: 100vw; height: 100vh;"></canvas>
    <script type="importmap">
      {
        "imports": {
          "webgl-fluid-enhanced": "https://esm.run/webgl-fluid-enhanced@latest"
        }
      }
    </script>
    <script type="module">
      import webGLFluidEnhanced from 'webgl-fluid-simulation';

      webGLFluidEnhanced.simulation(document.querySelector('canvas'), {
        COLOR_PALETTE: ['#cc211b', '#f1c593', '#e87e54', '#f193a7', '#ec6fa9'],
        HOVER: false,
        SPLAT_RADIUS: 0.1,
        VELOCITY_DISSIPATION: 0.99,
        BLOOM: false,
      });
    </script>
  </body>
</html>

React

import { useEffect, useRef } from 'react';
import webGLFluidEnhanced from 'webgl-fluid-enhanced';

const App = () => {
  const canvasRef = useRef(null);

  useEffect(() => {
    webGLFluidEnhanced.simulation(canvasRef.current, {
      SIM_RESOLUTION: 256,
      DENSITY_DISSIPATION: 0.8,
      PRESSURE_ITERATIONS: 30,
      COLOR_PALETTE: ['#61dafb', '#a8dadc', '#457b9d', '#1d3557', '#f1faee'],
    });
  }, []);

  return <canvas ref={canvasRef} style={{ width: '100vw', height: '100vh' }} />;
};

export default App;

Next.js (tailwindcss)

'use client';

import { useEffect, useRef } from 'react';
import webGLFluidEnhanced from 'webgl-fluid-enhanced';

const App = () => {
  const canvasRef = useRef(null);

  useEffect(() => {
    webGLFluidEnhanced.simulation(canvasRef.current!, {
      PRESSURE: 0.2,
      SUNRAYS: false,
      START_SPLATS: 10,
      DENSITY_DISSIPATION: 3,
      CURL: 100,
      COLOR_PALETTE: ['#0000ff', '#111111', '#1d1d1d', '#eaeaea', '#4dba87'],
    });
  }, []);

  return <canvas ref={canvasRef} className='h-screen w-screen' />;
};

export default App;

Vue.js

<!-- Not tested! -->
<template>
  <canvas ref="canvas"></canvas>
</template>

<script setup>
import { onMounted, ref } from 'vue'
import WebGLFluid from 'webgl-fluid'

const canvas = ref()

onMounted(() => {
  webGLFluidEnhanced.simulation(canvas, {
        SPLAT_RADIUS: 0.5,
        COLOR_UPDATE_SPEED: 20,
        BLOOM: false,
    <>});
})
</script>

<style>
canvas {
  width: 100vw;
  height: 100vh;
}
</style>

Angular

// Not tested!
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import webGLFluidEnhanced from 'webgl-fluid-enhanced';

@Component({
  selector: 'app-root',
  template: `
    <canvas #canvasRef style="width: 100vw; height: 100vh;"></canvas>
  `,
})
export class AppComponent implements OnInit {
  @ViewChild('canvasRef', { static: true }) canvasRef!: ElementRef;

  ngOnInit(): void {
    webGLFluidEnhanced.simulation(this.canvasRef.nativeElement, {
      COLOR_PALETTE: ['#dd0031', '#c3002f', '#dd0031'],
      START_SPLATS: 50,
      TRANSPARENT: true,
    });
  }
}

Svelte

<!-- Not tested! -->
<script>
  import { onMount } from 'svelte';

  let canvasRef;

  onMount(() => {
    import('webgl-fluid-enhanced').then(({ default: webGLFluidEnhanced }) => {
      webGLFluidEnhanced.simulation(canvasRef, {
        SIM_RESOLUTION: 256,
        VELOCITY_DISSIPATION: 0.99,
        COLOR_PALETTE: ['#ff7f00'],
      });
    });
  });
</script>

<canvas bind:this={canvasRef} style="width: 100vw; height: 100vh;" />

Want to contribute

Feel free to open an issue or a pull request! I'm always open to suggestions and improvements, and I have tried to make the development environment as good as possible with a descriptive file structure and TypeScript definitions.

References

https://github.com/PavelDoGreat/WebGL-Fluid-Simulation

https://developer.nvidia.com/gpugems/gpugems/part-vi-beyond-triangles/chapter-38-fast-fluid-dynamics-simulation-gpu

https://github.com/mharrys/fluids-2d

https://github.com/haxiomic/GPU-Fluid-Experiments

License

The code is available under the MIT license