Skip to content

Instantly share code, notes, and snippets.

@jdmichaud
Last active March 30, 2020 08:50
Show Gist options
  • Save jdmichaud/b528f5d541870e74bb2aefa76086a1b6 to your computer and use it in GitHub Desktop.
Save jdmichaud/b528f5d541870e74bb2aefa76086a1b6 to your computer and use it in GitHub Desktop.
Offscreen filter - url filter do not work with OffscreenCanvas and with filter are not applied on HTMLCanvasElement buffer.
<!DOCTYPE html>
<html>
<head>
<title>Test Filters</title>
<meta charset="utf-8">
<script type="text/javascript">
const xmlns = 'http://www.w3.org/2000/svg';
async function getImage(path) {
const response = await fetch(path);
return await createImageBitmap(await response.blob());
}
function createFilter(id, matrix) {
const svg = document.createElementNS(xmlns, 'svg');
const filter = document.createElementNS(xmlns, 'filter');
filter.setAttribute('id', id);
filter.setAttribute('x', 0);
filter.setAttribute('y', 0);
filter.setAttribute('width', '100%');
filter.setAttribute('height', '100%');
const feConvolveMatrix = document.createElementNS(xmlns, 'feConvolveMatrix');
feConvolveMatrix.setAttribute('order', 3);
feConvolveMatrix.setAttribute('kernelMatrix', matrix.join(' '));
filter.appendChild(feConvolveMatrix);
svg.appendChild(filter);
return svg;
}
function draw(image, offscreen, filter) {
const canvas = document.getElementById('viewport');
canvas.width = image.width;
canvas.height = image.height;
ctx = canvas.getContext('2d');
if (offscreen) {
// Using an OffscreenCanvas
const offscreenCanvas = new OffscreenCanvas(image.width, image.height);
const offscreenCtx = offscreenCanvas.getContext('2d');
offscreenCtx.filter = filter;
offscreenCtx.drawImage(image, 0, 0);
const imageBitmap = offscreenCanvas.transferToImageBitmap();
// Write image on visible canvas
ctx.drawImage(imageBitmap, 0, 0);
} else {
const onscreenCanvas = document.createElement('canvas');
document.body.appendChild(onscreenCanvas);
onscreenCanvas.width = image.width;
onscreenCanvas.height = image.height;
const onscreenCtx = onscreenCanvas.getContext('2d');
onscreenCanvas.style.filter = filter;
onscreenCtx.drawImage(image, 0, 0);
const imageData = onscreenCtx.getImageData(0, 0, onscreenCanvas.width, onscreenCanvas.height);
// Write image on visible canvas
ctx.putImageData(imageData, 0, 0);
}
}
async function main() {
// const filter = 'url(#testFilter)';
const filter = 'brightness(3)';
// Load the image
const image = await getImage('test.jpg');
// Create the filter in the DOM
document.body.appendChild(createFilter('testFilter', [1, 1, 0, 0, 0, 0, 0, 0, -1]));
draw(image, false, filter);
document.getElementById('canvas-type-switch').addEventListener('input', event => {
draw(image, event.target.checked, filter);
});
}
window.onload = main;
</script>
</head>
<body>
<canvas id="viewport"></canvas>
<input id="canvas-type-switch" type="checkbox" name="canvasType">
<label for="canvasType">Off screen canvas (chrome only)</label>
<div id="helper"></div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment