Created watermark component.
This commit is contained in:
parent
83e1180c37
commit
8c2a3f1216
117
packages/common/components/Watermarks/index.js
Normal file
117
packages/common/components/Watermarks/index.js
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
import { useEffect } from "react";
|
||||||
|
|
||||||
|
const Watermark = ({
|
||||||
|
text,
|
||||||
|
rotate,
|
||||||
|
image,
|
||||||
|
color,
|
||||||
|
|
||||||
|
isSemitransparent,
|
||||||
|
|
||||||
|
children,
|
||||||
|
}) => {
|
||||||
|
const setCtxText = (ctx) => {
|
||||||
|
const getColor = () => {
|
||||||
|
if (color)
|
||||||
|
return Array.isArray(color)
|
||||||
|
? `rgb(${color[0]}, ${color[1]}, ${color[2]}, 1)`
|
||||||
|
: color;
|
||||||
|
|
||||||
|
if (isSemitransparent) return "rgba(223, 226, 227, 1)";
|
||||||
|
|
||||||
|
return "rgba(208, 213, 218, 1)";
|
||||||
|
};
|
||||||
|
|
||||||
|
ctx.fillStyle = getColor();
|
||||||
|
ctx.textAlign = "center";
|
||||||
|
ctx.font = `${13}px Arial`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const setCtxCenteredText = (imgContent, ctx) => {
|
||||||
|
ctx.translate(imgContent.width / 2, imgContent.height / 2);
|
||||||
|
};
|
||||||
|
|
||||||
|
const setCtxRotate = (ctx) => {
|
||||||
|
const angle = (Math.PI / 180) * Number(rotate);
|
||||||
|
ctx.rotate(angle);
|
||||||
|
};
|
||||||
|
|
||||||
|
const setCtxTextWrap = (ctx, canvas) => {
|
||||||
|
let line = "",
|
||||||
|
marginTop = 0,
|
||||||
|
marginLeft = 0,
|
||||||
|
lineHeight = 15;
|
||||||
|
|
||||||
|
for (var n = 0; n < text.length; n++) {
|
||||||
|
let testLine = line + text[n];
|
||||||
|
let testWidth = ctx.measureText(testLine).width;
|
||||||
|
|
||||||
|
const percentWidth = ((canvas.width - testWidth) * 100) / canvas.width;
|
||||||
|
|
||||||
|
if (
|
||||||
|
(percentWidth < 32 && text[n] === " ") ||
|
||||||
|
testWidth > canvas.width - 4
|
||||||
|
) {
|
||||||
|
ctx.fillText(line, marginLeft, marginTop);
|
||||||
|
line = text[n];
|
||||||
|
marginTop += lineHeight;
|
||||||
|
} else {
|
||||||
|
line = testLine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.fillText(line, marginLeft, marginTop);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getContent = (canvas, ctx, imgContent, imgWidth, imgHeight) => {
|
||||||
|
setCtxText(ctx);
|
||||||
|
|
||||||
|
ctx.drawImage(imgContent, 0, 0, imgWidth, imgHeight);
|
||||||
|
|
||||||
|
setCtxCenteredText(imgContent, ctx);
|
||||||
|
setCtxRotate(ctx);
|
||||||
|
setCtxTextWrap(ctx, canvas);
|
||||||
|
};
|
||||||
|
|
||||||
|
const drawCanvas = (drawContent, ctx, canvas) => {
|
||||||
|
canvas.width = drawContent.naturalWidth;
|
||||||
|
canvas.height = drawContent.naturalHeight;
|
||||||
|
|
||||||
|
getContent(
|
||||||
|
canvas,
|
||||||
|
ctx,
|
||||||
|
drawContent || "",
|
||||||
|
drawContent.naturalWidth,
|
||||||
|
drawContent.naturalHeight
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderWatermark = () => {
|
||||||
|
const canvas = document.querySelector("canvas");
|
||||||
|
const ctx = canvas.getContext("2d");
|
||||||
|
|
||||||
|
const img = new Image();
|
||||||
|
|
||||||
|
img.onload = () => {
|
||||||
|
drawCanvas(img, ctx, canvas);
|
||||||
|
};
|
||||||
|
img.onerror = () => {
|
||||||
|
drawCanvas(text);
|
||||||
|
};
|
||||||
|
img.crossOrigin = "anonymous";
|
||||||
|
img.referrerPolicy = "no-referrer";
|
||||||
|
|
||||||
|
img.src = image;
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
renderWatermark();
|
||||||
|
}, [text, rotate, isSemitransparent]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<canvas>
|
||||||
|
<div>{children}</div>
|
||||||
|
</canvas>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default Watermark;
|
Loading…
Reference in New Issue
Block a user