Convert jQuery SVG to image - javascript

I am generating SVG object using jQuery SVG plug-in. The problem is how can I convert it into image in my script.
My script is following:
<html>
<head>
<script type="text/javascript" src="jquery-latest.min.js"></script>
<script type="text/javascript" src="jquery.svg.js"></script>
<script type="text/javascript">
$(function(){
$("#draw").click(function(){
$('#svg_container').svg();
svg = $('#svg_container').svg('get');
svg.clear(true);
svg.circle(200, 220, 150, {fill: "red", stroke: "blue", strokeWidth: 5});
alert(svg.toSVG()); //this prints svg source of the generated image, i.e. circle
});
});
</script>
</head>
<body>
<div id="svg_container" style="position: absolute; left: 100px; top: 100px; width: 400px; height: 400px; border: thin solid #4297D7;"></div>
<button id="draw">Draw</button>
</body>
</html>
I have tried out this and this but without success.
Could you please show me how to convert this svg into any type of image?
Thanks in advance.
UPDATE
The problem is solved and I have posted the solution as an answer, check it here.

This seams to be very hard to do.
I found this project that attempts to do this:
http://www.svgopen.org/2010/papers/62-From_SVG_to_Canvas_and_Back/index.html
I also found one project that tried to build a SVG renderer for Canvas but it was far from complete.
They did use a solution to go by the server and have the SVG rendered to PNG there, that might be the only really working solution right now.

I have finally solved the problem of converting SVG to image file. Here is the solution, if anybody is interested in:
<html>
<head>
<script type="text/javascript" src="jquery-latest.min.js"></script>
<script type="text/javascript" src="jquery.svg.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/canvg.js"></script>
<script type="text/javascript">
$(function(){
function q(k){
var qs = window.location.search.substring(1);
var t = qs.split("&");
for (i=0;i<t.length;i++) {
kv = t[i].split("=");
if (kv[0] == k) return unescape(kv[1]).replace('+',' ');
}
return null;
}
var context;
function bodyonload() {
if (typeof(FlashCanvas) != 'undefined') context = document.getElementById('canvas').getContext;
var qUrl = q('url'); if (qUrl != null && qUrl != '') { r(); canvg('canvas', qUrl); }
var qSvg = q('svg'); if (qSvg != null && qSvg != '') { r(); canvg('canvas', qSvg); }
}
function render() {
var c = document.getElementById('canvas');
c.width = 400;
c.height = 500;
if (context) c.getContext = context;
canvg(c, document.getElementById('svg').value);
var svg_content = c.toDataURL();
$.ajax({
type:"POST",
url:"svg.php",
data: ({
svg_content: svg_content
}),
timeout: 30000, //30 sec.
});
}
function r() {
var c = document.getElementById('canvas');
c.width = '1000'; //change it to the width of your image
c.height = '600'; //change it to the height of your image
if (context) c.getContext = context;
}
$("#save").click(function(){
render();
});
$("#draw").click(function(){
$('#svg_container').svg();
svg = $('#svg_container').svg('get');
svg.clear(true);
svg.circle(200, 220, 150, {fill: "red", stroke: "blue", strokeWidth: 5});
$("#svg").val(svg.toSVG());
});
});
</script>
</head>
<body>
<textarea id="svg" rows="5" cols="50" style="visibility: hidden;"></textarea><br />
<canvas id="canvas" width="1000px" height="600px"></canvas>
<div id="svg_container" style="position: absolute; left: 100px; top: 100px; width: 400px; height: 400px; border: thin solid #4297D7;"></div>
<button id="draw" style="position: absolute; top:400px; left: 500px;">Draw</button>
<button id="save" style="position: absolute; top:400px; left: 550px;">Save</button>
</body>
</html>
The content of svg.php is following:
<?php
if (isset($_POST['svg_content'])){
$imageData=$_POST['svg_content'];
$filteredData=substr($imageData, strpos($imageData, ",")+1);
$unencodedData=base64_decode($filteredData);
$fp = fopen('test.png', 'wb' );
fwrite( $fp, $unencodedData);
fclose( $fp );
}
?>
You can download jQuery library (jquery-latest.min.js) from jQuery official web site and jQuery SVG library from here .
Hope this will help to many of you who are looking toward converting SVG to image right from your program.
Best,
Bakhtiyor

