react-icon-tint
Version:
Put some colour on your PNG Icons.
60 lines (59 loc) • 2.91 kB
JavaScript
;
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
const React = require("react");
const { memo, useEffect, useRef, useState } = React;
const IconTint = (_a) => {
var { fallback = React.createElement("span", null), src, color, maxWidth, maxHeight } = _a, props = __rest(_a, ["fallback", "src", "color", "maxWidth", "maxHeight"]);
const canvasRef = useRef(null);
const [size, setSize] = useState({
width: 100,
height: 100,
});
const _scaleImage = (srcWidth, srcHeight, maxWidth, maxHeight) => {
if ((maxWidth && !maxHeight) || (!maxWidth && maxHeight))
throw new Error('If you are going to provide width, make sure to provide height as well');
if (!maxWidth && !maxHeight)
return { width: srcWidth, height: srcHeight };
const ratio = Math.min(maxWidth / srcWidth, maxHeight / srcHeight);
return { width: srcWidth * ratio, height: srcHeight * ratio };
};
useEffect(() => {
const { current: canvas } = canvasRef;
const pic = new Image();
pic.src = src;
const tintCanvas = document.createElement('canvas');
const tintCtx = tintCanvas.getContext('2d');
const ctx = canvas.getContext('2d');
pic.onload = () => {
const { width, height } = _scaleImage(pic.width, pic.height, maxWidth, maxHeight);
setSize({ width, height });
// Clear previous render
tintCtx.clearRect(0, 0, width, height);
ctx.clearRect(0, 0, width, height);
tintCanvas.width = width;
tintCanvas.height = height;
tintCtx.fillStyle = color;
tintCtx.fillRect(0, 0, width, height);
tintCtx.globalCompositeOperation = 'destination-atop';
tintCtx.drawImage(pic, 0, 0, width, height);
ctx.globalAlpha = 1;
ctx.drawImage(tintCanvas, 0, 0, width, height);
};
}, [src, color, maxWidth, maxHeight, canvasRef === null || canvasRef === void 0 ? void 0 : canvasRef.current]);
if (typeof window !== 'undefined' && window.document && window.document.createElement) {
return React.createElement("canvas", Object.assign({ width: size.width, height: size.height, ref: canvasRef }, props));
}
return fallback;
};
exports.default = memo(IconTint);