printing just canvas element on a page - html

im a little stuck using the canvas element in html5, have scoured the net looking for a workable solution but to no avail!
the main issue is that I want to click a button and send just the canvas element on the page to the printer.
i have tried using toDataUrl() - but this just seems to be resulting in a blank white image which has none of the canvas content!
the other issue i am experiencing is that attempting to initiate any javascript functions using "onClick" attached to a form button seems to be being tempermental at best!
here is my current attempt - this works in the sense that it does open a new window and attempt to send it to printer and it does create a base64 string (tested this using the "dataUrl" output on the second lowest document.write line) but as previously mentioned the image appears to be completely blank! (the canvas itself is definitely filled, both with an imported image and some text)
function printCanv()
{
var dataUrl = document.getElementById('copy').toDataURL(); //attempt to save base64 string to server using this var
document.getElementById('testBox').value = dataUrl; //load data into textarea
//attempt open window and add canvas etc
win = window.open();
self.focus();
win.document.open();
win.document.write('<'+'html'+'><'+'head'+'><'+'style'+'>');
win.document.write('body, td { font-family: Verdana; font-size: 10pt;}');
win.document.write('<'+'/'+'style'+'><'+'/'+'head'+'><'+'body'+'>');
((image code is here but site will not let me post it for some reason?))
win.document.write(dataUrl);
win.document.write('<'+'/'+'body'+'><'+'/'+'html'+'>');
win.document.close();
win.print();
win.close();
}
note: the code from "win = window.open()" onwards is currently taken from a tutorial and not my own work!
it is currently being called using <body onload="printCanv";"> - for some reason I could not get this to work at all using a button (little chunk of code below is my attempt which seemed to fail)
<input type="button" id="test" value="click me" onClick="printCanv();"> </input>
apologies is this help request is all over the place! i haven't posted to a site like this before and it didn't like me posting some html/script!
thanks in advance for any help you may be able to offer :)
Edit: draw function:
function copydraw() { //function called "copydraw" (could be anything)
var testimage3 = document.getElementById('copy').getContext('2d'); //declare variable for canvas overall (inc paths)
var img3 = new Image(); //declare image variable called "img3"
var testVar = document.getElementById('userIn').value; //take value from userin box. only updating on browser refresh?
img3.onload = function(){ //when image has loaded (img.onload) run this function
testimage3.drawImage(img3,0,0); //draw "img" to testimage
testimage3.font = "30pt 'Arial'"; //font method varies font attrib (weight, size, face)
testimage3.fillStyle = "#000000"; //sets fill color
testimage3.fillText(testVar, 310, 360); //filltext method draws text (xup ydown)
}
img3.src = 'images/liecakeA4.jpg'; //source of image
}
This function works perfectly, it draws the object and adds text from the variable, but for some reason it seems to be preventing me from outputting it as an image. I'm really confused!

I'm not sure exactly what's wrong with your code, I suspect in your current version calling printCanv in the body load event will mean you're trying to print the canvas before it's drawn. Running it off the button should work better, I'm not sure why that wasn't working for you as there's no reason in principle why it shouldn't work.
To arrive at a working version I've modified your code slightly:
function printCanvas(el) {
var dataUrl = document.getElementById(el).toDataURL(); //attempt to save base64 string to server using this var
var windowContent = '<!DOCTYPE html>';
windowContent += '<html>'
windowContent += '<head><title>Print canvas</title></head>';
windowContent += '<body>'
windowContent += '<img src="' + dataUrl + '">';
windowContent += '</body>';
windowContent += '</html>';
var printWin = window.open('','','width=340,height=260');
printWin.document.open();
printWin.document.write(windowContent);
printWin.document.close();
printWin.focus();
printWin.print();
printWin.close();
}
This works for me in the Firefox 4.0 nightly.

One addition to the accepted-best-answer: It doesnt work here with Chrome 17.0.942.0 winvista, because the print-preview-dlg is shown within the website itself and printWin.close() will close the dlg too.
So printWin.close() must be delayed or initiated by the user, but those are no good solutions.
It would be best, if chrome printdlg could have a callback, sth. one knows, printing is done, and can close the window. If this is possible is another question.

Related

Can't measure Clientwidth of Html-Image in Firefox

