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

buddhabrot-4d-viewer

v1.0.3

Published

A Buddhabrot 4D viewer for your browser

Downloads

4

Readme

buddhabrot-4d-viewer-js

Explore the 4 dimensions of the Buddhabrot using this HTML5 + Javascript viewer.

Check out the live demo!

Features

  • Easy click & drag rotation.
  • RGB color channel selection.
  • Control the render using the 'Cancel', 'Repaint' and 'Reset' buttons.
  • Adjust the granularity of the scan ('Density' select).
  • Select the 4D rotation to render.
  • Histogram equalization for improved image quality.

Quick start

Options to add buddhabrot-4d-viewer-js to your project:

  • Install with npm: npm install buddhabrot-4d-viewer-js
  • Download the latest release
  • Clone the repo: git clone https://github.com/llop/buddhabrot-4d-viewer-js.git

Basic use

A working example can be found in index.html.

Include 'buddhabrot-4d-viewer.js' and 'buddhabrot-4d-viewer.css' in your HTML file.

<script src='buddhabrot-4d-viewer.js'></script>
<link rel='stylesheet' href='assets/buddhabrot-4d-viewer.css'>

Add the viewer's HTML elements. The following code is taken directly from the example:

<div class='buddhabrot'>
<canvas id='buddhabrot-canvas' class='buddhabrot-canvas' width='1000' height='600'>Your browser does not support canvas.</canvas>
<div class='buddhabrot-controls'>
  <div class='controls-table'>
  <div class='controls-table-row'>
    <div class='controls-table-cell'><div class='controls-label'>Colors</div></div>
    <div class='controls-table-cell'><div class='controls-label'>Volume</div></div>
  </div>
  <div class='controls-table-row'>
    <div class='controls-table-cell'>
      <div class='colors-box'>
        <input type='number' id='red-input' class='buddhabrot-input red-input' value='5000' min='1' max='5000'></input>
        <input type='range' id='red-slider' class='color-slider red-slider' value='5000' min='1' max='5000'></input>
      </div>
      <div class='colors-box'>
        <input type='number' id='green-input' class='buddhabrot-input green-input' value='500' min='1' max='5000'></input>
        <input type='range' id='green-slider' class='color-slider green-slider' value='500' min='1' max='5000'></input>
      </div>
      <div class='colors-box'>
        <input type='number' id='blue-input' class='buddhabrot-input blue-input' value='50' min='1' max='5000'></input>
        <input type='range' id='blue-slider' class='color-slider blue-slider' value='50' min='1' max='5000'></input>
      </div>
      <div class='controls-label image-label'>Image</div>
      <div class='buttons-box'>
        <button id='reset-btn' class='buddhabrot-button control-btn'>Reset</button>
        <div class='density-box'>
          <label for='density-select'>Density: </label>
          <select id='density-select' class='density-select buddhabrot-select'>
            <option value='low'>Low</option>
            <option value='standard' selected>Standard</option>
            <option value='hi'>High</option>
          </select>
        </div>
        <button id='repaint-btn' class='buddhabrot-button control-btn'>Repaint</button>
        <button id='cancel-btn' class='buddhabrot-button control-btn'>Cancel</button>
      </div>
    </div>
    <div class='controls-table-cell'>
      <div class='volume-controls'>
      <div class='volume-slider-box'>
        <input type='range' id='volume-slider' class='color-slider volume-slider' value='0' min='0' max='1000'></input>
      </div>
      <div class='volumes-box'>
        <img src='/img/fractals/buddhabrot-volumes.png' alt='Buddhabrot volumes' width='400' height='112'></img>
        <select id='volAX-select' class='volAX buddhabrot-select'>
          <option value='zr' selected>Zr</option>
          <option value='zi'>Zi</option>
          <option value='cr'>Cr</option>
          <option value='ci'>Ci</option>
        </select>
        <select id='volAY-select' class='volAY buddhabrot-select'>
          <option value='zr'>Zr</option>
          <option value='zi' selected>Zi</option>
          <option value='cr'>Cr</option>
          <option value='ci'>Ci</option>
        </select>
        <select id='volAZ-select' class='volAZ buddhabrot-select'>
          <option value='zr'>Zr</option>
          <option value='zi'>Zi</option>
          <option value='cr' selected>Cr</option>
          <option value='ci'>Ci</option>
        </select>
        <select id='volBX-select' class='volBX buddhabrot-select'>
          <option value='zr'>Zr</option>
          <option value='zi'>Zi</option>
          <option value='cr' selected>Cr</option>
          <option value='ci'>Ci</option>
        </select>
        <select id='volBY-select' class='volBY buddhabrot-select'>
          <option value='zr'>Zr</option>
          <option value='zi'>Zi</option>
          <option value='cr'>Cr</option>
          <option value='ci' selected>Ci</option>
        </select>
        <select id='volBZ-select' class='volBZ buddhabrot-select'>
          <option value='zr'>Zr</option>
          <option value='zi' selected>Zi</option>
          <option value='cr'>Cr</option>
          <option value='ci'>Ci</option>
        </select>
      </div>
      </div>
    </div>
  </div>
  </div>
</div>
</div>

All elements are, of course, customizable via CSS.

The initial image is the 'front' view of the (zr, zi, cr) object. Start the viewer with the following code:

