I've created an SVG using Raphael that I want to capture and convert to PNG and then display in the open window. I have looked at some other stack overflow answers like this one. I implemented ollieg's answer to that question. Here's an example of what I'm doing:
<html>
<head>
<script src="NBA_test/lib/raphael-min.js"></script>
</head>
<body>
<div id="canvas"></div><br>
<script language="JavaScript">
var test=Raphael("canvas",50,50);
var rect=test.rect(0,0,50,50);
rect.attr({fill: '#fff000'})
window.onload = function() {
var canvas = document.getElementById("canvas");
window.location = canvas.toDataURL("image/png");
}
</script>
</body>
</html>
This should draw a yellow rectangle and output it as a png. The console confirms that the SVG is being captured correctly in the canvas var. However, the toDataURL line throws an error: "TypeError: 'null' is not an object (evaluating 'canvas.toDataURL')" I know my example is a little different in the sense that I don't have an actual canvas tag in my html, just the div that is going to get the canvas. Given that the canvas is being captured correctly, however, I don't understand why the second line throws that error.
Using canvg per the suggestion above and raphael.export.js, I have solved my problem (kind of). My minimal example now works as below:
<html>
<head>
<script src="lib/raphael-min.js"></script>
<script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/rgbcolor.js"></script>
<script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/StackBlur.js"></script>
<script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/canvg.js"></script>
<script src="lib/raphael.export.js"></script>
</head>
<body>
<div id="raph_canvas"></div><br>
<canvas id="html_canvas" width="50px" height="50px"></canvas>
<script language="JavaScript">
var test=Raphael("raph_canvas",50,50);
var rect=test.rect(0,0,50,50);
rect.attr({fill: '#fff000', 'fill-opacity':1, 'stroke-width':1})
window.onload = function() {
var canvas_svg = test.toSVG();
canvg('html_canvas',canvas_svg);
var canvas_html = document.getElementById("html_canvas");
window.location = canvas_html.toDataURL("image/png");
}
</script>
</body>
</html>
The problem now is that my actual app, which is a little more complex, doesn't work, but I will maybe post a separate question about that.
Related
I'm using regular JS (I know it isn't the best, but I'm a beginner)
So I'm writing code for a canvas project. However when using the getContext() function the JS console says
Uncaught TypeError: canvas.getContext is not a function
at master.js:4
I've looked around and found that nothing has fixed my problem.
var canvas = document.getElementsByClassName('myCanvas');
console.log(canvas);
var context = canvas.getContext('2d');
console.log(context);
The HTML is this:
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="master.js" charset="utf-8"></script>
<link rel="stylesheet" href="master.css">
</head>
<body>
<canvas class="myCanvas">Your browser doesn't support HTML canvas</canvas>
</body>
</html>
Does anyone know what I am doing wrong?
getElementsByClassName returns an array of elements. Thus, it does not have the method you are looking for. Try the following:
var canvas = document.getElementsByClassName('myCanvas')[0];
console.log(canvas);
var context = canvas.getContext('2d');
console.log(context);
Your code is also stored in the HTML head, so your canvas element will not be found. Either put your <script> tag in the HTML <body> tag or set a function inside document.onload as follows:
document.onload = function() {
var canvas = document.getElementsByClassName('myCanvas')[0];
console.log(canvas);
var context = canvas.getContext('2d');
console.log(context);
}
I am trying to convert a div containing some img tags to a png. After some search, it looks like the best way is to use the html2canvas library.
The problem is that it is not working for me and I don't understand why.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="lib/css/bootstrap.min.css">
<script src="lib/js/Blob.js"></script>
<script src="lib/js/canvas-to-blob.min.js"></script>
<script src="lib/js/FileSaver.js"></script>
<script src="lib/js/html2canvas.js"></script>
<script src="lib/js/jquery.min.js"></script>
<script src="lib/js/underscore-min.js"></script>
<title>Tests Only</title>
</head>
<body>
<div id="navigationButtons">
</div>
<div id="sourceScreen" style="width:200px">
<img id="lol" src="tier-icons/base_icons/bronze.png" />
</div>
<div id="targetScreen">
</div>
<script = "text/javascript">
jQuery('#navigationButtons').append('<button type="button" id="makeScreenshot">Screenshot</button>');
jQuery('#makeScreenshot').click(makeScreenshot);
function makeScreenshot(){
html2canvas(jQuery('#sourceScreen'), {
onrendered: function(canvas) {
jQuery('#targetScreen').html(canvas);
}
});
}
</script>
</body>
</html>
Here is a jsFiddle of my code:
https://jsfiddle.net/2vv79ehy/1/
I am trying to get it work with 1 img tag first on this example, the goal is to display the canvas under the real image.
I know there is a problem with cross-domain resources with this library but when I do the test with my real code, the image is hosted on my computer.
Does anyone know how to do it or if there is another way (would be great if it could bypass cross-domain problems too)?
Your JSFiddle works, except for the cross-domain problem. I've played around trying to find a quick hack around it, but the best I could come up with is just drawing onto the canvas that you're given in your onrendered event and I haven't really played with positioning and the z-order would be impossible to implement this way, but maybe this edit to your makeScreenshot function helps you find a solution that works for you:
function makeScreenshot(){
html2canvas(jQuery('#sourceScreen'), {
onrendered: function(canvas) {
var img = jQuery("#cat");
var ctx = canvas.getContext("2d");
var originalPosition = { left: 0, top: 18 };
ctx.drawImage(img[0],originalPosition.left,originalPosition.top);
jQuery('#targetScreen').html(canvas);
}
});
}
I have been trying to export my Dygraph images using the code:
<html>
<head>
<script type="text/javascript"
src="dygraph-combined.js"></script>
<script type="text/javascript"
src="dygraph-extra.js"></script>
</head>
<body>
<div id="graphdiv2"
style="width:500px; height:300px;"></div>
<script type="text/javascript">
g2 = new Dygraph(
document.getElementById("graphdiv2"),
"temp.csv", // path to CSV file
{} // options
);
var img = document.getElementById('demoimg')
Dygraph.Export.asPNG(g2, demoimg);
</script>
</body>
</html>
The actual image on my aspx-page is OK, but when I right-click on the image and try to view it, it's bland. I have tried to change the parameters in var img and Dygraph.Export lines but heven't been successful. So, what am I missing?
The image space for the PNG image has not been created. If you add <img id="demoimg" style="width:500px; height:300px;"/>
after graphdiv2, the exported image will appear in that image space. When you right click on that, you will be able to view the image.
My canvas wont show in my browser.
I'm guessing the reason is because of some newbie jquery mistakes.
The codes below are in two separate folders, Game.html and game.js
Game.html:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<canvas id="gameCanvas">
</canvas>
<script src="Scripts/jquery-2.0.3.js" type="text/javascript"> </script>
<script src="Scripts/game.js" type="text/javascript"> </script>
</body>
</html>
game.js:
var canvasWidth = 800;
var canvasHeight = 600;
$('#gameCanvas').attr('width', canvasWidth);
$('#gameCanvas').attr('height', canvasHeight);
var canvas = $('#gameCanvas')[0].getContext('2d');
canvas.strokeRect(0, 0, canvasWidth, canvasHeight);
Here is tested your code is working perfectly.
Look in your Scripts folder content files jquery-2.0.3.js and game.js.
the only possibility is error path, look at this.
And what browser are you testing? html5 canvas is then only works in some new browsers.
checked here if your browser does have canvas support
Code Equals
working example here
Are you sure your reference to the script file is correct. If both html and script are in two different folders, then the reference might need to be:
<script src="../Scripts/jquery-2.0.3.js" type="text/javascript"> </script>
<script src="../Scripts/game.js" type="text/javascript"> </script>
I have a simple HTML5 Snake game that uses canvas that I want to package as a Chrome App. Here is my normal HTML file:
<!DOCTYPE html>
<html>
<head>
<title>Snake</title>
<link rel="stylesheet" href="snake.css">
</head>
<body>
<canvas id="canvas" width="700" height="700"></canvas>
<script type="text/javascript" src="food.js"></script>
<script type="text/javascript" src="snake.js"></script>
<script type="text/javascript" src="point.js"></script>
<script type="text/javascript" src="game.js"></script>
<script type="text/javascript">
window.onload = function() {
var canvas = document.getElementById("canvas"),
game = new Game(canvas, new Snake(canvas), new Food(canvas));
game.init();
game.run();
}
</script>
</body>
</html>
However the script in the HTML is not allowed. So I removed it and placed it main.js which creates the window. I provide a callback that is the same as window.onload above because my understanding is that this is the chrome app equivalent:
chrome.app.runtime.onLaunched.addListener(function() {
"use strict";
chrome.app.window.create('snake.html', {
bounds: {
width: 800,
height: 800
}
}, function() {
var canvas = document.getElementById("canvas"),
game = new Game(canvas, new Snake(canvas), new Food(canvas));
game.init();
game.run();
});
});
This runs after the DOM appears to have loaded but document.getElementById always returns null. Looking at the document in the developer tools it looks like only the scripts are loaded even though I can see the canvas in the app window (I have a border around the canvas). Can anyone tell me what is going on? Where is the appropriate place to access the DOM from when window.onload doesn't work?
main.js is running on the background / event page and is not in the same context as the newly created window's DOM. You can interact with that context as documented on the create callback, but it's not how I recommend solving this.
Instead, from your main.js simply create the window, and from the HTML file load script code that executes directly.
window.html:
<!DOCTYPE html>
<html>
<body>
<canvas id="canvas" width="700" height="700"></canvas>
<script ...</script>
<script type="text/javascript" src="window.js"></script>
window.js:
var canvas = document.getElementById("canvas"),
game = new Game(canvas, new Snake(canvas), new Food(canvas));
game.init();
game.run();