Related

Onchange color picker not changing canvas background color

I'm trying to change the background of my canvas element for a school project based on user input from the color-picker. However I can't seem to get it to work. I've checked over the code and everything seems to be properly selected. Any ideas on why?
docolor() {
var myCanvas = document.querySelector("#myCanvas");
var colorinput = document.querySelector("#clr");
var color = colorinput.value;
myCanvas.style.backgroundColor = color;
}
<head>
<title> canvas practice </title>
</head>
<body>
<canvas id = "myCanvas">
</canvas>
<br>
<input type = "color" value = "#001A57" id = "clr" onchange = "docolor()">
</body>
</html>
-
#clr {
display: inline-block;
}
#myCanvas {
height: 150px;
width: 300px;
border: 2px solid;
}
docolor isn't properly defined, so it never runs. Declare your function like this and it should work:
function docolor() {
var myCanvas = document.querySelector("#myCanvas");
var colorinput = document.querySelector("#clr");
var color = colorinput.value;
myCanvas.style.backgroundColor = color;
}
Let me know if it's still not working. Here's a link to a working codepen if you want to see everything working together. Goodluck with your project!
It looks you forgot the function declaretion.
<html>
<head>
<title> canvas practice </title>
<style>
#clr {
display: inline-block;
}
#myCanvas {
height: 150px;
width: 300px;
border: 2px solid;
}
</style>
</head>
<body>
<canvas id="myCanvas">
</canvas>
<br>
<input type="color" value="#001A57" id="clr" onchange="docolor()">
</body>
<script>
function docolor() {
var myCanvas = document.querySelector("#myCanvas");
var colorinput = document.querySelector("#clr");
var color = colorinput.value;
myCanvas.style.backgroundColor = color;
}
</script>
</html>

Pie chart legend not showing - Uncaught TypeError: Cannot set property 'innerHTML' of null

