• Stars
    star
    130
  • Rank 277,575 (Top 6 %)
  • Language
    JavaScript
  • License
    GNU General Publi...
  • Created over 8 years ago
  • Updated about 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Mandelbrot fractal generator - js web app, uses zero libraries

Mandelbrot Fractal Generator

https://fractal.rafgraph.dev

JavaScript app that draws the Mandelbrot fractal and allows you to zoom in and explore the fractal (uses zero libraries). Launches in fullscreen mode for maximum impact on desktop, and has a responsive mobile compatible design with a multi-touch interface on mobile devices.

fractal-screenshot-from-iphone6-1

The coloring algorithm adjusts to the number of colors needed (i.e. the maximum escape time for the Mandelbrot set generation). See below for more info on the coloring algorithm.

By default the maximum escape time is 224, but you can select 448, 896, or 1792 via the higher escape time links on the launch page. Note that if you zoom in on the fractal and exit back to the launch page, and then select a different escape time, it will launch and redraw the fractal in the same place that you had zoomed in on, just with a different maximum escape time (and different coloring).

The code is split into two independent parts: app.js and fractal.js. The app handles all the setup and user interaction, and communicates these to the fractal using the fractal's api. The fractal just calculates and draws itself based on the settings it receives from the app.

Screenshots

Captured on iPhone 6

fractal-screenshot-from-iphone6-1



fractal-screenshot-from-iphone6-2



fractal-screenshot-from-iphone6-3



fractal-screenshot-from-iphone6-4



fractal-screenshot-from-iphone6-5



fractal-screenshot-from-iphone6-6



fractal-screenshot-from-iphone6-7



fractal-screenshot-from-iphone6-8



fractal-screenshot-from-iphone6-9

Fractal API

fractal.js is designed to work independently from app.js and can easily be integrated into any project. It provides an api through its update function, which takes an options object that instructs the fractal how to adjust itself before it re-renders.

// create fractal object, send it an HTML canvas element
// on which it will draw itself
var fractal = new Fractal(fractalCanvasElement);

// tell the fractal to update itself based on the options sent
// it will only redraw itself if necessary
fractal.update(options);
// fractal api as an options object
// all keys are optional
var options = {

  // set size of canvas
  // set pixel width of canvas
  pxWidth: number, // e.g. 2880

  // set pixel height of canvas
  pxHeight: number, // e.g. 1800


  // reset to default settings (coordinates, max escape time, and
  // starting options - does not reset canvas size)
  defaults: true,

  // reset to default cartesian coordinates (shows the whole fractal)
  resetToDefaultCords: true,

  // draw the fractal at these specific cartesian coordinates
  cords: {  
    xCartMin: number, // e.g. -2.1
    xCartMax: number, // e.g. 0.8,
    yCartMin: number, // e.g. -1.2,
    yCartMax: number // e.g. 1.2
  },

  // set the maximum escape time
  // numbers < 14 will be converted to 14
  // numbers > 1792 will be converted to 1792
  maxEscapeTime: number, // e.g. 224

  // pixel coordinates on canvas of point to zoom in on
  zoomInPxPoint: {
    xPx: number, // e.g. 100
    yPx: number // e.g. 100
  },

  // pixel coordinates on canvas of point to zoom out from
  zoomOutPxPoint: {
    xPx: number, // e.g. 100
    yPx: number // e.g. 100
  },

  // pixel coordinates of rectangle on canvas to zoom in on
  zoomInPxBox: {
    xPxMin: number, // e.g. 50
    xPxMax: number, // e.g. 100
    yPxMin: number, // e.g. 50
    yPxMax: number // e.g. 100
  },

  // set the current options as the starting options
  // the fractal resets to its starting options when told to reset
  setAsStartingOptions: bool, // e.g. true

  // reset cartesian coordinates to starting cartesian coordinates
  resetCords: bool, // e.g. true

  // reset the max escape time to the starting max escape time
  resetMaxEscapeTime: bool, // e.g. true

  // draw with distortion if the ratio of canvas width/height doesn't
  // match the ratio of cartesian coordinates width/height
  // by default (if this is omitted or false) the cartesian coordinates are
  // adjusted to match the ratio of the canvas width/height to avoid distortion
  distortion: bool // e.g. true

}

Coloring Algorithm

Start with 2 of the 3 red, green and blue values fixed at either 0 or 255, then increase the other R, G or B value in a given number of increments based on the number of colors needed, repeat this for seven cases and you get a maximum of 1792 colors (7*256). Note that white repeats 3 times, at the end of cases 2, 4 and 6.

The seven case are:
case 0: R=0, B=0, increase green from 0 to 255
case 1: R=0 G=255, increase blue from 0 to 255
case 2: G=255, B=255, increase red form 0 to 255
case 3: G=0, B=255, increase red from 0 to 255
case 4: R=255, B=255, increase green from 0 to 255
case 5: R=255, B=0, increase green from 0 to 255
case 6: R=255, G=255, increase blue from 0 to 255