<script>
window.addEventListener('load', event => {
  const canvas = document.getElementById('buddhabrot-canvas');
  const buddhabrot = new Buddhabrot(canvas);
  const buddhabrotControls = new BuddhabrotControls(buddhabrot, {
    redInput: document.getElementById('red-input'),
    greenInput: document.getElementById('green-input'),
    blueInput: document.getElementById('blue-input'),
    redSlider: document.getElementById('red-slider'),
    greenSlider: document.getElementById('green-slider'),
    blueSlider: document.getElementById('blue-slider'),
    volumeSlider: document.getElementById('volume-slider'),
    volAXSelect: document.getElementById('volAX-select'),
    volAYSelect: document.getElementById('volAY-select'),
    volAZSelect: document.getElementById('volAZ-select'),
    volBXSelect: document.getElementById('volBX-select'),
    volBYSelect: document.getElementById('volBY-select'),
    volBZSelect: document.getElementById('volBZ-select'),
    densitySelect: document.getElementById('density-select'),
    resetButton: document.getElementById('reset-btn'),
    repaintButton: document.getElementById('repaint-btn'),
    cancelButton: document.getElementById('cancel-btn')
  });
  buddhabrotControls.start();
});
</script>

Advanced use

It is recommended to learn about the Mandelbrot and the Buddhabrot rendering technique before changing the presets.

Buddhabrot class

The Buddhabrot class is in charge of scanning and rendering the fractal. Its constructor takes the HTML canvas (required).

You can also provide a custom options object to the Buddhabrot constructor in order to set the render parameters:

  • squareIters: How many points2 to sample within the area of a pixel.
  • maxNRed, maxNGreen, maxNBlue: For each color channel, set the maximum number of iterations for a point before it is considered to be in M.
  • histMaxN: To speed up scan times, a map is initially created to separate areas inside and outside of M. This value sets the maximum number of iterations for a point before it is considered to be in M in the aforementioned map. For consistency, it should be equal to max(maxNRed, maxNGreen, maxNBlue)
  • minN: Minimum number of iterations for a point before it is considered for plotting in the buddhabrot image.
  • brightness: Brightness multiplier.
  • colorCap: Maximum number of iterates per pixel per color channel to be considered for render.
  • waitMs: During a scan, this value sets how many ms before the next sleep cycle. This is necessary so as not to block the browser.
  • latitude, longitude: Determine the position of the observer.
  • volumeA, volumeB: The rendered 3D object can be volumeA, volumeB, or any rotation in between them. These values must be an array of the dimension's names.
  • angRot: Determines the rotation angles between volumeA's and volumeB's dimensions.

The defaults look like this:

{
  squareIters = undefined,
  maxNRed = 5000,
  maxNGreen = 500,
  maxNBlue = 50,
  histMaxN = 5000,
  minN = 1,
  brightness = 3.0,
  colorCap = 15000,
  waitMs = 100,
  latitude = 0.0,
  longitude = 0.0,
  angRot = [
      0.0,
      0.0,
      0.0
    ],
  volumeA = [ 
      'zr', 
      'zi', 
      'cr' 
    ],
  volumeB = [ 
      'cr', 
      'ci', 
      'zi' 
    ]
}

Render parameters can also be later changed using the following setters:

  • squareIters
  • setLatitudeLongitude(latitude, longitude)
  • setColorsMaxN(maxNRed, maxNGreen, maxNBlue)
  • setAngRot(angRotX, angRotY, angRotZ)
  • setVolumeA(x, y, z)
  • setVolumeB(x, y, z)

Once the a Buddhabrot instance is created, initialize() must be invoked. This function returns a Promise that will settle when everything is set up.

From then on, the Buddhabrot instance can be controlled via the following functions:

  • scan(callback): Sets off a scan for the currently specified parameters. callback must be a function, and it will be invoked when the scan finishes. callback will get one boolean argument success indicating if the scan completed or was canceled.

  • cancel(): Cancels the ongoing scan. It returns a Promise that will settle once the scan is cancelled. Does nothing if no scan is currently under way.

  • render(): Paints the available image data on the canvas.

Finally, there is a getter function painting to find out if a scan is in progress or not.

BuddhabrotControls class

The BuddhabrotControls class connects the UI to the Buddhabrot engine by using the aforementioned methods. Its constructor takes a Buddhabrot instance.

An options object can also be passed on to the constructor for customization. Besides the HTML elements, the following parameters are also available:

  • minNColor, maxNColor: Numeric bounds for the color channel inputs.
  • volumeSliderMax: Maximum value for the volumeA-volumeB slider input (minimum is 0).
  • progressWidth: Line width for the progress bar.
  • progressColor: Line color for the progress bar.
  • axesWidth: Line width for the axes.
  • axesColors: Array containing the line colors for the axes.

Default options are:

{
  minNColor = 1,
  maxNColor = 5000,
  volumeSliderMax = 1000,
  
  progressWidth = 4,
  progressColor = '#0f0',
  axesWidth = 3,
  axesColors = [ 
      '#9606b4', 
      '#ff8d12', 
      '#fff000' 
    ]
}

The start() function must be called to start up the viewer.

Events are dispatched whenever a scan starts or ends. It is best to add handlers before calling the start() function:

buddhabrotControls.on('scan-start', (event) => {
  console.log('scan-start', event);
});
buddhabrotControls.on('scan-end', (event) => {
  console.log('scan-end', event);
});
buddhabrotControls.start();

License

buddhabrot-4d-viewer-js is released under the MIT License. See LICENSE for details.