I have to show legends for a pie chart. I have been following below link.
http://jsfiddle.net/vrwjfg9z/
But it does not work for me in below code.
<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8">
<title>ChartJS - Pie Chart</title>
<link href = "https://code.jquery.com/ui/1.10.4/themes/ui-lightness/jquery-ui.css" rel = "stylesheet">
<script src = "https://code.jquery.com/jquery-1.10.2.js"></script>
<script src = "https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<script src="jquery-2.1.4.min.js"></script>
<script src="Chart.js"></script>
<script src="veeva-library.js" type="text/javascript"></script>
<link rel="stylesheet" href="styles.css">
<script src="veevaMessages.js" type="text/javascript"></script>
<script src="jquery-ui-1.11.4/external/jquery/jquery.js"></script>
<script src="jquery-ui-1.11.4/jquery-ui.min.js"></script>
<script src="MyInsightsLibrary.js"></script>
</head>
<body onload="init()">
<span style="float: left;margin-left:2em"> <b>Date Range: </b>
<input type="text" id="datepicker" > <b>to </b>
<input type="text" id="datepicker2"> </span><div id = "Alert" style="float:left;margin-left:2em"> Please select a valid Date Range!</div>
<div style="width: 100%; height: 100%;">
<canvas id="mycanvas" style="width: 100%; height: auto;"></canvas> <!--width="300" height="300">-->
</div>
<div id="js-legend" style="display: inline-block;width: 12px; height: 12px; margin-right: 5px;"></div> <!-- class="chart-legend" -->
</body>
<script>
var startDate;
var endDate;
var start;
var end;
$(function() {
$("#datepicker").datepicker({
onSelect: function() {
startDate = $(this).datepicker('getDate');
start = formatDate(startDate);
if( start!=null && end!=null && end>=start)
{document.getElementById('Alert').style.visibility = 'hidden';
init();
}
else {
document.getElementById('Alert').style.visibility = 'visible'; //Will show
}
}
});
$("#datepicker2").datepicker({
onSelect: function() {
endDate = $(this).datepicker('getDate');
end = formatDate(endDate);
alert('skn here s' + startDate);
alert('skn here e' + endDate);
if( start!=null && end!=null && end>=start)
{document.getElementById('Alert').style.visibility = 'hidden';
init();
}
else {
document.getElementById('Alert').style.visibility = 'visible'; //Will show
}
}
});
});
function init(){
var dynamicColors = function() {
var r = Math.floor(Math.random() * 255);
var g = Math.floor(Math.random() * 255);
var b = Math.floor(Math.random() * 255);
return "rgb(" + r + "," + g + "," + b + ")";
}
var data = [
{
value: 270,
color: dynamicColors(), //"cornflowerblue",
highlight: dynamicColors(), //"lightskyblue",
label: "Corn Flower Blue"
},
{
value: 50,
color: dynamicColors(), //"lightgreen",
highlight: dynamicColors(), //"yellowgreen",
label: "Lightgreen"
},
{
value: 40,
color: dynamicColors(), //"orange",
highlight: dynamicColors(),//"darkorange",
label: "Orange"
}
];
var options = {
segmentShowStroke: false,
animateRotate: true,
animateScale: false,
percentageInnerCutout: 50,
tooltipTemplate: "<%= value %>n"
};
var ctx = document.getElementById("mycanvas").getContext("2d");
//draw
var mycanvas = new Chart(ctx).Pie(data,options);
document.getElementById('js-legend').innerHTML = mycanvas.generateLegend();
}
</script>
</html>
I am getting below error in console. I do understand from google search that it needs somewhere to put document.ready or some onload function which I am not sure of.
Error
Uncaught TypeError: Cannot set property 'innerHTML' of null
at init & at onload
Can someone please let me know where I go wrong?
Please find the screenshot how the legend shows for me without rectangular color boxes.
enter image description here
jQuery is not finding your div #js_legend because you did not write it properly in your HTML. It should be this:
<div id="js-legend" style="display: inline-block;width: 12px; height: 12px; margin-right: 5px;"></div>
Instead of this:
</div id="js-legend" style="display: inline-block;width: 12px; height: 12px; margin-right: 5px;"></div>
Something else I noticed is, why are you using the traditional JavaScript document.getElementsById() when you're using jQuery? You ought to use the $ operator, like you're supposed to. I noticed this line that you have.
document.getElementById('js-legend').innerHTML = mycanvas.generateLegend();
This is bad practice in jQuery, and it screws up the flow of your script, it might even make things malfunction.
$("#js-legend").html(mycanvas.generateLegend());
To change the visibility property of your elements, you will want to use the jQuery .css() function. Also, have a look at this question. You should use the following syntax, as opposed to invoking .style.visibility the way you would in traditional JavaScript.
$("#Alert").css("visibility", "hidden");

add image on canvas on button click using fabric.js

I am trying to add images on button click on canvas. . By default there is 1 image on canvas. Images are getting added on button click, But all images are erased when i click on canvas. Only the background image remains constant.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="http://code.jquery.com/jquery-1.10.1.js"></script>
<script src="fabric.js"></script>
</script>
<script>
function fun(){
var canvas = window.canvas = new fabric.Canvas('c');
fabric.Image.fromURL('compress/a.jpg', function(img){
canvas.add(img.scale(0.1).set({ left: 150, top: 200, angle: 20 }));
});
$(canvas.wrapperEl).on('mousewheel', function(e) {
var target = canvas.findTarget(e);
var delta = e.originalEvent.wheelDelta / 120;
if (target) {
target.scaleX += delta;
target.scaleY += delta;
// constrain
if (target.scaleX < 0.1) {
target.scaleX = 0.1;
target.scaleY = 0.1;
}
// constrain
if (target.scaleX > 10) {
target.scaleX = 10;
target.scaleY = 10;
}
target.setCoords();
canvas.renderAll();
return false;
}
});
}
function add()
{
window.canvas = new fabric.Canvas('c');
window.canvas.getObjects();
fabric.Image.fromURL('compress/b.jpg', function(img){
window.canvas.add(img.scale(0.1).set({ left: 150, top: 200, angle: 20 }));
window.canvas.selection = true;
window.canvas.renderAll();
window.canvas.calcOffset();
});
}
</script>
<style>
canvas {
border: 1px solid #999;
}
</style>
</head>
<body onload=fun()>
<div id="test" align="center" style="display: block">
<canvas id="c" width="600" height="600"></canvas>
</div>
<button id="but" onclick="add()">add images</button>
</body>
</html>
Please help me with this code
try using canvas.clear() before adding

