From 042c32ea3bcb4f5986dcb6b39a25a8cead3bf86a Mon Sep 17 00:00:00 2001 From: Sasha Sorokin Date: Thu, 9 Jul 2020 18:01:30 +0700 Subject: [Glitch] Replace repetitive blurhash code with component (#14267) Port 61c07c37317f01c1ab4981826704750fe9937fe7 to glitch-soc Signed-off-by: Thibaut Girka --- .../flavours/glitch/components/blurhash.js | 61 ++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 app/javascript/flavours/glitch/components/blurhash.js (limited to 'app/javascript/flavours/glitch/components/blurhash.js') diff --git a/app/javascript/flavours/glitch/components/blurhash.js b/app/javascript/flavours/glitch/components/blurhash.js new file mode 100644 index 000000000..172f8c2f5 --- /dev/null +++ b/app/javascript/flavours/glitch/components/blurhash.js @@ -0,0 +1,61 @@ +// @ts-check + +import { decode } from 'blurhash'; +import React, { useRef, useEffect } from 'react'; +import PropTypes from 'prop-types'; + +/** + * @typedef BlurhashPropsBase + * @property {string} hash Hash to render + * @property {number} width + * Width of the blurred region in pixels. Defaults to 32 + * @property {number} [height] + * Height of the blurred region in pixels. Defaults to width + * @property {boolean} [dummy] + * Whether dummy mode is enabled. If enabled, nothing is rendered + * and canvas left untouched + */ + +/** @typedef {JSX.IntrinsicElements['canvas'] & BlurhashPropsBase} BlurhashProps */ + +/** + * Component that is used to render blurred of blurhash string + * + * @param {BlurhashProps} param1 Props of the component + * @returns Canvas which will render blurred region element to embed + */ +function Blurhash({ + hash, + width = 32, + height = width, + dummy = false, + ...canvasProps +}) { + const canvasRef = /** @type {import('react').MutableRefObject} */ (useRef()); + + useEffect(() => { + const { current: canvas } = canvasRef; + canvas.width = canvas.width; // resets canvas + + if (dummy) return; + + const pixels = decode(hash, width, height); + const ctx = canvas.getContext('2d'); + const imageData = new ImageData(pixels, width, height); + + ctx.putImageData(imageData, 0, 0); + }, [dummy, hash, width, height]); + + return ( + + ); +} + +Blurhash.propTypes = { + hash: PropTypes.string.isRequired, + width: PropTypes.number, + height: PropTypes.number, + dummy: PropTypes.bool, +}; + +export default React.memo(Blurhash); -- cgit