feat: Enable text input signature feature

This commit is contained in:
RaktimaNXG
2023-12-29 16:36:49 +05:30
parent 751c7b5787
commit 852a3dc8bb
6 changed files with 242 additions and 103 deletions
@@ -522,9 +522,10 @@ function PdfRequestFiles() {
};
//function for save button to save signature or image url
const saveSign = (isDefaultSign) => {
const saveSign = (isDefaultSign, width, height) => {
const isTypeText = width && height ? true : false;
const signatureImg = isDefaultSign ? defaultSignImg : signature;
let imgWH = { width: "", height: "" };
let imgWH = { width: width ? width : "", height: height ? height : "" };
setIsSignPad(false);
setIsImageSelect(false);
setImage();
@@ -558,7 +559,8 @@ function PdfRequestFiles() {
signKey,
signatureImg,
imgWH,
isDefaultSign
isDefaultSign,
isTypeText
);
const updateSignerData = currentSigner.map((obj, ind) => {
@@ -885,7 +887,7 @@ function PdfRequestFiles() {
display: "flex",
flexDirection: "row",
alignItems: "center",
padding:"10px 0",
padding: "10px 0",
background: checkSignerBackColor(obj)
}}
key={ind}
@@ -657,10 +657,10 @@ function SignYourSelf() {
};
//function for save button to save signature or image url
const saveSign = (isDefaultSign) => {
const saveSign = (isDefaultSign, width, height) => {
const isTypeText = width && height ? true : false;
const signatureImg = isDefaultSign ? defaultSignImg : signature;
let imgWH = { width: "", height: "" };
let imgWH = { width: width ? width : "", height: height ? height : "" };
setIsSignPad(false);
setIsImageSelect(false);
setImage();
@@ -681,7 +681,8 @@ function SignYourSelf() {
signKey,
signatureImg,
imgWH,
isDefaultSign
isDefaultSign,
isTypeText
);
setXyPostion(getUpdatePosition);
@@ -27,8 +27,34 @@ function SignPad({
const allColor = [bluePen, redPen, blackPen];
const canvasRef = useRef(null);
const [isDefaultSign, setIsDefaultSign] = useState(false);
const [isTab, setIsTab] = useState("signature");
const [isTab, setIsTab] = useState("draw");
const [isSignImg, setIsSignImg] = useState("");
const [signValue, setSignValue] = useState("");
const [textWidth, setTextWidth] = useState(null);
const fontOptions = [
{ value: "Lucida Handwriting" },
{ value: "Segoe Script" },
{ value: "Harrington" },
{ value: "cursive" }
// Add more font options as needed
];
const [fontSelect, setFontSelect] = useState(fontOptions[0].value);
useEffect(() => {
const senderUser =
localStorage.getItem(
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
) &&
localStorage.getItem(
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
);
const jsonSender = JSON.parse(senderUser);
const currentUserName = jsonSender && jsonSender.name;
//function for clear signature
setSignValue(currentUserName);
}, []);
//function for clear signature
const handleClear = () => {
if (canvasRef.current) {
@@ -68,8 +94,13 @@ function SignPad({
setIsSignImg("");
onSaveSign(isDefaultSign);
} else {
setIsSignImg("");
onSaveSign();
if (isTab === "type") {
setIsSignImg("");
onSaveSign(false, textWidth, 30);
} else {
setIsSignImg("");
onSaveSign();
}
}
setPenColor("blue");
@@ -82,13 +113,15 @@ function SignPad({
setIsImageSelect(false);
setIsDefaultSign(false);
setImage();
setIsTab("signature");
setIsTab("draw");
}}
style={{
background: themeColor(),
color: "white"
}}
disabled={isSignImg || image || isDefaultSign ? false : true}
disabled={
isSignImg || image || isDefaultSign || textWidth ? false : true
}
type="button"
className={
isSignImg || image ? "finishBtn saveBtn" : "disabledFinish saveBtn"
@@ -105,8 +138,46 @@ function SignPad({
if (canvasRef.current) {
canvasRef.current.fromDataURL(isSignImg);
}
if (isTab === "type") {
convertToImg();
}
}, [isTab]);
//function for convert input text value in image
const convertToImg = async () => {
//get text content to convert in image
const textContent = signValue;
// Calculate the width of the text content
const textWidth = getTextWidth(textContent);
// Increase pixel ratio for higher resolution
const pixelRatio = window.devicePixelRatio || 1;
// Create a canvas with the calculated width
const canvas = document.createElement("canvas");
canvas.width = textWidth * pixelRatio + 20 * pixelRatio;
canvas.height = 20 * pixelRatio; // You can adjust the height as needed
setTextWidth(textWidth * pixelRatio);
// Draw the text content on the canvas
const context = canvas.getContext("2d");
context.scale(pixelRatio, pixelRatio);
context.font = `13px ${fontSelect}`; // You can adjust the font size and style
context.fillText(textContent, 0, 10); // Adjust the y-coordinate as needed
// Convert the canvas to image data
const dataUrl = canvas.toDataURL("image/png");
setSignature(dataUrl);
};
//for getting text content width render text in span tag and get width
const getTextWidth = (text) => {
const tempSpan = document.createElement("span");
tempSpan.innerText = text;
tempSpan.style.visibility = "hidden";
document.body.appendChild(tempSpan);
const width = tempSpan.offsetWidth;
document.body.removeChild(tempSpan);
return width;
};
return (
<div>
{/*isSignPad */}
@@ -143,22 +214,23 @@ function SignPad({
onClick={() => {
setIsDefaultSign(false);
setIsImageSelect(false);
setIsTab("signature");
setIsTab("draw");
setImage();
}}
style={{
color: isTab === "signature" ? themeColor() : "#515252",
color: isTab === "draw" ? themeColor() : "#515252",
marginLeft: "2px"
}}
className="signTab"
>
Signature
Draw
</span>
<div
style={{
border:
isTab === "signature"
isTab === "draw"
? "1.5px solid #108783"
: "1.5px solid #ffffff"
}}
@@ -187,7 +259,33 @@ function SignPad({
}}
></div>
</div>
<div>
<span
onClick={() => {
setIsDefaultSign(false);
setIsImageSelect(false);
setIsTab("type");
setImage();
}}
style={{
color: isTab === "type" ? themeColor() : "#515252",
marginLeft: "2px"
}}
className="signTab"
>
Type
</span>
<div
style={{
border:
isTab === "type"
? "1.5px solid #108783"
: "1.5px solid #ffffff"
}}
></div>
</div>
{defaultSign && (
<div>
<span
@@ -234,7 +332,7 @@ function SignPad({
setIsImageSelect(false);
setIsDefaultSign(false);
setImage();
setIsTab("signature");
setIsTab("draw");
}}
>
X
@@ -254,6 +352,7 @@ function SignPad({
alignItems: "center",
marginBottom: 6,
cursor: "pointer"
// background:'rgb(255, 255, 255)'
}}
className="signatureCanvas"
>
@@ -262,6 +361,7 @@ function SignPad({
style={{
width: "100%",
height: "100%",
background: "rgb(255, 255, 255)",
objectFit: "contain"
}}
src={defaultSign}
@@ -276,6 +376,7 @@ function SignPad({
<div
style={{
border: "1px solid black",
display: "flex",
flexDirection: "column",
justifyContent: "center",
@@ -293,6 +394,7 @@ function SignPad({
accept="image/*"
ref={imageRef}
hidden
// style={{ display: "none" }}
/>
<i className="fas fa-cloud-upload-alt uploadImgLogo"></i>
<div className="uploadImg">Upload</div>
@@ -301,25 +403,24 @@ function SignPad({
<>
<div
style={{
// position: "relative",
border: "1px solid black",
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
marginBottom: 6,
cursor: "pointer"
// justifyContent:"center"
overflow: "hidden"
}}
className="signatureCanvas"
>
<img
alt="stamp img"
alt="print img"
ref={imageRef}
// alt="preview image"
src={image.src}
style={{
width: "100%",
height: "100%",
//overflow:"hidden",
objectFit: "contain"
}}
ref={imageRef}
src={image.src}
/>
</div>
<div style={{ display: "flex", justifyContent: "flex-end" }}>
@@ -327,6 +428,46 @@ function SignPad({
</div>
</>
)
) : isTab === "type" ? (
<div>
<div style={{ display: "flex", justifyContent: "space-between" }}>
<span>Signature: </span>
<input
style={{ fontFamily: fontSelect }}
type="text"
className="signatureInput"
placeholder="Your signature"
value={signValue}
onChange={(e) => {
setSignValue(e.target.value);
convertToImg();
}}
/>
</div>
<div className="fontOptionContainer">
{fontOptions.map((font, ind) => {
return (
<div
key={ind}
style={{
fontFamily: font.value,
backgroundColor:
fontSelect === font.value && "rgb(206 225 247)"
}}
onClick={() => setFontSelect(font.value)}
>
<div style={{ padding: "5px 10px 5px 10px" }}>
{signValue ? signValue : "Your signature"}
</div>
</div>
);
})}
</div>
<div style={{ display: "flex", justifyContent: "flex-end" }}>
<SaveBtn />
</div>
</div>
) : (
<>
<SignatureCanvas
@@ -381,9 +522,11 @@ function SignPad({
width={20}
height={20}
/>
// </button>
);
})}
</div>
<SaveBtn />
</div>
</>
@@ -555,10 +555,11 @@ function EmbedPdfImage() {
};
//function for save button to save signature or image url
const saveSign = (isDefaultSign) => {
const saveSign = (isDefaultSign, width, height) => {
const isTypeText = width && height ? true : false;
const signatureImg = isDefaultSign ? defaultSignImg : signature;
const signFlag = true;
let imgWH = { width: "", height: "" };
let imgWH = { width: width ? width : "", height: height ? height : "" };
setIsSignPad(false);
setIsImageSelect(false);
setImage();
@@ -580,7 +581,7 @@ function EmbedPdfImage() {
signatureImg,
imgWH,
isDefaultSign,
signFlag
isTypeText
);
if (getUpdatePosition) {
@@ -123,7 +123,6 @@
}
.signatureInput {
padding: 10px;
width: 80%;
border-radius: 4px;
font-size: 0.75rem;
@@ -134,10 +133,13 @@
font-variation-settings: inherit;
font-weight: inherit;
overflow: visible;
height: 30px;
}
.signatureInput:focus {
outline: none;
border: 1px solid blue;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.18);
}
.resizable-box-overlay {
@@ -664,7 +666,7 @@ option {
.fontOptionContainer {
border: 1px solid #d6d3d3;
margin: 10px 5px 5px 5px;
margin: 10px 0px 5px 0px;
}
+59 -69
View File
@@ -126,7 +126,8 @@ export function onSaveSign(
signKey,
signatureImg,
imgWH,
isDefaultSign
isDefaultSign,
isTypeText
) {
let getIMGWH;
let getXYdata = xyPostion[index].pos;
@@ -134,21 +135,17 @@ export function onSaveSign(
if (position.key === signKey) {
if (isDefaultSign) {
getIMGWH = calculateImgAspectRatio(imgWH, position);
} else if (isTypeText) {
getIMGWH = { newWidth: imgWH.width, newHeight: imgWH.height };
} else {
getIMGWH = calculateImgAspectRatio(
{ width: 150, height: 60 },
position
);
}
const getSignImgWH = calculateImgAspectRatio(
{ width: 150, height: 60 },
position
);
const posWidth = isDefaultSign
? getIMGWH.newWidth
: position.Width
? getSignImgWH.newWidth
: 150;
const posHeight = isDefaultSign
? getIMGWH.newHeight
: position.Height
? getSignImgWH.newHeight
: 60;
const posWidth = getIMGWH ? getIMGWH.newWidth : 150;
const posHeight = getIMGWH ? getIMGWH.newHeight : 60;
return {
...position,
@@ -765,66 +762,62 @@ export const handleImageResize = (
export const handleSignYourselfImageResize = (
ref,
key,
direction,
position,
xyPostion,
index,
setXyPostion,
pdfOriginalWidth,
containerWH
setXyPostion
) => {
const updateFilter = xyPostion[index].pos.filter(
(data) => data.key === key && data.Width && data.Height
);
// const updateFilter = xyPostion[index].pos.filter(
// (data) => data.key === key && data.Width && data.Height
// );
if (updateFilter.length > 0) {
const getXYdata = xyPostion[index].pos;
const getPosData = getXYdata;
const addSign = getPosData.map((url, ind) => {
if (url.key === key) {
return {
...url,
Width: ref.offsetWidth,
Height: ref.offsetHeight,
IsResize: true
};
}
return url;
});
// if (updateFilter.length > 0) {
// const getXYdata = xyPostion[index].pos;
// const getPosData = getXYdata;
// const addSign = getPosData.map((url, ind) => {
// if (url.key === key) {
// return {
// ...url,
// Width: ref.offsetWidth,
// Height: ref.offsetHeight,
// IsResize: true
// };
// }
// return url;
// });
const newUpdateUrl = xyPostion.map((obj, ind) => {
if (ind === index) {
return { ...obj, pos: addSign };
}
return obj;
});
// const newUpdateUrl = xyPostion.map((obj, ind) => {
// if (ind === index) {
// return { ...obj, pos: addSign };
// }
// return obj;
// });
setXyPostion(newUpdateUrl);
} else {
const getXYdata = xyPostion[index].pos;
// setXyPostion(newUpdateUrl);
// } else {
const getXYdata = xyPostion[index].pos;
const getPosData = getXYdata;
const getPosData = getXYdata;
const addSign = getPosData.map((url, ind) => {
if (url.key === key) {
return {
...url,
Width: ref.offsetWidth,
Height: ref.offsetHeight,
IsResize: true
};
}
return url;
});
const addSign = getPosData.map((url, ind) => {
if (url.key === key) {
return {
...url,
Width: ref.offsetWidth,
Height: ref.offsetHeight,
IsResize: true
};
}
return url;
});
const newUpdateUrl = xyPostion.map((obj, ind) => {
if (ind === index) {
return { ...obj, pos: addSign };
}
return obj;
});
setXyPostion(newUpdateUrl);
}
const newUpdateUrl = xyPostion.map((obj, ind) => {
if (ind === index) {
return { ...obj, pos: addSign };
}
return obj;
});
setXyPostion(newUpdateUrl);
// }
};
//function for call cloud function signPdf and generate digital signature
@@ -1052,7 +1045,6 @@ export const getFirstLetter = (name) => {
return firstLetter;
};
export const darkenColor = (color, factor) => {
// Remove '#' from the color code and parse it to get RGB values
const hex = color.replace("#", "");
@@ -1070,5 +1062,3 @@ export const darkenColor = (color, factor) => {
.toString(16)
.padStart(6, "0")}`;
};