Processing for CRuby - A Processing-compatible creative coding framework

Ask DeepWiki License Build Status Gem Version

⚠️ Notice

This repository is a read-only mirror of our monorepo. We do not accept pull requests or direct contributions here.

🔄 Where to Contribute?

All development happens in our xord/all monorepo, which contains all our main libraries. If you'd like to contribute, please submit your changes there.

For more details, check out our Contribution Guidelines.

Thanks for your support! 🙌

🚀 About

Processing for CRuby is an independent, OpenGL-based Ruby implementation of the Processing API. It is not affiliated with the original Processing project, and it is not the JRuby / JOGL-based ruby-processing either — this gem runs on CRuby (MRI), and all rendering goes through the xord/* family's own OpenGL 2D drawing engine (Rays, via Reflex).

Write a setup do ... end and a draw do ... end at the top of a Ruby file, run it, and a window appears — just like a .pde sketch. This gem is the thin, pure-Ruby layer that maps Processing's vocabulary onto the underlying engine (windowing, drawing, input, MIDI, camera, physics).

Looking for the same API on mobile / with a game-engine flavor? See RubySketch.

📋 Requirements

  • Ruby 3.0.0 or later
  • All the runtime requirements of Reflex (which in turn brings Rays, Rucy, Xot, plus the platform GUI backend — AppKit / UIKit / Win32 / SDL2 — and OpenGL)
  • The dependent gems are installed automatically: rexml, xot, rucy, rays, reflexion

There is no native C/C++ extension in this gem; the heavy lifting is done by the dependencies' extensions.

📦 Installation

Add this line to your Gemfile:

gem 'processing'

Then install:

$ bundle install

Or install it directly:

$ gem install processing

📚 What's Provided

require 'processing' exposes a Processing module that, when activated, makes the Processing API available as top-level methods inside the current file. There are two ways to activate it.

Two ways to use the gem

Style How
Refinement, camelCase require 'processing' + using Processing — the standard, Processing-compatible style
Refinement, snake_case too require 'processing' + using Processing(snake_case: true) — adds Ruby-idiomatic aliases (color_mode, ellipse_mode, ...) alongside the camelCase originals

In both cases, the framework opens a window for you and runs the sketch automatically when the file exits. You do not need an explicit start call.

Core API

Area Examples
Sketch lifecycle setup, draw, windowResized, windowMoved
State size, frameRate, frameCount, width, height, pixelDensity, noLoop / loop_ / redraw
Color & state background, fill, stroke, noFill, noStroke, strokeWeight, colorMode, blendMode
Shapes point, line, rect, square, triangle, quad, ellipse, circle, arc, curve, bezier, beginShape / endShape / vertex
Transforms push / pop, pushMatrix / popMatrix, translate, rotate, scale, shearX, shearY
Text text, textSize, textFont, textAlign, textWidth, loadFont
Images image, loadImage (file path or URL), createImage, tint, noTint
Vectors & math PVector, createVector, random, noise, map, lerp, dist, radians, degrees
Input mousePressed, mouseReleased, mouseMoved, mouseDragged, mouseClicked, doubleClicked, mouseWheel, keyPressed, keyReleased, keyTyped, touchStarted / touchEnded / touchMoved, motion
Live state mouseX, mouseY, pmouseX, pmouseY, key, keyCode, touches
Off-screen buffer createGraphics → a Graphics object that shares the same drawing API
Shapes / SVG createShape, loadShape (SVG)
Shaders loadShader, shader, resetShader — GLSL shaders go straight to the OpenGL pipeline
Camera createCapture — live camera capture via Rays::Camera

Top-level constants

The familiar Processing constants are defined: RGB, HSB, RADIANS, DEGREES, CORNER, CORNERS, CENTER, RADIUS, LEFT, RIGHT, TOP, BOTTOM, BASELINE, BLEND, ADD, MULTIPLY, SCREEN, ...

Internal API convention

Methods ending in __ (e.g. init__, beginDraw__, @context__) are framework internals and are deliberately excluded from the refinement-exposed top-level method set, so they will not collide with names in your sketch.

💡 Usage

Hello, world

require 'processing'
using Processing

draw do
  background 0, 10           # alpha trail
  textSize 50
  text 'hello, world!', mouseX, mouseY
end

Save as hello.rb, then ruby hello.rb. A 500 × 500 window opens automatically.

setup and draw

require 'processing'
using Processing

setup do
  size 600, 400
  colorMode RGB, 1
  angleMode DEGREES
end

draw do
  background 0
  fill 1, 0.4, 0.1
  stroke 1
  strokeWeight 2

  rectMode CENTER
  push
    translate width / 2, height / 2
    rotate frameCount      # one degree per frame
    rect 0, 0, 200, 120, 12
  pop
end

Loading an image from a URL

require 'processing'
using Processing

icon = loadImage 'https://xord.org/rubysketch/images/rubysketch128.png'

draw do
  background 0, 10
  image icon, mouseX, mouseY, icon.width / 10, icon.height / 10
end

Mouse and keyboard input

require 'processing'
using Processing

setup { background 0 }

draw do
  fill 1
  ellipse mouseX, mouseY, 20, 20
end

mousePressed { background 0 }
keyPressed   { puts "pressed: #{key.inspect} (#{keyCode})" }

Snake_case aliases

require 'processing'
using Processing(snake_case: true)

draw do
  background 0
  fill 1
  stroke_weight 4              # alias of strokeWeight
  no_fill                      # alias of noFill
  ellipse mouse_x, mouse_y, 50, 50
end

Off-screen rendering with createGraphics

require 'processing'
using Processing

g = nil

setup do
  size 400, 400
  g = createGraphics 200, 200
  g.beginDraw
  g.background 0, 100, 200
  g.fill 255
  g.ellipse 100, 100, 120, 120
  g.endDraw
end

draw do
  background 0
  image g, mouseX - 100, mouseY - 100
end

More examples live in examples/breakout.rb, camera.rb, clock.rb, delay_camera.rb, filter.rb, image.rb, shake.rb, shapes.rb.

🛠️ Development

$ rake test         # run the test suite (drawing tests run headless by default)
$ rake test:draw    # run drawing tests only
$ rake doc          # generate YARD docs
$ rake              # default tasks

Visual regression tests can be enabled with TEST_WITH_BROWSER=1 — the suite then drives Ferrum to capture browser-rendered screenshots and compare them against the gem's output.

In the xord/all monorepo you can scope by module, e.g. rake processing test.

📜 License

Processing for CRuby is licensed under the MIT License. See the LICENSE file for details.

This project is not affiliated with Processing.org; it is an independent reimplementation of their API.