react-native-signature-canvas
Version:
React Native Signature Component based Canvas for Android && IOS && expo
204 lines (173 loc) • 7.35 kB
JavaScript
const content = `
var wrapper = document.getElementById("signature-pad"),
clearButton = wrapper.querySelector("[data-action=clear]"),
saveButton = wrapper.querySelector("[data-action=save]"),
canvas = wrapper.querySelector("canvas"),
signaturePad;
// Adjust canvas coordinate space taking into account pixel ratio,
// to make it look crisp on mobile devices.
// This also causes canvas to be cleared.
function resizeCanvas() {
// When zoomed out to less than 100%, for some very strange reason,
// some browsers report devicePixelRatio as less than 1
// and only part of the canvas is cleared then.
var context = canvas.getContext("2d"); //context.getImageData(0,0,canvas.width,canvas.height)
var imgData = signaturePad ? signaturePad.toData() : null;
var ratio = Math.max(window.devicePixelRatio || 1, 1);
canvas.width = canvas.offsetWidth * ratio;
canvas.height = canvas.offsetHeight * ratio;
context.scale(ratio, ratio);
// context.putImageData(imgData,0,0);
imgData && signaturePad.fromData(imgData);
}
window.onresize = resizeCanvas;
resizeCanvas();
signaturePad = new SignaturePad(canvas, {
onBegin: () => window.ReactNativeWebView.postMessage("BEGIN"),
onEnd: () => window.ReactNativeWebView.postMessage("END"),
penColor: '<%penColor%>',
backgroundColor: '<%backgroundColor%>',
dotSize: <%dotSize%>,
minWidth: <%minWidth%>,
});
function clearSignature (event) {
signaturePad.clear();
window.ReactNativeWebView.postMessage("CLEAR");
}
function undo(event){
var data = signaturePad.toData();
if (data) {
data.pop(); // remove the last dot or line
signaturePad.fromData(data);
}
window.ReactNativeWebView.postMessage("UNDO");
}
function changePenColor(color){
signaturePad.penColor=color;
window.ReactNativeWebView.postMessage("CHANGE_PEN");
}
function getData (event) {
var data = signaturePad.toData();
window.ReactNativeWebView.postMessage(JSON.stringify(data));
}
function draw(event){
//signaturePad.minWidth= 0.5;
//signaturePad.maxWidth= 2.5;
var ctx = canvas.getContext('2d');
console.log(ctx.globalCompositeOperation);
ctx.globalCompositeOperation = 'source-over';
window.ReactNativeWebView.postMessage("DRAW");
}
function erase(event){
//signaturePad.minWidth= 5;
//signaturePad.maxWidth= 10;
var ctx = canvas.getContext('2d');
ctx.globalCompositeOperation = 'destination-out';
window.ReactNativeWebView.postMessage("ERASE");
}
clearButton.addEventListener("click", clearSignature );
var autoClear = <%autoClear%>;
var trimWhitespace = <%trimWhitespace%>;
var dataURL = '<%dataURL%>';
if (dataURL) {
signaturePad.fromDataURL(dataURL);
}
function cropWhitespace(url) {
var myImage = new Image();
myImage.crossOrigin = "Anonymous";
myImage.onload = function(){
window.ReactNativeWebView.postMessage(removeImageBlanks(myImage)); //Will return cropped image data
}
myImage.src = url;
//-----------------------------------------//
function removeImageBlanks(imageObject) {
imgWidth = imageObject.width;
imgHeight = imageObject.height;
var canvas = document.createElement('canvas');
canvas.setAttribute("width", imgWidth);
canvas.setAttribute("height", imgHeight);
var context = canvas.getContext('2d');
context.drawImage(imageObject, 0, 0);
var imageData = context.getImageData(0, 0, imgWidth, imgHeight),
data = imageData.data,
getRBG = function(x, y) {
var offset = imgWidth * y + x;
return {
red: data[offset * 4],
green: data[offset * 4 + 1],
blue: data[offset * 4 + 2],
opacity: data[offset * 4 + 3]
};
},
isWhite = function (rgb) {
// many images contain noise, as the white is not a pure #fff white
return !rgb.opacity || (rgb.red > 200 && rgb.green > 200 && rgb.blue > 200);
},
scanY = function (fromTop) {
var offset = fromTop ? 1 : -1;
// loop through each row
for(var y = fromTop ? 0 : imgHeight - 1; fromTop ? (y < imgHeight) : (y > -1); y += offset) {
// loop through each column
for(var x = 0; x < imgWidth; x++) {
var rgb = getRBG(x, y);
if (!isWhite(rgb)) {
if (fromTop) {
return y;
} else {
return Math.min(y + 1, imgHeight);
}
}
}
}
return null; // all image is white
},
scanX = function (fromLeft) {
var offset = fromLeft? 1 : -1;
// loop through each column
for(var x = fromLeft ? 0 : imgWidth - 1; fromLeft ? (x < imgWidth) : (x > -1); x += offset) {
// loop through each row
for(var y = 0; y < imgHeight; y++) {
var rgb = getRBG(x, y);
if (!isWhite(rgb)) {
if (fromLeft) {
return x;
} else {
return Math.min(x + 1, imgWidth);
}
}
}
}
return null; // all image is white
};
var cropTop = scanY(true),
cropBottom = scanY(false),
cropLeft = scanX(true),
cropRight = scanX(false),
cropWidth = cropRight - cropLeft,
cropHeight = cropBottom - cropTop;
canvas.setAttribute("width", cropWidth);
canvas.setAttribute("height", cropHeight);
// finally crop the guy
canvas.getContext("2d").drawImage(imageObject,
cropLeft, cropTop, cropWidth, cropHeight,
0, 0, cropWidth, cropHeight);
return canvas.toDataURL('<%imageType%>');
}
}
function readSignature() {
if (signaturePad.isEmpty()) {
window.ReactNativeWebView.postMessage("EMPTY");
} else {
var url = signaturePad.toDataURL('<%imageType%>');
trimWhitespace? cropWhitespace(url): window.ReactNativeWebView.postMessage(url);
if (autoClear) {
signaturePad.clear();
}
}
}
saveButton.addEventListener("click", () => {
readSignature();
getData();
});
`;
export default content;