processing 1.1.18 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cb185e6835ce1e5361fcb66b667eb4d328c2af7e32a047bbb54e3397f4ea6973
4
- data.tar.gz: 4988d984b6c9ef039902d812ff2af813a967f11e43834cbfc168a980e2cc3179
3
+ metadata.gz: 854a85bdbae535597d51821ec8a2b8cc0c948ad355a889bfdd714dbcf2f2ee38
4
+ data.tar.gz: 5ed6cb2ae766ad26658a85826a660be0fbe92575c1b221a8440a38c722d8ec63
5
5
  SHA512:
6
- metadata.gz: '09f27de2e255f090068e1e4a9c3d421debbe37758e64e0436859be28a7a0fcf0fbc43c39f9bcafb913847df3a8eb3ddbe0ee0e5ee7cc9f680f6bef6ddb8cfeb0'
7
- data.tar.gz: 0b51113d2705579a0f7474aa60d8b73f393afc0f76c30085a87dd9381afa5c98ab69a2062d222550f04b9e06b56ae830898879628e8379323a4bd3ff71e4826d
6
+ metadata.gz: 49a769fbfd6e72f538b007b6da83dae50b873b2f15f1e4240bb4639f90ec459a56b0b1266a8e262aee994ed06e2f01be8e212c1215cbe815f54f188caefdef01
7
+ data.tar.gz: d5cd70ca39f8bd953d322efa398a4325863937c9d28338bd29d7f0004b8882c59d0004e49ca9b8468c89920e0980272f5fd8ad764ff754ebeb137f0b81c02169
@@ -36,23 +36,9 @@ jobs:
36
36
  echo path=$(ruby -e 'print Dir.glob("*.gem").first') >> $GITHUB_OUTPUT
37
37
 
38
38
  - name: create github release
39
- id: release
40
- uses: actions/create-release@v1
41
39
  env:
42
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
43
- with:
44
- tag_name: ${{ github.ref }}
45
- release_name: ${{ github.ref }}
46
-
47
- - name: upload to github release
48
- uses: actions/upload-release-asset@v1
49
- env:
50
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
51
- with:
52
- upload_url: ${{ steps.release.outputs.upload_url }}
53
- asset_path: ./${{ steps.gem.outputs.path }}
54
- asset_name: ${{ steps.gem.outputs.path }}
55
- asset_content_type: application/zip
40
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
41
+ run: ruby -I.github/workflows -rutils -e 'release(*ARGV)' ./${{ steps.gem.outputs.path }}
56
42
 
57
43
  - name: upload to rubygems
58
44
  env:
data/ChangeLog.md CHANGED
@@ -1,6 +1,15 @@
1
1
  # processing ChangeLog
2
2
 
3
3
 
4
+ ## [v1.2.0] - 2026-05-17
5
+
6
+ - [BREAKING] Wheel Y delta now follows top-left origin convention (from reflex)
7
+
8
+ - Avoid painter.push overhead in image/blend draws
9
+ - Rewrite README.md
10
+ - CI: Migrate release-gem.yml from actions/create-release to gh release create
11
+
12
+
4
13
  ## [v1.1.18] - 2026-05-10
5
14
 
6
15
  - Support WebAssembly
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Processing for CRuby - Processing compatible Creative Coding Framework
1
+ # Processing for CRuby - A Processing-compatible creative coding framework
2
2
 
3
3
  [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/xord/processing)
