I am working on something using HTML5 Canvas.
It's all working great, except right now, I can export the canvas content to PNG using Canvas2image. But I would like to export it to PDF. I've made some research and I'm pretty sure it's possible...but I can't seem to understand what I need to change in my code to make it work. I've read about a plugin called pdf.js...but I can't figure out how to implent it in my code.
First part :
function showDownloadText() {
document.getElementById("buttoncontainer").style.display = "none";
document.getElementById("textdownload").style.display = "block";
}
function hideDownloadText() {
document.getElementById("buttoncontainer").style.display = "block";
document.getElementById("textdownload").style.display = "none";
}
function convertCanvas(strType) {
if (strType == "PNG")
var oImg = Canvas2Image.saveAsPNG(oCanvas, true);
if (strType == "BMP")
var oImg = Canvas2Image.saveAsBMP(oCanvas, true);
if (strType == "JPEG")
var oImg = Canvas2Image.saveAsJPEG(oCanvas, true);
if (!oImg) {
alert("Sorry, this browser is not capable of saving " + strType + " files!");
return false;
}
oImg.id = "canvasimage";
oImg.style.border = oCanvas.style.border;
oCanvas.parentNode.replaceChild(oImg, oCanvas);
showDownloadText();
}
And the JS to that saves the image :
document.getElementById("convertpngbtn").onclick = function() {
convertCanvas("PNG");
}
document.getElementById("resetbtn").onclick = function() {
var oImg = document.getElementById("canvasimage");
oImg.parentNode.replaceChild(oCanvas, oImg);
hideDownloadText();
}
}
You need to use 2 plugins for this:
1) jsPDF
2) canvas-toBlob.js
Then add this piece of code to generate light weight PDF:
canvas.toBlob(function (blob) {
var url = window.URL || window.webkitURL;
var imgSrc = url.createObjectURL(blob);
var img = new Image();
img.src = imgSrc;
img.onload = function () {
var pdf = new jsPDF('p', 'px', [img.height, img.width]);
pdf.addImage(img, 0, 0, img.width, img.height);
pdf.save(fileName + '.pdf');
};
});
Look at this links:
http://www.codeproject.com/Questions/385045/export-html5-webpage-including-canvas-to-pdf
http://badassjs.com/post/708922912/pdf-js-create-pdfs-in-javascript
Most probably it will do the work you need
This jspdf is only useful in saving the file in the browser but we can't use that PDF generated to send to the server
Related
I would like to be able to display a GIF while the image is being loaded. Is this possible with the script I am using?
From what I understand I would use something like
$('#image').load { loadingimage.hide }
Here is my code:
$.get('http://192.168.1.69:8090/VirtualRadar/AirportDataThumbnails.json?icao=' + p.Icao + '®=' + p.Reg , function(res) {
var error = res.status;
if (error == "404") {
$("#image").attr('src', "placeholder.jpg");
$("#image2").attr('src', "placeholder.jpg");
$("#imageurl").attr('href', "//airport-data.com");
} else {
var imgUrl = res.data[0].image;
var imgHref = res.data[0].link;
$("#image").attr('src', imgUrl);
$("#image2").attr('src', imgUrl);
$("#imageurl").attr('href', imgHref);
}
})
Use the Image.onload attribute or attach an event listener.. load the loading wheel image first then display that while the larger image is loading...
function loadImage(src){
return new Promise(done=>{
var i = new Image();
i.onload = ()=>done(i);
i.src = src;
});
}
const loadImgSrc = "https://media.giphy.com/media/3oEjI6SIIHBdRxXI40/giphy.gif";
const bigImgSrc = "https://www.gannett-cdn.com/-mm-/4252e7af1a3888197136b717f5f93523f21f8eb2/r=x1683&c=3200x1680/local/-/media/USATODAY/onpolitics/2012/10/03/bigbird-16_9.jpg";
loadImage(loadImgSrc).then(img=>{
img.style.maxWidth = "100%";
document.getElementById('myImg').appendChild(img);
loadImage(bigImgSrc).then(img=>{
img.style.maxWidth = "100%";
document.getElementById('myImg').innerHTML = '';
document.getElementById('myImg').appendChild(img);
});
})
<div id=myImg></div>
I'm using the javascript from this older script: JavaScript: how to load all images in a folder?
However, I want to use the same javascript file to write some html code before the loop and some after the loop, all using this same javascript file.
Just putting a document.write before and after it in the javascript doesn't work.
var bCheckEnabled = true;
var bFinishCheck = false;
var img;
var imgArray = new Array();
var i = 0;
var myInterval = setInterval(loadImage, 1);
function loadImage() {
if (bFinishCheck) {
clearInterval(myInterval);
document.write('Loaded ' + i + ' image(s)');
return;
}
if (bCheckEnabled) {
bCheckEnabled = false;
img = new Image();
img.onload = fExists;
img.onerror = fDoesntExist;
img.src = 'assets/' + i + '.png';
document.write('<img src="assets/' + i + '.png" width="1016" height="813" alt="Kar" />');
}
}
function fExists() {
imgArray.push(img);
i++;
bCheckEnabled = true;
}
function fDoesntExist() {
bFinishCheck = true;
}
You may be using this example code incorrectly. Its intent appears to be to pre-load the image files in the background, not display them to the user in the HTML (yet). This is to improve apparent download speed of your page.
In short, this code doesn't actually render the image into the DOM; and that is intentional behavior.
I'm building a navigation bar where the images should be swapped out on mouseover; normally I use CSS for this but this time I'm trying to figure out javascript. This is what I have right now:
HTML:
<li class="bio"><img src="images/nav/bio.jpg" name="bio" /></li>
Javascript:
if (document.images) {
var bio_up = new Image();
bio_up.src = "images/nav/bio.jpg";
var bio_over = new Image();
bio_over.src = "images/nav/bio-ov.jpg";
}
function over_bio() {
if (document.images) {
document["bio"].src = bio_over.src
}
}
function up_bio() {
if (document.images) {
document["bio"].src = bio_up.src
}
}
However, all of the images have names of the form "xyz.jpg" and "xyz-ov.jpg", so I would prefer to just have a generic function that works for every image in the navbar, rather than a separate function for each image.
A quick-fire solution which should be robust enough provided all your images are of the same type:
$("li.bio a").hover(function() {
var $img = $(this).find("img");
$img[0].src = $img[0].src.replace(".jpg", "") + "-ov.jpg";
}, function() {
var $img = $(this).find("img");
$img[0].src = $img[0].src.replace("-ov.jpg", "") + ".jpg";
});
This should work will all image formats as long as the extension is between 2 and 4 characters long IE. png, jpeg, jpg, gif etc.
var images = document.getElementById('navbar').getElementsByTagName('img'), i;
for(i = 0; i < images.length; i++){
images[i].onmouseover = function(){
this.src = this.src.replace(/^(.*)(\.\w{2,4})$/, '$1'+'-ov'+'$2');
}
images[i].onmouseout = function(){
this.src = this.src.replace(/^(.*)-ov(\.\w{2,4})$/, '$1'+'$2');
}
}
Here's an idea in plain javascript (no jQuery):
function onMouseOverSwap(e) {
e.src = e.src.replace(/\.jpg$/", "-ov.jpg"); // add -ov onto end
}
function onMouseOutSwap(e) {
e.src = e.src.replace(/(-ov)+\.jpg$/, ".jpg"); // remove -ov
}
I'm using html5 to create drag and drop image upload functionality. This works great for me in firefox but in chrome the image onload event only fires the first time. If I drag multiple images in only the first works and if I drag a second in it fails. I believe the problem is with the image onload.
here is the way my code works I have removed the irrelevant sections:
var img = document.createElement("img");
var reader = new FileReader();
var canvas = document.createElement("canvas");
var canvasData;
var ctx = canvas.getContext("2d");
var myFiles;
var i = 0;
reader.onload = (function (aImg)
{
return function (e)
{
aImg.src = e.target.result;
};
})(img);
img.onload = function (){
//resizes image
//draws it to the canvas
//posts to server
i++;
if(i < myFiles.length){
processNext(i);
}
}
function processNext(filei) {
var file = myFiles[filei];
img.file = file;
reader.readAsDataURL(file);
}
i = 0;
myFiles = files;
processNext(0);
Does anyone know why this works in firefox but not chrome?
Explanation from chromium tracker:
This is not a bug. WebKit is just more strict. You must instantiate a new Image() object before the replacement, like this:
var photo = document.getElementById('image_id');
var img = new Image();
img.addEventListener('load', myFunction, false);
img.src = 'http://newimgsource.jpg';
photo.src = img.src;
source: http://code.google.com/p/chromium/issues/detail?id=7731#c12
This is strange, none of the above worked for me. I was defining the image variable as local and change it to global and it started working. Does this make sense? Can somebody explain it?
This didnt worked for me:
function loadImage() {
var ImageToLoad = new Image();
ImageToLoad.onload = function() {
console.log("finish loading");
};
ImageToLoad.src = "myimage.png";
}
This did work:
var ImageToLoad = new Image();
function loadImage() {
ImageToLoad.onload = function() {
console.log("finish loading");
};
ImageToLoad.src = "myimage.png";
}
How do you implement a preloader for a processingjs canvas element?
Two cases - assets have loaded, but js still calculating/rendering the view; assets have not loaded
P.S. Someone create the processingjs tag! Users with rep lt 1500 can't do that yet :(
May be this very old snippet helps you, after loading all images a callback is called. The folder param was used to load low or highres pics.
pics = {
'Trans100' : "trans100.png",
'Trans101' : "trans101.png",
'TransPanel' : "transPanel.png"
}
function oAttrs(o) { var a, out = ""; for (a in o){ out += a + " ";} return trim(out);}
function imageLoader(pics, folder, onready){
this.nextPic = 0;
this.pics = pics;
this.folder = folder;
this.names = oAttrs(pics).split(" ");
this.onReady = onready;
this.loadNext();
}
imageLoader.prototype.loadNext = function (){
if (this.nextPic === this.names.length) {
this.onReady();
} else {
this.loadImage(this.pics[this.names[this.nextPic]]);
}
};
imageLoader.prototype.loadImage = function (file){
this.nextPic += 1;
var pic = new Image();
pic.onload = this.loadNext.bind(this);
pic.onerror = function(){console.error("ERROR: " + file);};
pic.src = this.folder + file;
};
// example:
new imageLoader(pics, "images", function(){
console.log("Images loaded");
})