I was searching for a way to blur behind a transparent box in Nodejs
canvas API
. Something like the apple glossy effect when opening a window etc. After researching I found an answer on StackOverflow that demonstrates how to achieve the effect. The code was working fine in the browser version of Canvas, but when I tried that code in Nodejs canvas API, it gave different results.
var blurredRect = {
x: 80,
y: 80,
height: 400,
width: 400,
spread: 10
};
var ctx = canvas.getContext('2d');
var img = new Image();
img.onload = draw;
img.src = 'https://images.unsplash.com/photo-1507525428034-b723cf961d3e?auto=format&fit=crop&q=80&w=2073&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D';
function draw() {
canvas.width = img.width / 2;
canvas.height = img.height / 2;
// first pass draw everything
ctx.drawImage(img, 0,0, canvas.width, canvas.height);
// next drawings will be blurred
ctx.filter = 'blur('+ blurredRect.spread +'px)';
// draw the canvas over itself, cropping to our required rect
ctx.drawImage(canvas,
blurredRect.x, blurredRect.y, blurredRect.width, blurredRect.height,
blurredRect.x, blurredRect.y, blurredRect.width, blurredRect.height
);
// draw the coloring (white-ish) layer, without blur
ctx.filter = 'none'; // remove filter
ctx.fillStyle = 'rgba(255,255,255,0.2)';
ctx.fillRect(blurredRect.x, blurredRect.y, blurredRect.width, blurredRect.height);
}
<canvas id="canvas"></canvas>
When I tried the exact same code in Nodejs canvas api :-
const { createCanvas, loadImage } = require('canvas');
const fs = require('fs')
var blurredRect = {
x: 80,
y: 80,
height: 300,
width: 300,
spread: 10
};
const canvas = createCanvas(0, 0);
const ctx = canvas.getContext('2d');
// Load the background image
loadImage('path/to/newbrowser.png').then((background) => {
canvas.width = background.width / 2;
canvas.height = background.height / 2;
// first pass draw everything
ctx.drawImage(background, 0,0, canvas.width, canvas.height);
// next drawings will be blurred
ctx.filter = 'blur('+ blurredRect.spread +'px)';
// draw the canvas over itself, cropping to our required rect
ctx.drawImage(canvas,
blurredRect.x, blurredRect.y, blurredRect.width, blurredRect.height,
blurredRect.x, blurredRect.y, blurredRect.width, blurredRect.height
);
// draw the coloring (white-ish) layer, without blur
ctx.filter = 'none'; // remove filter
ctx.fillStyle = 'rgba(255,255,255,0.2)';
ctx.fillRect(blurredRect.x, blurredRect.y, blurredRect.width, blurredRect.height);
const outputStream = fs.createWriteStream('path/to/blur.png');
const stream = canvas.createPNGStream();
stream.pipe(outputStream);
});