I am trying to place markers on points of interest (poi) on an Image.
These poi have been set in a different software and were stored in a database. The position is determined by their pixel position relative to the original Image. In my webapp the Images are scaled down thanks to panzoom.js (a plugin irrelevant to my question I think). I got the right formula to scale the markerposition, the only Problem is:
In firefox I'm unable to read the Images size in time (In Chrome that's not an Issue).
This is the Code
$(document).ready(function ()
{
var imagectrl = document.getElementById('<%= img.ClientID %>');
var hiddenfield = document.getElementById('<%= hf.ClientID %>');
if (hiddenfield.value == "")
{
var myWidth;
var myHeight;
myWidth = imagectrl.clientWidth;
myHeight = imagectrl.clientHeight;
hiddenfield.value = myWidth + ';' + myHeight;
__doPostBack();
}
});
If I do a postback manually (clicking a button that shows the Image in higher quality) the size gets written correctly.
I've also tried calling an identical function from Code behind when my X or Y are 0, but nothing worked.
What can i do to get the Images size when first loading the page?
Firefox has a different implementation on asynchronous operations like image loading than Chrome. I guess this could be the reason why in Chrome you can access the image right away with $(document).ready, but in Firefox the image source gets loaded after the document is ready - thus clientWidth and clientHeight will be undefined.
Solution: Define an onload event handler on your image and put your logic into that method:
$(document).ready(function ()
{
var imagectrl = document.getElementById('<%= img.ClientID %>');
var hiddenfield = document.getElementById('<%= hf.ClientID %>');
imagectrl.onload = function() {
if (hiddenfield.value == "")
{
var myWidth;
var myHeight;
myWidth = imagectrl.clientWidth;
myHeight = imagectrl.clientHeight;
hiddenfield.value = myWidth + ';' + myHeight;
__doPostBack();
}
}
});
I found a Solution:
No matter what I did, the Image itself can't be measured in time.
So i gave the Image the height of it's surrounding control via CSS and used
AddHandler dvGalerieFill.Load, AddressOf Me.measure_height
in the Page_Load method to react to the loading of the surrounding control.
In "measure_height" I called my Javascript function.
Through the height of the control (wich is the height of my image)
I can calculate the width of my image as height and width rescale with the same factor.

element.addEventListener not adding listener

So I have an array of strings that will turn into buttons,
//At start
function acceptSuggestion() {
console.log(`clicked`)
console.log(this.textContent);
}
//Else where
suggestions.couldBe.innerHTML = ``;
list.suggestions.forEach(function (item) {
let button = document.createElement(`button`);
button.textContent = item;
button.addEventListener(`click`, acceptSuggestion);//before append
button.style = `text-align:center; width:50%`;
suggestions.couldBe.appendChild(button);
button.addEventListener(`click`, acceptSuggestion);//after append
suggestions.couldBe.innerHTML+=`<br>`;
});
It creates the buttons fine
But clicking them does nothing.
Why is this? I know I have the event right cuz of this: https://www.w3schools.com/js/js_htmldom_eventlistener.asp
If it matters, I am using electron.js to create an webpage like application, and not a browser.
The reason this is happening is because of this line:
suggestions.couldBe.innerHTML+="<br>";
What is happening is your Browser element is generating all new fresh HTML each loop because of the += on the innerHTML.
Basically in pseudo code:
var temp = suggestions.couldBe.innerHTML + "<br>;
suggestions.couldBe.innerHTML = temp;
This causes your element that was added via the suggestions.couldBe.appendChild(button); to be converted to html, then re-parsed and all new elements created from HTML each iteration of the loop. Because your Button event handler was created in JS; it is lost when it recreated the button from the HTML version.
You want to do this either all via JS; not mixing it. So my suggestion would be to change this line:
suggestions.couldBe.innerHTML+="<br>";
to
suggestions.couldBe.appendChild(document.createElement('br'));

Copying text with a new line to <input type="text"/> not working in IE

My problem is the following:
I have an input, simple as that:
<input type="text"/>
And when I try to paste some text that contains a new line in it, all the text after the new line does not appear.
Now I know this type of input shouldn't support such behavior, and the best scenario is to use a textarea but that would be hardly achievable in the current project I am working on.
However, other browsers convert the new line to a space character and append the text after the new line so you eventually get the whole text in a single line. IE doesn't do that.
I have found the following solution to intercept paste event and I thought maybe I can use it to transform the string into a single-lined but it doesn't work in firefox. I can try a browser detection but I am afraid it can fail in many other scenarios as well.
Is there something else that I can do to make IE behave like other browsers and what are my best options?
I found this answer that might be the solution to your problem:
JavaScript get clipboard data on paste event (Cross browser)
It should work in IE6+, FF 22+, Chrome & Safari.
HTML
<input id='editableDiv' contenteditable='true' type="text"/>
JavaScript
function handlePaste (e) {
var clipboardData, pastedData;
// Stop data actually being pasted into input field
e.stopPropagation();
e.preventDefault();
// Get pasted data via clipboard API
clipboardData = e.clipboardData || window.clipboardData;
pastedData = clipboardData.getData('Text');
// Remove new line characters
alert(pastedData);
var res = pastedData.replace(/\r?\n|\r/g, );
}
document.getElementById('editableDiv').addEventListener('paste', handlePaste);
Hope this helps mate.
Thanks for your answer George K - yours was the base for my solution. I had a few remaining problems to get past:
addEventListener was giving me 'element not found'
concatenated value wasn't populating the field
So I ended up with these slight modifications to your javascript:
function handlePaste(e) {
var clipboardData, pastedData;
// Stop data actually being pasted into input field
e.stopPropagation();
e.preventDefault();
// Get pasted data via clipboard API
clipboardData = e.clipboardData || window.clipboardData;
pastedData = clipboardData.getData('Text');
// Remove new line characters
var res = pastedData.replace(/\r?\n|\r/g, ' ');
document.getElementById(e.target.id).value = res; // <- added this to populate value
}
// added this also - this fixed my 'element not found' error
window.addEventListener('load', function () {
document.getElementById('editableDiv').addEventListener('paste', handlePaste);
})
BTW, I am using an <asp:textbox> instead of an <input> element.
This works for me in both IE (11) and Chrome (83.x).