4
4
  ![License](https://img.shields.io/github/license/xord/processing)
@@ -21,18 +21,28 @@ Thanks for your support! 🙌
21
21
 
22
22
  ## 🚀 About
23
23
 
24
- **Processing for CRuby** is a creative coding framework compatible with the Processing language, designed specifically for CRuby.
24
+ **Processing for CRuby** is an independent, OpenGL-based Ruby implementation of the [Processing](https://processing.org/) API. It is **not** affiliated with the original Processing project, and it is not the JRuby / JOGL-based [`ruby-processing`](https://github.com/jashkenas/ruby-processing) either — this gem runs on CRuby (MRI), and all rendering goes through the `xord/*` family's own OpenGL 2D drawing engine ([Rays](https://github.com/xord/rays), via [Reflex](https://github.com/xord/reflex)).
25
25
 
26
- It allows artists and developers to create visual art and interactive graphics using the familiar Processing syntax and concepts, leveraging the power and flexibility of Ruby.
26
+ 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).
27
+
28
+ > Looking for the same API on mobile / with a game-engine flavor? See [RubySketch](https://github.com/xord/rubysketch).
29
+
30
+ ## 📋 Requirements
31
+
32
+ - Ruby **3.0.0** or later
33
+ - All the runtime requirements of [Reflex](https://github.com/xord/reflex) (which in turn brings Rays, Rucy, Xot, plus the platform GUI backend — AppKit / UIKit / Win32 / SDL2 — and OpenGL)
34
+ - The dependent gems are installed automatically: `rexml`, `xot`, `rucy`, `rays`, `reflexion`
35
+
36
+ There is no native C/C++ extension in this gem; the heavy lifting is done by the dependencies' extensions.
27
37
 
28
38
  ## 📦 Installation
29
39
 
30
40
  Add this line to your Gemfile:
31
41
  ```ruby
32
- $ gem 'processing'
42
+ gem 'processing'
33
43
  ```
34
44
 
35
- Then, install gem:
45
+ Then install:
36
46
  ```bash
37
47
  $ bundle install
38
48
  ```
@@ -42,7 +52,178 @@ Or install it directly:
42
52
  $ gem install processing
43
53
  ```
44
54
 
55
+ ## 📚 What's Provided
56
+
57
+ `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.
58
+
59
+ ### Two ways to use the gem
60
+
61
+ | Style | How |
62
+ | ------------------------------ | ----------------------------------------------------------------------------------------- |
63
+ | **Refinement, camelCase** | `require 'processing'` + `using Processing` — the standard, Processing-compatible style |
64
+ | **Refinement, snake_case too** | `require 'processing'` + `using Processing(snake_case: true)` — adds Ruby-idiomatic aliases (`color_mode`, `ellipse_mode`, ...) alongside the camelCase originals |
65
+
66
+ 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.
67
+
68
+ ### Core API
69
+
70
+ | Area | Examples |
71
+ | ----------------- | --------------------------------------------------------------------------------------------------- |
72
+ | Sketch lifecycle | `setup`, `draw`, `windowResized`, `windowMoved` |
73
+ | State | `size`, `frameRate`, `frameCount`, `width`, `height`, `pixelDensity`, `noLoop` / `loop_` / `redraw` |
74
+ | Color & state | `background`, `fill`, `stroke`, `noFill`, `noStroke`, `strokeWeight`, `colorMode`, `blendMode` |
75
+ | Shapes | `point`, `line`, `rect`, `square`, `triangle`, `quad`, `ellipse`, `circle`, `arc`, `curve`, `bezier`, `beginShape` / `endShape` / `vertex` |
76
+ | Transforms | `push` / `pop`, `pushMatrix` / `popMatrix`, `translate`, `rotate`, `scale`, `shearX`, `shearY` |
77
+ | Text | `text`, `textSize`, `textFont`, `textAlign`, `textWidth`, `loadFont` |
78
+ | Images | `image`, `loadImage` (file path *or* URL), `createImage`, `tint`, `noTint` |
79
+ | Vectors & math | `PVector`, `createVector`, `random`, `noise`, `map`, `lerp`, `dist`, `radians`, `degrees` |
80
+ | Input | `mousePressed`, `mouseReleased`, `mouseMoved`, `mouseDragged`, `mouseClicked`, `doubleClicked`, `mouseWheel`, `keyPressed`, `keyReleased`, `keyTyped`, `touchStarted` / `touchEnded` / `touchMoved`, `motion` |
81
+ | Live state | `mouseX`, `mouseY`, `pmouseX`, `pmouseY`, `key`, `keyCode`, `touches` |
82
+ | Off-screen buffer | `createGraphics` → a `Graphics` object that shares the same drawing API |
83
+ | Shapes / SVG | `createShape`, `loadShape` (SVG) |
84
+ | Shaders | `loadShader`, `shader`, `resetShader` — GLSL shaders go straight to the OpenGL pipeline |
85
+ | Camera | `createCapture` — live camera capture via `Rays::Camera` |
86
+
87
+ ### Top-level constants
88
+
89
+ The familiar Processing constants are defined: `RGB`, `HSB`, `RADIANS`, `DEGREES`, `CORNER`, `CORNERS`, `CENTER`, `RADIUS`, `LEFT`, `RIGHT`, `TOP`, `BOTTOM`, `BASELINE`, `BLEND`, `ADD`, `MULTIPLY`, `SCREEN`, ...
90
+
91
+ ### Internal API convention
92
+
93
+ 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.
94
+
95
+ ## 💡 Usage
96
+
97
+ ### Hello, world
98
+
99
+ ```ruby
100
+ require 'processing'
101
+ using Processing
102
+
103
+ draw do
104
+ background 0, 10 # alpha trail
105
+ textSize 50
106
+ text 'hello, world!', mouseX, mouseY
107
+ end
108
+ ```
109
+
110
+ Save as `hello.rb`, then `ruby hello.rb`. A 500 × 500 window opens automatically.
111
+
112
+ ### `setup` and `draw`
113
+
114
+ ```ruby
115
+ require 'processing'
116
+ using Processing
117
+
118
+ setup do
119
+ size 600, 400
120
+ colorMode RGB, 1
121
+ angleMode DEGREES
122
+ end
123
+
124
+ draw do
125
+ background 0
126
+ fill 1, 0.4, 0.1
127
+ stroke 1
128
+ strokeWeight 2
129
+
130
+ rectMode CENTER
131
+ push
132
+ translate width / 2, height / 2
133
+ rotate frameCount # one degree per frame
134
+ rect 0, 0, 200, 120, 12
135
+ pop
136
+ end
137
+ ```
138
+
139
+ ### Loading an image from a URL
140
+
141
+ ```ruby
142
+ require 'processing'
143
+ using Processing
144
+
145
+ icon = loadImage 'https://xord.org/rubysketch/images/rubysketch128.png'
146
+
147
+ draw do
148
+ background 0, 10
149
+ image icon, mouseX, mouseY, icon.width / 10, icon.height / 10
150
+ end
151
+ ```
152
+
153
+ ### Mouse and keyboard input
154
+
155
+ ```ruby
156
+ require 'processing'
157
+ using Processing
158
+
159
+ setup { background 0 }
160
+
161
+ draw do
162
+ fill 1
163
+ ellipse mouseX, mouseY, 20, 20
164
+ end
165
+
166
+ mousePressed { background 0 }
167
+ keyPressed { puts "pressed: #{key.inspect} (#{keyCode})" }
168
+ ```
169
+
170
+ ### Snake_case aliases
171
+
172
+ ```ruby
173
+ require 'processing'
174
+ using Processing(snake_case: true)
175
+
176
+ draw do
177
+ background 0
178
+ fill 1
179
+ stroke_weight 4 # alias of strokeWeight
180
+ no_fill # alias of noFill
181
+ ellipse mouse_x, mouse_y, 50, 50
182
+ end
183
+ ```
184
+
185
+ ### Off-screen rendering with `createGraphics`
186
+
187
+ ```ruby
188
+ require 'processing'
189
+ using Processing
190
+
191
+ g = nil
192
+
193
+ setup do
194
+ size 400, 400
195
+ g = createGraphics 200, 200
196
+ g.beginDraw
197
+ g.background 0, 100, 200
198
+ g.fill 255
199
+ g.ellipse 100, 100, 120, 120
200
+ g.endDraw
201
+ end
202
+
203
+ draw do
204
+ background 0
205
+ image g, mouseX - 100, mouseY - 100
206
+ end
207
+ ```
208
+
209
+ More examples live in [`examples/`](./examples) — `breakout.rb`, `camera.rb`, `clock.rb`, `delay_camera.rb`, `filter.rb`, `image.rb`, `shake.rb`, `shapes.rb`.
210
+
211
+ ## 🛠️ Development
212
+
213
+ ```bash
214
+ $ rake test # run the test suite (drawing tests run headless by default)
215
+ $ rake test:draw # run drawing tests only
216
+ $ rake doc # generate YARD docs
217
+ $ rake # default tasks
218
+ ```
219
+
220
+ Visual regression tests can be enabled with `TEST_WITH_BROWSER=1` — the suite then drives [Ferrum](https://github.com/rubycdp/ferrum) to capture browser-rendered screenshots and compare them against the gem's output.
221
+
222
+ In the [`xord/all`](https://github.com/xord/all) monorepo you can scope by module, e.g. `rake processing test`.
223
+
45
224
  ## 📜 License
46
225
 
47
226
  **Processing for CRuby** is licensed under the MIT License.
48
227
  See the [LICENSE](./LICENSE) file for details.
228
+
229
+ This project is not affiliated with [Processing.org](https://processing.org/); it is an independent reimplementation of their API.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.18
1
+ 1.2.0
@@ -108,11 +108,15 @@ module Processing
108
108
  end
109
109
 
110
110
  # @private
111
- def drawImage__(painter, *args, **states)
112
- shader = painter.shader || @filter&.getInternal__
113
- painter.push shader: shader, **states do |_|
114
- painter.image getInternal__, *args
111
+ def drawImage__(painter, *args)
112
+ if @filter
113
+ shader = painter.shader
114
+ painter.shader = @filter.getInternal__
115
115
  end
116
+ painter.image getInternal__, *args
117
+ nil
118
+ ensure
119
+ painter.shader = shader if @filter
116
120
  end
117
121
 
118
122
  end# Capture
@@ -1835,8 +1835,14 @@ module Processing
1835
1835
  def image(img, a, b, c = nil, d = nil)
1836
1836
  assertDrawing__
1837
1837
  x, y, w, h = toXYWH__ @imageMode__, a, b, c || img.width, d || img.height
1838
- img.drawImage__ @painter__, x, y, w, h, fill: getTint__, stroke: :none
1839
- nil
1838
+ fill = @painter__.fill
1839
+ begin
1840
+ @painter__.fill = getTint__
1841
+ img.drawImage__ @painter__, x, y, w, h
1842
+ nil
1843
+ ensure
1844
+ @painter__.fill = fill
1845
+ end
1840
1846
  end
1841
1847
 
1842
1848
  alias drawImage image
@@ -2074,9 +2080,17 @@ module Processing
2074
2080
  #
2075
2081
  def blend(img = nil, sx, sy, sw, sh, dx, dy, dw, dh, mode)
2076
2082
  assertDrawing__
2077
- (img || self).drawImage__(
2078
- @painter__, sx, sy, sw, sh, dx, dy, dw, dh,
2079
- fill: getTint__, stroke: :none, blend_mode: mode)
2083
+ fill = @painter__.fill
2084
+ blend_mode = @painter__.blend_mode
2085
+ begin
2086
+ @painter__.fill = getTint__
2087
+ @painter__.blend_mode = mode
2088
+ (img || self).drawImage__(@painter__, sx, sy, sw, sh, dx, dy, dw, dh)
2089
+ nil
2090
+ ensure
2091
+ @painter__.fill = fill
2092
+ @painter__.blend_mode = blend_mode
2093
+ end
2080
2094
  end
2081
2095
 
2082
2096
  # Loads all pixels to the 'pixels' array.
@@ -2535,11 +2549,15 @@ module Processing
2535
2549
  end
2536
2550
 
2537
2551
  # @private
2538
- def drawImage__(painter, *args, image__: getInternal__, **states)
2539
- shader = painter.shader || @filter__&.getInternal__
2540
- painter.push shader: shader, **states do |_|
2541
- painter.image image__, *args
2552
+ def drawImage__(painter, *args, image__: getInternal__)
2553
+ if @filter__
2554
+ shader = painter.shader
2555
+ painter.shader = @filter__.getInternal__
2542
2556
  end
2557
+ painter.image image__, *args
2558
+ nil
2559
+ ensure
2560
+ painter.shader = shader if @filter__
2543
2561
  end
2544
2562
 
2545
2563
  # @private
@@ -200,7 +200,13 @@ module Processing
200
200
  def blend(img = nil, sx, sy, sw, sh, dx, dy, dw, dh, mode)
201
201
  img ||= self
202
202
  getInternal__.paint do |painter|
203
- img.drawImage__ painter, sx, sy, sw, sh, dx, dy, dw, dh, blend_mode: mode
203
+ blend_mode = painter.blend_mode
204
+ begin
205
+ painter.blend_mode = mode
206
+ img.drawImage__ painter, sx, sy, sw, sh, dx, dy, dw, dh
207
+ ensure
208
+ painter.blend_mode = blend_mode
209
+ end
204
210
  end
205
211
  nil
206
212
  end
@@ -270,11 +276,15 @@ module Processing
270
276
  end
271
277
 
272
278
  # @private
273
- def drawImage__(painter, *args, **states)
274
- shader = painter.shader || @filter&.getInternal__
275
- painter.push shader: shader, **states do |_|
276
- painter.image getInternal__, *args
279
+ def drawImage__(painter, *args)
280
+ if @filter
281
+ shader = painter.shader
282
+ painter.shader = @filter.getInternal__
277
283
  end
284
+ painter.image getInternal__, *args
285
+ nil
286
+ ensure
287
+ painter.shader = shader if @filter
278
288
  end
279
289
 
280
290
  # @private
data/processing.gemspec CHANGED
@@ -26,10 +26,10 @@ Gem::Specification.new do |s|
26
26
  s.required_ruby_version = '>= 3.0.0'
27
27
 
28
28
  s.add_dependency 'rexml'
29
- s.add_dependency 'xot', '~> 0.3.12'
30
- s.add_dependency 'rucy', '~> 0.3.12'
31
- s.add_dependency 'rays', '~> 0.3.12'
32
- s.add_dependency 'reflexion', '~> 0.3.15'
29
+ s.add_dependency 'xot', '~> 0.3.13'
30
+ s.add_dependency 'rucy', '~> 0.3.13'
31
+ s.add_dependency 'rays', '~> 0.3.13'
32
+ s.add_dependency 'reflexion', '~> 0.4.0'
33
33
 
34
34
  s.files = `git ls-files`.split $/
35
35
  s.test_files = s.files.grep %r{^(test|spec|features)/}
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: processing
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.18
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - xordog
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-05-09 00:00:00.000000000 Z
11
+ date: 2026-05-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rexml
@@ -30,56 +30,56 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.3.12
33
+ version: 0.3.13
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.3.12
40
+ version: 0.3.13
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rucy
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 0.3.12
47
+ version: 0.3.13
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 0.3.12
54
+ version: 0.3.13
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rays
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.3.12
61
+ version: 0.3.13
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.3.12
68
+ version: 0.3.13
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: reflexion
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 0.3.15
75
+ version: 0.4.0
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 0.3.15
82
+ version: 0.4.0
83
83
  description: Creative Coding Framework has API compatible to Processing or p5.js.
84
84
  email: xordog@gmail.com
85
85
  executables: []