Change background color if width is bigger

I want to change the background color if width is bigger than 100.
This is my code but it doesn't work.
Thanks for any help!
<html>
<head>
<style type="text/css">
div#mydiv {
width: 200px;
height: 100px;
background-color: red;
}
</style>
<script language="JavaScript">
function () {
var mydiv = document.getElementById("mydiv");
var curr_width = parseInt(mydiv.style.width);
if (curr_width > 100) {
mydiv.style.BackgroundColor = "blue";
}
}
</script>
</head>
<body>
<div id="mydiv" style=""></div>
</body>
</html>
Change
parseInt(mydiv.style.width);
mydiv.style.BackgroundColor = "blue";
To
mydiv.offsetWidth
mydiv.style.backgroundColor = "blue";
use
var curr_width = mydiv.offsetWidth;
instead
var curr_width = parseInt(mydiv.style.width);
Change:
var curr_width = parseInt(mydiv.style.width);
mydiv.style.BackgroundColor = "blue";
to:
var curr_width = mydiv.offsetWidth;
mydiv.style.backgroundColor = "blue";
I have set up a fiddle here.
Also notice I took it out of the function because it looked like it wasn't being called anywhere. You should also move the script out of the head to the bottom of the body tag or use window.onload.
UPDATE
Another fiddle with everything together
I assume this is a duplicate question.
Anyway, your intialization of curr_width need not include parseInt.
parseInt is for converting a value to integer type and here you doesnt require it.
Your code can be re-written as
<html>
<head>
<style type="text/css">
div#mydiv {
width: 200px;
height: 100px;
background-color: red;
}
</style>
<script language="JavaScript">
function () {
var mydiv = document.getElementById("mydiv");
var curr_width = mydiv.offsetWidth;
if (curr_width > 100) {
mydiv.style.BackgroundColor = "blue";
}
}
</script>
</head>
<body>
<div id="mydiv" style=""></div>
</body>
</html>
Assuming your function to be called onload. Here's the code:
<html>
<head>
<style type="text/css">
#mydiv {
width: 200px;
height: 100px;
background-color: red;
}
</style>
<script language="JavaScript">
function load(){
var mydiv = parseInt(document.getElementById("mydiv").offsetWidth);
if (mydiv > 100) {
document.getElementById("mydiv").style.backgroundColor = "blue";
}
}
</script>
</head>
<body onload="load();">
<div id="mydiv" style=""></div>
</body>
</html>
Changes:
Use offsetWidth to get the width of the div.
Use backgroundColor instead of BackgroundColor.
To get a proper computed width, you need to use the (not enough used) method getBoundingClientRect() https://developer.mozilla.org/en-US/docs/Web/API/element.getBoundingClientRect
Latest browsers have .width property, otherwise you just need to take right - left to get it.
Some comments:
- language="JavaScript" is useless. Like type="text/javascript". It's the default behavior. Seriously.
- you need to execute your code after the div has been created. So using onload or just by calling the code after in the html (like in my example)
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
#mydiv {
width: 200px;
height: 100px;
background-color: red;
}
</style>
</head>
<body>
<div id="mydiv"></div>
<script>
/* run the code after the creation of #mydiv */
var mydiv = document.getElementById("mydiv");
var clientRect = mydiv.getBoundingClientRect()
var curr_width = clientRect.width || (clientRect.right - clientRect.left);
if (curr_width > 100) {
mydiv.style.backgroundColor = "blue";
}
</script>
</body>
</html>
Here is a working example http://jsbin.com/xapet/1/edit
Warning: to do this properly it's recommended that you execute this code each time the browser is resized.
Maybe you can take a look to the "element queries" thing, that will be a nice workaround according to media queries limitations.
https://encrypted.google.com/search?hl=en&q=element%20queries%20css