Text field not working on converting swf file to html5 using swiffy

I have following issues on conversion:
Text field not working on converting swf file to html5 using swiffy..
some animation are not working..
There is also sound problem in in some browser.
Is there any way to identify the textfield actions ?
I have googled but nothing works.. I think they are saying use js.
1) The key is to send the value to the swiffy object with this line in javascript:
function sendValue() {
myValue=inputFieldName.value;
stage.setFlashVars('myMessageFromTextfield='+myValue);
}
2) Then, inside the fla file, in actionscript2, get the value:
getValue = function() {
if(_level0.myMessageFromTextfield == "undefined" || _level0.myMessageFromTextfield == undefined) {
this.cat.animCat.myText.text = "";
} else {
this.cat.animCat.myText.text = _level0.myMessageFromTextfield;
returnButton._visible = true;
}
}
3) You need to constantly monitor when te data apears so use a setInterval:
myInterval = setInterval(this, "getValue", 100);
4) Now, to send the value back to html file, we use getURL with the data attached:
returnButton.onRelease = function() {
getURL("Javascript:showMessage('"+_level0.myMessageFromTextfield+" says the cat');");
}
5) And finally, again in javascript inside the html we execute the function with the parameter:
function showMessage(message) {
alert(message);
}
It works perfectly in IE, Firefox, Chrome, safari (ios).
So you now can send text in ipad or iphone.
I attached the source files in the next link:
https://onedrive.live.com/redir?resid=E64343A7ADE7D670!1401&authkey=!AO86aUEdyZRqQN4&ithint=file%2czip
Hope this help you (I've been trying to solve this during many months and until today i could).

Storing HTML5 canvas containing images

How do you store a canvas that contains images using the toDataURL method? Everything works fine for text and drawing, but I don't know how to handle images. Any help would be appreciated. Thanks
I have modified my question as follows:
This works when the image is pulled directly from a .png. However, when I call the Google Charts API, toDataURL doesn't work even though the image renders correctly on the canvas. Google Charts is returning a .png. Anyone have any ideas? Thanks.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript" charset="utf-8">
function test() {
var c = document.getElementById("drawing-canvas");
var cxt = c.getContext("2d");
// This doesn't work.
//var imgsrc = 'http://chart.apis.google.com/chart?cht=tx&chf=bg,s,ffffff&chco=000000&
chl=a';
// This works
var imgsrc = 'chart.png';
var img = new Image();
img.src = imgsrc;
cxt.drawImage(img,0,0);
}
function wr() {
var cc = document.getElementById("drawing-canvas");
var url = cc.toDataURL();
var newImg = document.createElement("img");
newImg.src = url;
document.body.appendChild(newImg);
}
</script>
</head>
<body onload = "test();">
<canvas id="drawing-canvas" width = "500px" height = "500px" style="background-color:
#ffffff; border: 2px solid #000000;">
Your browser does not support the canvas element.
</canvas>
<input type = "button" value = "go" onclick = "wr();">
</body>
</html>
First of all, your chart didn't even render on the canvas when I tested it. You need to wait for the image to load. Your chart.png image probably loads instantaneously since it's cached, but the one generated by Google Charts API isn't. This is what you should do:
var img = new Image();
img.onload = function()
{
cxt.drawImage(img,0,0);
}
img.src = imgsrc;
Aside from that, you must be getting a SECURITY_ERR in your browser's console. This is because the Canvas security model doesn't allow you to export images coming from an external URL. You should use a server-side language to save the Google Charts image to your server, then load it from there.
The HTML canvas element has a method called toDataURL, that will return a data URL image representing the canvas. You can check the documentation API on the MDN.
Specifically, it says about toDataURL:
toDataURL(in optional DOMString type, in any ...args)
returns DOMString
Returns a data: URL containing a representation of the image in the format specified by type (defaults to PNG).
If the height or width of the canvas is 0, "data:," representing the empty string, is returned.
If the type requested is not image/png, and the returned value starts with data:image/png, then the requested type is not supported.
Chrome supports the image/webp type.
If the requested type is image/jpeg or image/webp, then the second argument, if it is between 0.0 and 1.0, is treated as indicating image quality; if the second argument is anything else, the default value for image quality is used. Other arguments are ignored.
And provides and example on how to use it:
function test() {
var canvas = document.getElementById("canvas");
var url = canvas.toDataURL();
var newImg = document.createElement("img");
newImg.src = url;
document.body.appendChild(newImg);
}
In this example, we use the dataURL as the source attribute of an img element, but you can do whatever you want you it (like storing it somewhere, or sending it to the server with an ajax call).
Note that most of the methods involved in drawing on canvas are methods of drawing context (obtained by a call to getContext), while this method is one of the canvas element.