Last active
March 30, 2020 08:50
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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