admin管理员组文章数量:1344174
I am using Signature pad js from szimek for making canvas signature pad. I have used 3 canvas at a time. After some research I got a link from Codepen for using multiple instance. Its working though, but the problem arise when the signature needs to be downloaded. After download the PNG and JPG, the images get fully black. Sharing the codes below.
var wrapper1 = document.getElementById("signature-pad-1"),
canvas1 = wrapper1.querySelector("canvas"),
signaturePad1;
var wrapper2 = document.getElementById("signature-pad-2"),
canvas2 = wrapper2.querySelector("canvas"),
signaturePad2;
function resizeCanvas(canvas) {
var ratio = window.devicePixelRatio || 1;
canvas.width = canvas.offsetWidth * ratio;
canvas.height = canvas.offsetHeight * ratio;
canvas.getContext("2d").scale(ratio, ratio);
}
function clear1() { signaturePad1.clear(); }
function clear2() { signaturePad2.clear(); }
function save() {
if (signaturePad1.isEmpty() || signaturePad2.isEmpty())
alert("Error: Please sign both pads!");
else
alert("Success!");
}
resizeCanvas(canvas1);
signaturePad1 = new SignaturePad(canvas1);
resizeCanvas(canvas2);
signaturePad2 = new SignaturePad(canvas2);
$("#clear1").click(clear1);
$("#clear2").click(clear2);
$("#save").click(save);
var savePNGButton1 = wrapper1.querySelector("[data-action=save-png]");
var saveJPGButton1 = wrapper1.querySelector("[data-action=save-jpg]");
var saveSVGButton1 = wrapper1.querySelector("[data-action=save-svg]");
var savePNGButton2 = wrapper2.querySelector("[data-action=save-png]");
var saveJPGButton2 = wrapper2.querySelector("[data-action=save-jpg]");
var saveSVGButton2 = wrapper2.querySelector("[data-action=save-svg]");
// One could simply use Canvas#toBlob method instead, but it's just to show
// that it can be done using result of SignaturePad#toDataURL.
function dataURLToBlob(dataURL) {
// Code taken from .js
var parts = dataURL.split(';base64,');
var contentType = parts[0].split(":")[1];
var raw = window.atob(parts[1]);
var rawLength = raw.length;
var uInt8Array = new Uint8Array(rawLength);
for (var i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], { type: contentType });
}
function download(dataURL, filename) {
if (navigator.userAgent.indexOf("Safari") > -1 && navigator.userAgent.indexOf("Chrome") === -1) {
window.open(dataURL);
} else {
var blob = dataURLToBlob(dataURL);
var url = window.URL.createObjectURL(blob);
var a = document.createElement("a");
a.style = "display: none";
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
}
}
savePNGButton1.addEventListener("click", function (event) {
if (signaturePad1.isEmpty()) {
alert("Please provide a signature first.");
} else {
var dataURL = signaturePad1.toDataURL();
download(dataURL, "signature.png");
}
});
saveJPGButton1.addEventListener("click", function (event) {
if (signaturePad1.isEmpty()) {
alert("Please provide a signature first.");
} else {
var dataURL = signaturePad1.toDataURL("image/jpeg");
download(dataURL, "signature.jpg");
}
});
saveSVGButton1.addEventListener("click", function (event) {
if (signaturePad1.isEmpty()) {
alert("Please provide a signature first.");
} else {
var dataURL = signaturePad1.toDataURL('image/svg+xml');
download(dataURL, "signature.svg");
}
});
savePNGButton2.addEventListener("click", function (event) {
if (signaturePad2.isEmpty()) {
alert("Please provide a signature first.");
} else {
var dataURL = signaturePad2.toDataURL();
download(dataURL, "signature.png");
}
});
saveJPGButton2.addEventListener("click", function (event) {
if (signaturePad2.isEmpty()) {
alert("Please provide a signature first.");
} else {
var dataURL = signaturePad2.toDataURL("image/jpeg");
download(dataURL, "signature.jpg");
}
});
saveSVGButton2.addEventListener("click", function (event) {
if (signaturePad2.isEmpty()) {
alert("Please provide a signature first.");
} else {
var dataURL = signaturePad2.toDataURL('image/svg+xml');
download(dataURL, "signature.svg");
}
});
body {
font-family: Helvetica, Sans-Serif;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
.m-signature-pad {
position: relative;
font-size: 10px;
width: 400px;
height: 400px;
border: 1px solid #e8e8e8;
background-color: #fff;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.27), 0 0 40px rgba(0, 0, 0, 0.08) inset;
border-radius: 4px;
}
.m-signature-pad:before, .m-signature-pad:after {
position: absolute;
z-index: -1;
content: "";
width: 40%;
height: 10px;
left: 20px;
bottom: 10px;
background: transparent;
-webkit-transform: skew(-3deg) rotate(-3deg);
-moz-transform: skew(-3deg) rotate(-3deg);
-ms-transform: skew(-3deg) rotate(-3deg);
-o-transform: skew(-3deg) rotate(-3deg);
transform: skew(-3deg) rotate(-3deg);
box-shadow: 0 8px 12px rgba(0, 0, 0, 0.4);
}
.m-signature-pad:after {
left: auto;
right: 20px;
-webkit-transform: skew(3deg) rotate(3deg);
-moz-transform: skew(3deg) rotate(3deg);
-ms-transform: skew(3deg) rotate(3deg);
-o-transform: skew(3deg) rotate(3deg);
transform: skew(3deg) rotate(3deg);
}
.m-signature-pad--body {
position: absolute;
left: 20px;
right: 20px;
top: 20px;
bottom: 20px;
border: 1px solid #f4f4f4;
}
.m-signature-pad--body canvas {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
border-radius: 4px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.02) inset;
background-color: #fff;
}
.btn-grp{display:block; width:100%;}
.signature-pad--footer{position:absolute; bottom:0; left:0; right:0;}
@media screen and (max-width: 1024px) {
.m-signature-pad {
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 50%;
height: auto;
min-width: 100px;
min-height: 100px;
margin: 5%;
}
#github {
display: none;
}
}
@media screen and (min-device-width: 768px) and (max-device-width: 1024px) {
.m-signature-pad {
margin: 10%;
}
}
@media screen and (max-height: 320px) {
.m-signature-pad--body {
left: 0;
right: 0;
top: 0;
bottom: 32px;
}
.m-signature-pad--footer {
left: 20px;
right: 20px;
bottom: 4px;
height: 28px;
}
.m-signature-pad--footer
.description {
font-size: 1em;
margin-top: 1em;
}
}
<script src=".3.1/jquery.min.js"></script>
<script src=".3.2/signature_pad.min.js"></script>
<div id="signature-pad-1" class="m-signature-pad">
<div class="m-signature-pad--body">
<canvas></canvas>
</div>
<div class="signature-pad--footer">
<div class="signature-pad--actions">
<div>
<button type="button" class="button clear" data-action="clear">Clear</button>
<button type="button" class="button" data-action="change-color">Change color</button>
<button type="button" class="button" data-action="undo">Undo</button>
</div>
<div>
<button type="button" class="button save" data-action="save-png">Save as PNG</button>
<button type="button" class="button save" data-action="save-jpg">Save as JPG</button>
<button type="button" class="button save" data-action="save-svg">Save as SVG</button>
</div>
</div>
</div>
</div>
<button id="clear1" onclick="clear(1);">Clear</button>
<div id="signature-pad-2" class="m-signature-pad">
<div class="m-signature-pad--body">
<canvas></canvas>
</div>
<div class="signature-pad--footer">
<div class="signature-pad--actions">
<div>
<button type="button" class="button clear" data-action="clear">Clear</button>
<button type="button" class="button" data-action="change-color">Change color</button>
<button type="button" class="button" data-action="undo">Undo</button>
</div>
<div>
<button type="button" class="button save" data-action="save-png">Save as PNG</button>
<button type="button" class="button save" data-action="save-jpg">Save as JPG</button>
<button type="button" class="button save" data-action="save-svg">Save as SVG</button>
</div>
</div>
</div>
</div>
<button id="clear2" onclick="clear(2);">Clear</button>
<br />
<button id="save">Save</button>
I am using Signature pad js from szimek for making canvas signature pad. I have used 3 canvas at a time. After some research I got a link from Codepen for using multiple instance. Its working though, but the problem arise when the signature needs to be downloaded. After download the PNG and JPG, the images get fully black. Sharing the codes below.
var wrapper1 = document.getElementById("signature-pad-1"),
canvas1 = wrapper1.querySelector("canvas"),
signaturePad1;
var wrapper2 = document.getElementById("signature-pad-2"),
canvas2 = wrapper2.querySelector("canvas"),
signaturePad2;
function resizeCanvas(canvas) {
var ratio = window.devicePixelRatio || 1;
canvas.width = canvas.offsetWidth * ratio;
canvas.height = canvas.offsetHeight * ratio;
canvas.getContext("2d").scale(ratio, ratio);
}
function clear1() { signaturePad1.clear(); }
function clear2() { signaturePad2.clear(); }
function save() {
if (signaturePad1.isEmpty() || signaturePad2.isEmpty())
alert("Error: Please sign both pads!");
else
alert("Success!");
}
resizeCanvas(canvas1);
signaturePad1 = new SignaturePad(canvas1);
resizeCanvas(canvas2);
signaturePad2 = new SignaturePad(canvas2);
$("#clear1").click(clear1);
$("#clear2").click(clear2);
$("#save").click(save);
var savePNGButton1 = wrapper1.querySelector("[data-action=save-png]");
var saveJPGButton1 = wrapper1.querySelector("[data-action=save-jpg]");
var saveSVGButton1 = wrapper1.querySelector("[data-action=save-svg]");
var savePNGButton2 = wrapper2.querySelector("[data-action=save-png]");
var saveJPGButton2 = wrapper2.querySelector("[data-action=save-jpg]");
var saveSVGButton2 = wrapper2.querySelector("[data-action=save-svg]");
// One could simply use Canvas#toBlob method instead, but it's just to show
// that it can be done using result of SignaturePad#toDataURL.
function dataURLToBlob(dataURL) {
// Code taken from https://github./ebidel/filer.js
var parts = dataURL.split(';base64,');
var contentType = parts[0].split(":")[1];
var raw = window.atob(parts[1]);
var rawLength = raw.length;
var uInt8Array = new Uint8Array(rawLength);
for (var i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], { type: contentType });
}
function download(dataURL, filename) {
if (navigator.userAgent.indexOf("Safari") > -1 && navigator.userAgent.indexOf("Chrome") === -1) {
window.open(dataURL);
} else {
var blob = dataURLToBlob(dataURL);
var url = window.URL.createObjectURL(blob);
var a = document.createElement("a");
a.style = "display: none";
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
}
}
savePNGButton1.addEventListener("click", function (event) {
if (signaturePad1.isEmpty()) {
alert("Please provide a signature first.");
} else {
var dataURL = signaturePad1.toDataURL();
download(dataURL, "signature.png");
}
});
saveJPGButton1.addEventListener("click", function (event) {
if (signaturePad1.isEmpty()) {
alert("Please provide a signature first.");
} else {
var dataURL = signaturePad1.toDataURL("image/jpeg");
download(dataURL, "signature.jpg");
}
});
saveSVGButton1.addEventListener("click", function (event) {
if (signaturePad1.isEmpty()) {
alert("Please provide a signature first.");
} else {
var dataURL = signaturePad1.toDataURL('image/svg+xml');
download(dataURL, "signature.svg");
}
});
savePNGButton2.addEventListener("click", function (event) {
if (signaturePad2.isEmpty()) {
alert("Please provide a signature first.");
} else {
var dataURL = signaturePad2.toDataURL();
download(dataURL, "signature.png");
}
});
saveJPGButton2.addEventListener("click", function (event) {
if (signaturePad2.isEmpty()) {
alert("Please provide a signature first.");
} else {
var dataURL = signaturePad2.toDataURL("image/jpeg");
download(dataURL, "signature.jpg");
}
});
saveSVGButton2.addEventListener("click", function (event) {
if (signaturePad2.isEmpty()) {
alert("Please provide a signature first.");
} else {
var dataURL = signaturePad2.toDataURL('image/svg+xml');
download(dataURL, "signature.svg");
}
});
body {
font-family: Helvetica, Sans-Serif;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
.m-signature-pad {
position: relative;
font-size: 10px;
width: 400px;
height: 400px;
border: 1px solid #e8e8e8;
background-color: #fff;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.27), 0 0 40px rgba(0, 0, 0, 0.08) inset;
border-radius: 4px;
}
.m-signature-pad:before, .m-signature-pad:after {
position: absolute;
z-index: -1;
content: "";
width: 40%;
height: 10px;
left: 20px;
bottom: 10px;
background: transparent;
-webkit-transform: skew(-3deg) rotate(-3deg);
-moz-transform: skew(-3deg) rotate(-3deg);
-ms-transform: skew(-3deg) rotate(-3deg);
-o-transform: skew(-3deg) rotate(-3deg);
transform: skew(-3deg) rotate(-3deg);
box-shadow: 0 8px 12px rgba(0, 0, 0, 0.4);
}
.m-signature-pad:after {
left: auto;
right: 20px;
-webkit-transform: skew(3deg) rotate(3deg);
-moz-transform: skew(3deg) rotate(3deg);
-ms-transform: skew(3deg) rotate(3deg);
-o-transform: skew(3deg) rotate(3deg);
transform: skew(3deg) rotate(3deg);
}
.m-signature-pad--body {
position: absolute;
left: 20px;
right: 20px;
top: 20px;
bottom: 20px;
border: 1px solid #f4f4f4;
}
.m-signature-pad--body canvas {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
border-radius: 4px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.02) inset;
background-color: #fff;
}
.btn-grp{display:block; width:100%;}
.signature-pad--footer{position:absolute; bottom:0; left:0; right:0;}
@media screen and (max-width: 1024px) {
.m-signature-pad {
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 50%;
height: auto;
min-width: 100px;
min-height: 100px;
margin: 5%;
}
#github {
display: none;
}
}
@media screen and (min-device-width: 768px) and (max-device-width: 1024px) {
.m-signature-pad {
margin: 10%;
}
}
@media screen and (max-height: 320px) {
.m-signature-pad--body {
left: 0;
right: 0;
top: 0;
bottom: 32px;
}
.m-signature-pad--footer {
left: 20px;
right: 20px;
bottom: 4px;
height: 28px;
}
.m-signature-pad--footer
.description {
font-size: 1em;
margin-top: 1em;
}
}
<script src="https://cdnjs.cloudflare./ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/signature_pad/1.3.2/signature_pad.min.js"></script>
<div id="signature-pad-1" class="m-signature-pad">
<div class="m-signature-pad--body">
<canvas></canvas>
</div>
<div class="signature-pad--footer">
<div class="signature-pad--actions">
<div>
<button type="button" class="button clear" data-action="clear">Clear</button>
<button type="button" class="button" data-action="change-color">Change color</button>
<button type="button" class="button" data-action="undo">Undo</button>
</div>
<div>
<button type="button" class="button save" data-action="save-png">Save as PNG</button>
<button type="button" class="button save" data-action="save-jpg">Save as JPG</button>
<button type="button" class="button save" data-action="save-svg">Save as SVG</button>
</div>
</div>
</div>
</div>
<button id="clear1" onclick="clear(1);">Clear</button>
<div id="signature-pad-2" class="m-signature-pad">
<div class="m-signature-pad--body">
<canvas></canvas>
</div>
<div class="signature-pad--footer">
<div class="signature-pad--actions">
<div>
<button type="button" class="button clear" data-action="clear">Clear</button>
<button type="button" class="button" data-action="change-color">Change color</button>
<button type="button" class="button" data-action="undo">Undo</button>
</div>
<div>
<button type="button" class="button save" data-action="save-png">Save as PNG</button>
<button type="button" class="button save" data-action="save-jpg">Save as JPG</button>
<button type="button" class="button save" data-action="save-svg">Save as SVG</button>
</div>
</div>
</div>
</div>
<button id="clear2" onclick="clear(2);">Clear</button>
<br />
<button id="save">Save</button>
Share
Improve this question
edited Feb 19, 2020 at 9:25
Matt Ellen
11.6k4 gold badges72 silver badges93 bronze badges
asked Feb 19, 2020 at 6:33
KevinKevin
1,3771 gold badge9 silver badges21 bronze badges
3
- I'm only getting the bug with the JPG option in Firefox – Matt Ellen Commented Feb 19, 2020 at 9:30
- Is there a reason you're using an old version of signature pad? – Matt Ellen Commented Feb 19, 2020 at 9:39
- @MattEllen same problem in latest version also.. I am getting the downloaded JPG is to be black. – Kevin Commented Feb 19, 2020 at 10:00
1 Answer
Reset to default 10The problem is that you're not setting the background colour, so the JPG is defaulting to black, which means that the whole image is black, because it can't handle transparency.
It's not a problem for PNG or SVG, which is why these work as expected.
To fix it set the background colour of the signature pad to white (taken from the signature pad example):
var signaturePad = new SignaturePad(canvas, {
// It's Necessary to use an opaque color when saving image as JPEG;
// this option can be omitted if only saving as PNG or SVG
backgroundColor: 'rgb(255, 255, 255)'
});
To apply the above to your code:
signaturePad1 = new SignaturePad(canvas1, {backgroundColor: 'rgb(255, 255, 255)'});
本文标签:
版权声明:本文标题:javascript - Canvas Signature on Signature Pad turns out fully black when downloading as JPG, PNG - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1743698560a2523921.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论