Fractal.prototype.rgbNum = function(escapeTime){
  if (escapeTime <= 2) {
    //pin all escape times less than 3 to black
    return [0, 0, 0];
  } else if (escapeTime === this.maxEscapeTime) {
    //normally this would be white, but that's too much white, so override
    return [0, 25, 0];
  }

  var redNum;
  var greenNum;
  var blueNum;
  var rgbIncrements = Math.floor(((this.maxEscapeTime) / 7));
  var caseNum = Math.floor(escapeTime / rgbIncrements);
  var remainNum = escapeTime % rgbIncrements;

  switch (caseNum) {
    case 0:
      redNum = 0;
      greenNum = Math.floor(256 / rgbIncrements) * remainNum;
      blueNum = 0;
      break;
    case 1:
      redNum = 0;
      greenNum = 255;
      blueNum = Math.floor(256 / rgbIncrements) * remainNum;
      break;
    case 2:
      redNum = Math.floor(256 / rgbIncrements) * remainNum;
      greenNum = 255;
      blueNum = 255;
      break;
    case 3:
      redNum = Math.floor(256 / rgbIncrements) * remainNum;
      greenNum = 0;
      blueNum = 255;
      break;
    case 4:
      redNum = 255;
      greenNum = Math.floor(256 / rgbIncrements) * remainNum;
      blueNum = 255;
      break;
    case 5:
      redNum = 255;
      greenNum = Math.floor(256 / rgbIncrements) * remainNum;
      blueNum = 0;
      break;
    case 6:
      redNum = 255;
      greenNum = 255;
      blueNum = Math.floor(256 / rgbIncrements) * remainNum;
      break;
  }

  return [redNum, greenNum, blueNum];
};

More Repositories

1

spa-github-pages

Host single page apps with GitHub Pages
TypeScript
3,818
star
2

react-router-hash-link

Hash link scroll functionality for React Router
JavaScript
732
star
3

fscreen

Vendor agnostic access to the Fullscreen API
JavaScript
436
star
4

detect-it

Detect if a device is mouseOnly, touchOnly, or hybrid, and if the primary input is mouse or touch.
TypeScript
415
star
5

rollpkg

Zero-config build tool to create packages with Rollup and TypeScript
TypeScript
174
star
6

react-interactive

Better hover, active and focus states than CSS pseudo-classes, and a callback when the interactive state changes.
TypeScript
167
star
7

react-github-pages

React with React Router boilerplate for GitHub Pages
JavaScript
49
star
8

detect-passive-events

Detect if the browser supports passive event listeners
TypeScript
39
star
9

event-from

Determine if a browser event was caused by mouse, touch or key input.
TypeScript
21
star
10

react-markdown-tree

Renders markdown as React components and never uses dangerouslySetInnerHTML
JavaScript
15
star
11

the-listener

Easily set complex listeners for mouse, touch and pointer events without conflicts
JavaScript
13
star
12

browserslist-config-css-grid

Browserslist config of all browsers that support css grid
JavaScript
11
star
13

current-input

Detect the current input (mouse or touch) and fix the sticky :hover bug on touch devices.
TypeScript
9
star
14

simplemark

A smaller version of Markdown
JavaScript
9
star
15

detect-touch-events

Detect if the browser has a touch screen and supports the Touch Events API
JavaScript
8
star
16

detect-touch

Detect if a device has a touch interface
JavaScript
5
star
17

detect-pointer-events

Detect if the browser supports the Pointer Events API
JavaScript
5
star
18

react-fast-mount

Fast mount slow loading React components
JavaScript
5
star
19

react-simplemark

React component and renderer for Simplemark
JavaScript
4
star
20

four-corner-layout

Design concept for four presentation pages on a single web page
JavaScript
4
star
21

device-responsive-apps

Device responsive apps presentation
JavaScript
3
star
22

sticky-hover

Fixing the sticky hover problem on mobile
JavaScript
3
star
23

rollpkg-example-package

Example package for Rollpkg
TypeScript
3
star
24

polymorphic-as-prop-api

Polymorphic as prop api standard proof of concept. Brings composability to the polymorphic as prop.
TypeScript
3
star
25

react-markdown-tree-config-default

Default Config for React Markdown Tree
JavaScript
3
star
26

detect-hover

JavaScript wrapper for hover and any-hover media queries
JavaScript
2
star
27

flux-async-dispatcher

Asynchronous app dispatcher for Flux design pattern with React
JavaScript
2
star
28

detect-it-v1-demo

JavaScript
1
star
29

detect-it-v3-demo

JavaScript
1
star
30

detect-pointer

JavaScript wrapper for pointer and any-pointer media queries
JavaScript
1
star
31

interactive-style-options

Created with CodeSandbox
TypeScript
1
star
32

test-exports

JavaScript
1
star
33

react-interactive-v0-demo

Demo app fro React Interactive v0
JavaScript
1
star
34

randompage

HTML
1
star
35

react-component-dev

Minimal boilerplate for developing and demonstrating a React component
JavaScript
1
star