A JavaScript library for generating beautiful Penrose tilings - non-periodic tilings named after mathematician Roger Penrose.
Built for learning, exploring and imagining.
- Generate Penrose tilings with customizable options
- Two rendering methods:
- Canvas-based rendering for web applications
- Bitmap/pixel-based rendering for more control and potential use in non-canvas environments
- Easy to use API with sensible defaults
- Supports various customization options (colors, dimensions, subdivision levels)
npm install @guinetik/penrose-js
import { PenroseCanvas } from 'penrose-js';
// Get canvas and context
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// Create a Penrose tiling generator
const penrose = new PenroseCanvas();
// Generate the tiling with options
penrose.generatePenroseTiling({
ctx: ctx,
width: 800,
height: 800,
divisions: 5,
zoomType: 'in',
color1: '#cc4c4c', // color for thin rhombi
color2: '#4c99cc', // color for thick rhombi
color3: '#333333' // color for outlines
});
import { PenroseBitmap } from 'penrose-js';
// Create a Penrose bitmap generator
const penrose = new PenroseBitmap();
// Generate pixel data
const pixelData = penrose.generatePenroseTiling({
width: 800,
height: 800,
divisions: 5,
zoomType: 'in',
color1: [1, 0, 0, 1], // RGBA for thin rhombi (normalized 0-1)
color2: [0, 0, 1, 1], // RGBA for thick rhombi (normalized 0-1)
color3: [0, 0, 0, 1], // RGBA for outlines
backgroundColor: [1, 1, 1, 1] // RGBA background color
});
// Use with canvas
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
const imageData = new ImageData(pixelData, 800, 800);
ctx.putImageData(imageData, 0, 0);
<!-- UMD Version (unminified) -->
<script src="https://unpkg.com/penrose-js@0.1.0/dist/penrose-js.umd.js"></script>
<!-- UMD Version (minified) -->
<script src="https://unpkg.com/penrose-js@0.1.0/dist/penrose-js.umd.min.js"></script>
<script>
// Access via global variable
const penrose = new penrosejs.PenroseCanvas();
// ... use as normal
</script>
Abstract base class that provides common functionality.
const penrose = new Penrose(defaultOptions);
defaultOptions
(optional): Custom default options to override built-in defaults
generatePenroseTiling(options)
: Abstract method implemented by subclasses
Class for generating tilings directly on a canvas.
generatePenroseTiling(options)
: Generates a Penrose tiling on a canvas- Returns the canvas context for chaining
ctx
(required): Canvas 2D context to draw ondivisions
(default: 5): Number of subdivision iterationszoomType
(default: 'in'): Zoom level ('in' or 'out')width
(default: 800): Width of the outputheight
(default: 800): Height of the outputcolor1
: Color for thin rhombi (CSS color string or RGBA array)color2
: Color for thick rhombi (CSS color string or RGBA array)color3
: Color for outlines (CSS color string or RGBA array)backgroundColor
: Background color (CSS color string or RGBA array)
Class for generating tilings as pixel data.
generatePenroseTiling(options)
: Generates a Penrose tiling as pixel data- Returns a
Uint8ClampedArray
containing RGBA pixel data
- Returns a
divisions
(default: 5): Number of subdivision iterationszoomType
(default: 'in'): Zoom level ('in' or 'out')width
(default: 800): Width of the outputheight
(default: 800): Height of the outputcolor1
: Color for thin rhombi (CSS color string or RGBA array)color2
: Color for thick rhombi (CSS color string or RGBA array)color3
: Color for outlines (CSS color string or RGBA array)backgroundColor
: Background color (CSS color string or RGBA array)
# Install dependencies
npm install
# Start the development server
npm run dev
This will start a development server and open a browser to a demo page showcasing both the Canvas and Bitmap renderers.
# Build for production (standard and minified versions)
npm run build
# Build for debugging (unminified with source maps)
npm run build:debug
The build output includes:
-
ES modules:
- Standard:
dist/penrose-js.es.js
- Minified:
dist/penrose-js.es.min.js
- Standard:
-
UMD modules:
- Standard:
dist/penrose-js.umd.js
- Minified:
dist/penrose-js.umd.min.js
- Standard:
-
Debug build:
dist/penrose-js.debug.js
-
TypeScript declaration files:
dist/index.d.ts
Penrose tilings are fascinating mathematical structures that fill a plane non-periodically with a small set of shapes. This library implements the P3 Penrose tiling system (rhombus-based).
The generation algorithm:
- Starts with a set of triangles arranged in a decagon
- Iteratively subdivides these triangles using specific rules based on the golden ratio
- After the specified number of subdivision iterations, constructs the final tiling
Two rendering approaches are provided:
- Canvas-based: Uses the HTML5 Canvas API's path drawing
- Bitmap-based: Uses direct pixel manipulation for environments without Canvas
The mathematical foundation relies on:
- Complex number operations for precise vertex calculations
- The golden ratio (φ ≈ 1.618) as a key component of subdivision rules
- Triangle-based subdivision that produces the distinctive Penrose pattern
See the demos
directory for examples:
canvas-example.html
: Shows the canvas-based rendering approachbitmap-example.html
: Shows the bitmap-based rendering approach
MIT