Javascript, displaying a transparent image.

<!DOCTYPE html>
<html>
<head>
<style>
#container {
width: 320px;
height: 480px;
border: 1px solid red;
}
</style>
</head>
<body>
<div style="position: relative;" id="container">
<canvas id="myCanvas" width="320" height="480"
style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas>
<canvas id="plane" width="320" height="480"
style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas>
<canvas id="canvas2" width="100" height="100"
style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
</div>
<img id="scream" src="http://4.bp.blogspot.com/-BrJHwoqM2qg/Uq94Il8t-1I/AAAAAAAAD7s/vyFLZUgMkdA/s1600/Plane.png" alt="The Scream" width="0" height="0">
<script>
var c=document.getElementById("myCanvas");
var c2=document.getElementById("canvas2");
var c3=document.getElementById("plane");
var plane;
var ground;
var score1 = "1"
var score = score1;
var increase = 6;
var delay = 40;
var scorez;
start();
function start(){
backgrounds();
planeDraw();
var scorez = setInterval(scoring, delay);
}
function backgrounds(){
var ctx=c.getContext("2d");
var my_gradient=ctx.createLinearGradient(0,0,0, 280);
my_gradient.addColorStop(0,"white");
my_gradient.addColorStop(1,"blue");
ctx.fillStyle=my_gradient;
ctx.fillRect(0,0,320,480);
ground = c.getContext("2d");
ctx.fillStyle="black";
ctx.fillRect(0,450 , 320 ,30);
}
function scoring(){
scores();
score2();
}
function scores(){
score -= 3-(3+increase);
}
function score2(){
//var canvas = document.getElementById('canvas2');
var context = c2.getContext('2d');
context.clearRect(0, 0, c2.width, c2.height);
var w = c2.width;
c2.width = 1;
c2.width = w;
var text=c2.getContext("2d");
text.font="20px Georgia";
text.fillText(score ,15,20);
}
function hit(){
}
function loes(){
clearInterval(scorez);
}
function planeDraw(){
plane = c3.getContext('2d');
var img = new Image();
img.src = "http://4.bp.blogspot.com/-BrJHwoqM2qg/Uq94Il8t-1I/AAAAAAAAD7s/vyFLZUgMkdA/s1600/Plane.png"; //transparent png
plane.drawImage(img, 0, 0, 320, 100);
}
</script>
<!--
http://4.bp.blogspot.com/-BrJHwoqM2qg/Uq94Il8t-1I/AAAAAAAAD7s/vyFLZUgMkdA/s1600/Plane.png
--!>
</body>
</html>
All the code seems to be working fine, the only issue I am finding is the image of the plane is not printing. Could some one please tell me what I am doing wrong. Thank you.
When I changed the planeDraw function to create a rectangle it worked perfectly. As well as this the code worked in JSFiddle, when it was isolated.
You are drawing the image before it has loaded.
Load the plane image once, and draw it after its onload event has fired.
If you can, consider embedding the image as a data: URL, as this will remove the need for waiting for the image to load, however keep in mind that it makes your code bigger!
You have to wait for the image to load before drawing it.
Try:
img.onload = function()
{
plane.drawImage(img, 0, 0, 320, 100);
};
img.src = "http://4.bp.blogspot.com/-BrJHwoqM2qg/Uq94Il8t-1I/AAAAAAAAD7s/vyFLZUgMkdA/s1600/Plane.png"; //transparent png
It's best to define the onload function before setting the src attribute - depending on the browser, if the image file is in your cache, the onload event may fire as soon as the src is set (before you have a chance to define onload).

Categories

Resources