Hello!
I recently discovered a way of adding fast/efficient effects to Processing sketches.
Unfortunately, this method only supports the FX2D
renderer, as AWT does not support effects.
The method is quite simple:
import javafx.scene.canvas.*;
import javafx.scene.effect.*;
import javafx.scene.paint.Color; // JavaFX uses different colors than Processing
GraphicsContext ctx;
GaussianBlur fxGaussianBlur = new GaussianBlur(20d); // the 'd' stands for 'double'
DropShadow fxDropShadow = new DropShadow(15d, 0d, 20d, Color.gray(0, 0.2)); // we have to use the Color JavaFX class becasue JFX does not support Processing colors (kind of obviously)
void setup() {
size(256, 160, FX2D); // it is crucial to set the FX2D renderer!
// in order to apply effects we need to get the 'native' graphics context of our canvas
ctx = ((Canvas) surface.getNative()).getGraphicsContext2D();
}
void draw() {
background(255);
fill(0);
noStroke();
// this applies the previously created effect to subsequent draw calls
ctx.setEffect(fxGaussianBlur);
rect(32, 32, 64, 64);
// to disable the effect, just set it to `null`
ctx.setEffect(null);
fill(56);
rect(64, 64, 64, 64);
ctx.setEffect(fxDropShadow); // material design-style drop shadow
fill(128);
ellipse(192, 64, 48, 48);
}
Here’s a screenshot:
As one might notice, those effects are way faster than the built-in filters, and provide similar functionality, if not more flexible.
You might’ve also noticed the use of the Color
class instead of int
s/Processing color
s. This Color
class is actually quite useful, however unsupported by Processing itself: Color
javadoc
Another nice thing one might do using this GraphicsContext
is gradients. Yeah, gradients are now possible without having to draw thousands of lines! Just a rect()
, ellipse()
, or any shape drawing call, and you’re all set! This is how you can use gradients:
import javafx.scene.canvas.*;
import javafx.scene.paint.*;
GraphicsContext ctx;
LinearGradient gradient;
void setup() {
size(256, 160, FX2D);
ctx = ((Canvas) surface.getNative()).getGraphicsContext2D();
/* I like to use the valueOf() function of the LinearGradient class,
because it provides a simple, CSS-like way for defining gradients. */
gradient = LinearGradient.valueOf("linear-gradient(" +
"from 0% 0% to 100% 100%," +
"black 0%, white 100%)");
}
void draw() {
background(255);
noStroke();
fill(#ff00ff); // we assign a dummy color due to how Processing draws fills and strokes internally
ctx.setFill(gradient); // use setStroke for strokes
rect(0, 0, width, height);
}
Here’s a reference for LinearGradient.valueOf(String)
.
And here’s a screenshot:
There are so many more things you can do with the GraphicsContext
! In fact, I highly suggest you check out its javadoc, because direct access to it really expands upon your drawing possibilities.
Thank you for reading!