svg to canvas image in jspdf - I Get a black content - javascript
I've used jspdf to convert the svg image to canvas and then to pdf
The plugins I've used are
<script type="text/javascript" src="assets/js/jquery.js"></script>
<script type="text/javascript" src="assets/js/jspdf.js"></script>
<script type="text/javascript" src="assets/js/html2canvas.js"></script>
<script type="text/javascript" src="assets/js/html2canvas.svg.js"></script>
<script type="text/javascript" src="assets/js/canvg.js"></script>
My HTML code for the svg is
genpdf
<svg class="bullet" width="416" height="50">
<g transform="translate(75,5)">
<rect class="range s0" width="301" height="25" x="0"/>
<rect class="range s1" width="250.83333333333334" height="25" x="0"/>
<rect class="range s2" width="200.66666666666666" height="25" x="0"/>
<rect class="measure s0" width="230.76666666666668" height="8.333333333333334" x="0" y="8.333333333333334"/>
<rect class="measure s1" width="210.7" height="8.333333333333334" x="0" y="8.333333333333334"/>
<g class="tick" transform="translate(0,0)" style="opacity: 1;">
<line y1="25" y2="29.166666666666668"/>
<text text-anchor="middle" dy="1em" y="29.166666666666668">0</text>
</g>
<g class="tick" transform="translate(50.16666793823242,0)" style="opacity: 1;">
<line y1="25" y2="29.166666666666668"/>
<text text-anchor="middle" dy="1em" y="29.166666666666668">5</text>
</g>
<g class="tick" transform="translate(100.33333587646484,0)" style="opacity: 1;">
<line y1="25" y2="29.166666666666668"/>
<text text-anchor="middle" dy="1em" y="29.166666666666668">10</text>
</g>
<g class="tick" transform="translate(150.5,0)" style="opacity: 1;">
<line y1="25" y2="29.166666666666668"/>
<text text-anchor="middle" dy="1em" y="29.166666666666668">15</text>
</g>
<g class="tick" transform="translate(200.6666717529297,0)" style="opacity: 1;">
<line y1="25" y2="29.166666666666668"/>
<text text-anchor="middle" dy="1em" y="29.166666666666668">20</text>
</g>
<g class="tick" transform="translate(250.8333282470703,0)" style="opacity: 1;">
<line y1="25" y2="29.166666666666668"/>
<text text-anchor="middle" dy="1em" y="29.166666666666668">25</text>
</g>
<g class="tick" transform="translate(301,0)" style="opacity: 1;">
<line y1="25" y2="29.166666666666668"/>
<text text-anchor="middle" dy="1em" y="29.166666666666668">30</text>
</g>
<g x="200" y="100" style="text-anchor: end;" transform="translate(-6,12.5)">
<text class="title">NOVORA</text>
</g>
</g>
</svg>
I'm unable to get the exact image that is required as an output when I generate it to pdf.
I'm converting the svg to canvas but still I'm unable to get the desired output. Instead of the exact image I get a black content inside that.
The css code for the above one is
.bullet {
font: 10 px sans-serif;
}
.bullet.marker {
stroke: #000;
stroke-width: 2px;
}
.bullet .tick line {
stroke: # 666;
stroke-width: .5px;
}
.bullet.range.s0 {
fill: #eee;
}
.bullet.range.s1 {
fill: #ddd;
}
.bullet.range.s2 {
fill: #ccc;
}
.bullet.measure.s0 {
fill: steelblue;
}
.bullet.measure.s1 {
fill: #fff;
}
.bullet.measure.s2 {
fill: steelblue;
}
.bullet.measure.s3 {
fill: lightsteelblue;
}
.bullet.title {
font-size: 10px;
font-weight: bold;
}
.bullet.subtitle {
fill: #999;
}
The javascript that helps me rendering the data is
function genPdf(){
var svgElements = $("#page-content-wrapper").find('svg');
//replace all svgs with a temp canvas
svgElements.each(function() {
var canvas, xml;
canvas = document.createElement("canvas");
canvas.className = "screenShotTempCanvas";
// canvas.getContext("3d");
//convert SVG into a XML string
xml = (new XMLSerializer()).serializeToString(this);
// Removing the name space as IE throws an error
xml = xml.replace(/xmlns=\"http:\/\/www\.w3\.org\/2000\/svg\"/, '');
//draw the SVG onto a canvas
canvg(canvas, xml);
$(canvas).insertAfter(this);
$(this).addClass('tempHide');
$(this).hide();
});
html2canvas(document.getElementById('page-content-wrapper'), {
onrendered: function (canvas){
var img = canvas.toDataURL("image/jpeg",1.0);
var doc = new jsPDF();
doc.addImage(img, 'JPEG' , 10, 10);
doc.save('test.pdf');
}
});
setTimeout(function(){
$("#page-content-wrapper").find('.screenShotTempCanvas').remove();
$("#page-content-wrapper").find('.tempHide').show().removeClass('tempHide');
$("#page-content-wrapper").find('.bullet').show();
},2000);
}
function getStyle(el, styleProp) {
var camelize = function(str) {
return str.replace(/\-(\w)/g, function(str, letter) {
return letter.toUpperCase();
});
};
if (el.currentStyle) {
return el.currentStyle[camelize(styleProp)];
} else if (document.defaultView && document.defaultView.getComputedStyle) {
return document.defaultView.getComputedStyle(el, null)
.getPropertyValue(styleProp);
} else {
return el.style[camelize(styleProp)];
}
}
Please help me out in this. Thanks
Related
how to make svg curve at one end
im using svg for circular progress bar , i want to make one end curve not the both end . how is this possible ? how can i implement one end curve in svg? svg { height: 80vh; margin: 10vh auto; border: 1px solid red; display: block; transform: rotate(-90deg); } svg circle { stroke-width: 10; fill: transparent; } #outer { stroke: lightgrey; } #inner { stroke: blue; animation: value 2.5s linear forwards; stroke-linecap: round; } #keyframes value { 0% { stroke-dasharray: 0 100; } 100% { stroke-dasharray: 90 100; } } <svg viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <circle id="outer" cx="50" cy="50" r="40" /> <circle id="inner" pathLength="100" cx="50" cy="50" r="40" /> </svg>
The easiest way would be to mask the starting point of the blue circle. For this you will need a <mask> like so: <mask id="m"> <rect width="100" height="100" fill="white"/> <rect x="85" y="40" width="10" height="10" /> </mask> Please observe that the first rectangle is white and it covers the whole chart. (Everything under a white pixel will be visible). The smaller rectangle is black and covers the starting point of the blue circle. Everything under a black pixel will be invisible. svg { height: 80vh; margin: 10vh auto; border: 1px solid red; display: block; transform: rotate(-90deg); } svg circle { stroke-width: 10; fill: transparent; } #outer { stroke: lightgrey; } #inner { stroke: blue; animation: value 2.5s linear forwards; stroke-linecap: round; } #keyframes value { 0% { stroke-dasharray: 0 100; } 100% { stroke-dasharray: 90 100; } } <svg viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <mask id="m"> <rect width="100" height="100" fill="white"/> <rect x="85" y="40" width="10" height="10" /> </mask> <circle id="outer" cx="50" cy="50" r="40" /> <circle id="inner" pathLength="100" cx="50" cy="50" r="40" mask="url(#m)" /> </svg>
Try this code: svg { height: 80vh; margin: 10vh auto; border: 1px solid red; display: block; transform: rotate(-90deg); border-top-right-radius: 20px; } svg circle { stroke-width: 10; fill: transparent; } #outer { stroke: lightgrey; } #inner { stroke: blue; animation: value 2.5s linear forwards; stroke-linecap: round; } #keyframes value { 0% { stroke-dasharray: 0 100; } 100% { stroke-dasharray: 90 100; } } <svg viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <circle id="outer" cx="50" cy="50" r="40" /> <circle id="inner" pathLength="100" cx="50" cy="50" r="40" /> </svg>
I came up with an alternative solution than enxaneta suggested. The problem with using a mask is that when your value goes over 96% or so, the circle isn't completely filled and the mask is revealed. Instead, you can set a rounded progress line on top of another progress line that has flat endcaps. By rotating the rounded progress line by roughly 5 degrees, the flat end is revealed. Here's how to do that in React Native with react-native-svg: const radius = 60; let myPercentage = 40; const circleCircumference = 2 * Math.PI * radius; const valueOffset = circleCircumference - (circleCircumference * myPercentage * 0.98) / 100; <Svg height={radius * 2 + 30} width={radius * 2 + 30}> <G rotation={-90} originX={radius + 15} originY={radius + 15}> // Background gray circle <Circle cx="50%" cy="50%" r={radius} stroke="rgb(60, 60, 60)" fill="transparent" strokeWidth="10" strokeDasharray={circleCircumference} strokeLinecap="butt" /> // Background progress circle with flat ends <Circle cx="50%" cy="50%" r={radius} stroke={"rgb(0, 51, 204)"} fill="transparent" strokeWidth="10" strokeDasharray={circleCircumference} strokeDashoffset={valueOffset} strokeLinecap="butt" /> // Progress circle with round ends rotated by 5 degrees <Circle cx="50%" cy="50%" r={radius} stroke={rgb(0, 51, 204)} fill="transparent" rotation={5} originX={radius + 15} originY={radius + 15} strokeWidth="10" strokeDasharray={circleCircumference} strokeDashoffset={valueOffset} strokeLinecap="round" /> </G> </Svg>
Isolate section of SVG when mouse is hovered
I am attempting to build an interactive map from scratch. I have an SVG of the map of Canada that has separate layers for each province. I'd like to highlight a specific province/territory when the mouse is hovered over it. I have tried using a function that gets the live update of the mouse coordinates, but I am unsure as to how to figure out which section of the image it is on. I am unsure as to if this is the best method of doing it. Through some of my research, I have found a method of gathering the pointer coordinates: let x = 0; let y = 0; function showCoords() { x = event.clientX; y = event.clientY; } And I call it around the SVG using: <div onmousemove="showCoords()"> ...SVG HERE </div> I can select the different layers inside of the SVG, but the question is if I can find a way of checking which layer my mouse is currently over. Thank you! Edit: I have reached a solution that accomplishes my goal, but I am unsure as to if it is efficient. Using CSS, I fill each group upon hover: #canada { fill: hsl(0, 0%, 29%); } #canada g { transition: .3s; } #canada g:hover { fill: hsl(189, 88%, 59%); } I am also using the onClick option on each group to pull up their dialogue.
Maybe something like this? Just keep "data-name" attribute on each <g> inside svg code. let x = 0; let y = 0; let svgCountry = document.querySelector("#states svg"); let svgStates = svgCountry.querySelectorAll("[data-name]"); let resContainer = document.getElementById("state-hovered-is"); // init tooltip function showCoords(event) { let x = event.clientX; let y = event.clientY; resContainer.setAttribute("style", "left:" + (x + 15) + "px;" + "top:" + (y - 50) + "px;"); } // close tooltip function clearCoor() { resContainer.innerHTML = ""; } // clear everything function clearAllOn() { svgStates.forEach(function(el) { el.classList.remove("hover"); resContainer.innerHTML = ""; console.clear(); }); } // display current state in div function displayState(el) { var res = el.getAttribute("data-name"); el.classList.add("hover"); resContainer.innerHTML = "<p>You're at" + " " + res + "</p>"; console.log(res); } svgStates.forEach(function(el) { // mouse events el.addEventListener("mouseenter", function() { displayState(el); }); el.addEventListener("mouseleave", function() { clearAllOn(); }); // touch events el.addEventListener("touchstart", function() { clearAllOn(); displayState(el); }); }); body { background-color: #fff; font-family: Arial, Helvetica, sans-serif; color: #333; } g.hover { opacity: 0.5; } #states { margin: 0 auto; width: 600px; max-width: 100%; position: relative; } #state-hovered-is { text-align: center; min-height: 50px; position: fixed; pointer-events: none; background-color: rgba(0, 0, 0, 0.76); border-radius: 6px; } #state-hovered-is p { color: #fff; margin: 0; padding: 15px; width: 180px; } <div id="states" onmousemove="showCoords(event)" onmouseout="clearCoor()"> <!-- State name here --> <div id="state-hovered-is"></div> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 961.38 830.7"> <defs> <style> .cls-1 { fill: #fff;} .cls-2 {fill: #b8c4e6;} .cls-3 {fill: #ce8080;} .cls-4 {fill: #e99bd2;} .cls-5 {fill: #acac90;} .cls-6 {fill: #e6c0c0;} .cls-7 {fill: #4d6ac1;} .cls-8 {fill: #c9e6b8;} .cls-9 {fill: #f3f3db;} .cls-10 {fill: #cece71;} .cls-11 {fill: #7188ce;} .cls-12 {fill: #daa0a0;} .cls-13 {fill: #91916b;} .cls-14 {fill: #dada94;} .cls-15 {fill: #916b86;} </style> </defs> <title>Canada</title> <g id="Layer_1"> <ellipse class="cls-1" cx="480.69" cy="415.35" rx="679.8" ry="587.39" /> <path class="cls-1" d="M539.84,220.75c-2.45,5-6.57,8.18-10.72,11.7l2-9.56C534.53,224.17,537,221.84,539.84,220.75Z" transform="translate(-0.06 -0.26)" /> <path class="cls-1" d="M53,543.56c-1.09,2.13-2.18,4.23-3.52,6.84l-.51-10.68.56-.25Z" transform="translate(-0.06 -0.26)" /> <path class="cls-1" d="M771.19,558.14c-.32-2.18-.77-4.36-.89-6.56a3.15,3.15,0,0,1,1.31-2.05,1.76,1.76,0,0,1,1.64.49,4.19,4.19,0,0,1,.17,2.5c-.48,1.84-1.18,3.62-1.79,5.43Z" transform="translate(-0.06 -0.26)" /> <path class="cls-1" d="M40.77,527.77l-7-8.41.35-.18A76,76,0,0,1,40.4,524c.77.71.87,2.14,1.27,3.25Z" transform="translate(-0.06 -0.26)" /> <path class="cls-1" d="M493.56,95.47l3.41,6L485.7,105a30.91,30.91,0,0,1,2.81-2.42C491.7,100.51,493.64,100.2,493.56,95.47Z" transform="translate(-0.06 -0.26)" /> </g> <g id="Yukon" data-name="Yukon"> <path class="cls-3" d="M174.12,185.61c.91,1.61.88,2.8-.63,4.31-4.21,4.21-8.16,8.68-12.2,13.07-.34.38-.78,1-.72,1.39.58,3.9-2,6.08-4.31,8.53a6.48,6.48,0,0,0-1.84,3.83,5.33,5.33,0,0,0,1.79,3.5c1.85,1.68,4.07,2.94,6,4.53,3.45,2.83,3.47,5.7.33,9.15-2.19,2.39-4.41,4.77-6.37,7.34-1.76,2.3-1.12,4.05,1.42,5.49,1.4.81,2.66,1.88,4.19,3-2.18,1.51-3.35,2.81-2.33,5.22.45,1.05,0,2.31-1.73,2.4a17.09,17.09,0,0,0-3.62.83c-4.36,1.21-5.4,4.72-5.53,8.56a57.14,57.14,0,0,0,.5,10c.23,1.57,1.5,3,2.39,4.63-2.26,2.84-2.38,6.32-1.6,10.12a46.41,46.41,0,0,1,.52,7.56,1.6,1.6,0,0,1-.82,1.17c-2.55,1.24-3,3.61-3.48,6a9.38,9.38,0,0,1-1.27,3.48,10.68,10.68,0,0,0-1.7,8.87,2.39,2.39,0,0,1-.44,1.48c-.6,1-1.32,2-2,2.93-1.42,2.18-1.43,4,.77,5.24,3.32,1.83,3.1,4.7,2.57,7.41-.72,3.66-.45,6.87,2,9.78,1.47,1.77,1.39,3.3-.37,4.95a7.72,7.72,0,0,0-1.45,3.08c-.28.81-.27,1.71-.5,2.53-1.52,5.43,1,6.26,4.74,7.61,1.41.5,2.57,1.66,3.93,2.34a26.86,26.86,0,0,0,4.63,1.87c1.72.5,3.51.73,5.24,1.06.05.25.15.5.1.53-3,2.14-3,5.28-2.81,8.48.09,2,0,4,0,6.25A575.11,575.11,0,0,1,48.14,298a7.87,7.87,0,0,1,.58-.75c3.2-3.33,3.13-5.09-.71-7.55a38.29,38.29,0,0,0-6.52-3.12c-2.14-.86-3.05-5-1.32-6.73q13.23-13,26.49-26c6.81-6.67,13.65-13.31,20.46-20q13.26-13,26.5-26,10.56-10.35,21.15-20.68,11.07-10.83,22.16-21.66c1.92-1.87,3.87-3.74,6-5.43a2.44,2.44,0,0,1,2.34-.08,12.63,12.63,0,0,1,4.51,7.68c.95,5.52,2.44,10.95,3.73,16.42A5.64,5.64,0,0,0,174.12,185.61Z" transform="translate(-0.06 -0.26)" /> </g> <g id="British_Columiba" data-name="British Columiba"> <g> <path class="cls-4" d="M190.26,405.28c.27.14.53.31,1.06.62-1,1.88-2,3.69-2.9,5.53-5.64,11.14-11.24,22.3-16.9,33.43-4.43,8.73-8.92,17.42-13.38,26.13l-19.37,37.93c-.21.42-.68.84-.65,1.24.17,2.7,0,5.24-2.52,6.95.78,2,1.25,4.14,2.45,5.8.82,1.15,1.83,1.89,1.89,3.54s.46,3.46,2.33,4.55c2.39,1.41,1.92,4.19,2.3,6.41.31,1.81-.17,3.77-.35,5.66s.8,3.35,2.22,4.62a2.72,2.72,0,0,1,.81,2.17,5.54,5.54,0,0,0,1.49,5.42c.88,1,1.18,2.44,1.69,3.71.82,2,1.6,4,2.38,6,1,2.51,2,5,2.9,7.55.32.88.14,2.18.72,2.67,3.23,2.74,2.75,6.63,3,10.1a15.41,15.41,0,0,0,3.74,8.9c3.16,3.57,2.61,7,1.68,10.73-.83,3.31-1.92,6.57-3,9.84s-.35,6.2,1.21,9.74c-5.31-2.27-10.13-4.28-14.9-6.38-10.53-4.64-21.08-9.23-31.54-14-8.14-3.72-16.25-7.52-24.19-11.65-8.81-4.6-17.41-9.61-26.09-14.47a2,2,0,0,1-1-1.12,65.21,65.21,0,0,1-1-7.47c-.16-3.6-1.05-5-4.37-5.94,0-1.19,0-2.34,0-3.5a3.82,3.82,0,0,0-2.71-3.76c-1.17-.5-3.27-.93-3.32-1.53a9.88,9.88,0,0,1,.91-5.44c3.08-5.49,3.08-7.06-1-11.44-2.29-2.47-4.78-4.79-6.82-7.46a9.16,9.16,0,0,1-1.44-4.76c-.2-2.61-1.08-4.69-3.49-5.72-3.27-1.39-4.67-4.2-5.48-7.23a5.27,5.27,0,0,1,1-4.36,5.48,5.48,0,0,0,1.59-5.2c-.48-3.26,1.93-4.89,4.78-5.55a19.58,19.58,0,0,0,3.83-1c2.43-1.12,2.65-3.06.7-4.87a7.78,7.78,0,0,1-2-9.22c1.46-3.4,1.33-5.05-1-6.15-1.19-.56-2.78-.29-4.19-.39-.47,0-.93-.05-1.65-.09,1.67-3,3-5.78,6.86-6.28a4.12,4.12,0,0,0,3.2-2.73c.72-1.68,2.44-2.95,3.74-4.38,1.14-1.23,1.82-2.81.52-4a5.8,5.8,0,0,0-4-1A30.06,30.06,0,0,0,44.62,459c-1.84-6.08-.47-11.9,1.17-17.65A3.74,3.74,0,0,1,48,439.05c7.2-1.55,10.53-7,13.68-12.85a30.35,30.35,0,0,1,3.83-4.91c1.69-2,2.72-4.14,1.8-6.84s-1.71-5.51-2.66-8.23A52.51,52.51,0,0,0,62,399.51c-1.34-2.62-.9-5.19-.39-7.83q2.15-11.08,4.26-22.15c1.08-5.61,2.21-11.21,3.21-16.84a9.48,9.48,0,0,0-.36-2.74c-.16-1.32-.33-2.65-.44-4-.14-1.58-.18-3.17-.36-4.74a11.92,11.92,0,0,1,1.16-7.34c1.92-3.53,1.66-7.9-.48-9.87l1.06-1.21c7.65,6.68,15.29,13.38,23.2,19.74,8.69,7,17.59,13.76,26.79,20,13.27,9,26.71,17.88,40.42,26.24C169.85,394.8,180.18,399.83,190.26,405.28Z" transform="translate(-0.06 -0.26)" /> <path class="cls-4" d="M67.71,323.4c-4.2-2.13-8.84-4.21-13.43-1.55-2.84,1.64-5.18.87-8.06.13,2.21-2.52,1.9-5.53,1.88-8.49s0-6.08,0-9.44a8.14,8.14,0,0,1,1.68.85c5.42,4.9,10.73,9.92,16.24,14.72l3.65,3.2L68.61,324A4,4,0,0,0,67.71,323.4Z" transform="translate(-0.06 -0.26)" /> <path class="cls-1" d="M52.34,580.17c.15,1.23-.68,2.57-1.25,4.47-2.23-1.77-4.17-2.89-5.53-4.5a75.63,75.63,0,0,1-5.85-8.23,3.32,3.32,0,0,1-.2-2.75c2.52-5.09,2.08-6.95-3.06-9.61-1.82-.94-2.5-1.94-2.32-4,.32-3.52.35-4.15-4.79-9.94,2-2.92,1.55-3.82-.24-7-1.32-2.35-1.69-5.31-2.07-8.06-.29-2.13-.63-4-2.58-5.25a2.26,2.26,0,0,1-.79-1.75c.24-3.45.6-6.89.93-10.33,2-.08,2.8,1.11,3.33,2.71A29.72,29.72,0,0,0,36,529,45.65,45.65,0,0,1,43,536.54c1.16,1.66,1.53,4.06,1.7,6.17a84.4,84.4,0,0,1,0,10.06c-.17,4.12,1.42,7.63,3.38,11.07a18,18,0,0,1,2.24,4.56A109.17,109.17,0,0,1,52.34,580.17Z" transform="translate(-0.06 -0.26)" /> <path class="cls-1" d="M17.57,426.81l6.17,8.48C16.39,441.78,11.81,449.73,11,459.7,10.41,448.18,12.87,437.39,17.57,426.81Z" transform="translate(-0.06 -0.26)" /> </g> </g> <g id="Alberta" data-name="Alberta"> <path class="cls-5" d="M194.56,407.63c27.17,14.46,55.83,25.35,85,35.57L214.1,643.67c-10.88-4-21.29-7.82-31.68-11.68-3.52-1.3-6.91-3-10.51-4s-5.08-3.41-6.18-6.74c-1.26-3.84-.43-7.18,1.12-10.59A26.88,26.88,0,0,0,169.13,597a4.52,4.52,0,0,0-1-2.58c-4.16-4.42-5.32-9.88-5.71-15.66-.07-1-.13-2.32-.75-2.88-2.84-2.56-2.45-6.26-3.65-9.38-.64-1.69-1.62-3.26-2.29-4.95-.84-2.14-1.52-4.35-2.27-6.53-.05-.15-.06-.35-.17-.44a6.25,6.25,0,0,1-2-7.07c.17-.6-1.07-1.75-1.85-2.43a2.33,2.33,0,0,1-1.08-2.43,28.92,28.92,0,0,0-.52-7.52c-.36-2.17,0-4.65-2.15-6.28-1.47-1.09-1.92-2.71-2.35-4.49-.35-1.45-1.6-2.69-2.47-4-.51-.77-1.07-1.51-1.72-2.42,2.55-1.41,2.87-3.59,2.69-6a5,5,0,0,1,.5-2.5q5-9.88,10-19.7c6.78-13.11,13.63-26.19,20.37-39.32,3.84-7.45,7.51-15,11.31-22.47C187.5,421.2,191,414.48,194.56,407.63Z" transform="translate(-0.06 -0.26)" /> </g> </svg> </div> Here's how the full map looks: https://jsfiddle.net/darkosss/7umphzwn/
Can't get hamburger menu to animate on click
I targeted the SVG rect using :nth-chid(1), 2 and 3 and made a -> that I'm trying to trigger on click. Don't know what I'm doing wrong here. Any Help would be great thank you! (function() { var burger; buger = document.getElementById('burger'); burger.addEventListener('click', function() { console.log('you cliked the burger'); return burger.classList.toggle('st0-active'); }); }).call(this); body { max-width: 900px; margin: 0 auto; } .st0-active:nth-child(1) { -webkit-transform: rotate(27deg) translate(23px, -51px); transform: rotate(27deg) translate(23px, -51px); fill: #000; } .st0-active:nth-child(2) { fill: #000; } .st0-active:nth-child(3) { -webkit-transform: rotate(-21deg) translate(-48px, 15px); transform: rotate(-21deg) translate(-48px, 15px); fill: #000; } <body> <svg class="mo-icon__svg" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 200 200" style="enable-background:new 0 0 200 200;" xml:space="preserve" id="burger"> <g id="icon_x5F_hamburger"> <rect x="0.11206" y="46.3329" class="st0" width="200" height="8"/> <rect x="0.11206" y="96.22083" class="st0" width="200" height="8"/> <rect x="0.11206" y="146.10876" class="st0" width="200" height="8"/> </g> </svg> </body> Here is a picture of my designed end goal Which is the reason I'm using CSS Transforms and targeting the rect using nth-child Here is a link to the codepen that I'm currently working on enter link description here
(function() { var burger; burger = document.getElementById('burger'); burger.addEventListener('click', function() { console.log('you cliked the burger'); return burger.classList.toggle('st0-active'); }); }).call(this); body { max-width: 900px; margin: 0 auto; } #burger > g > rect{ transition: transform 1s; } .st0-active > g > rect:nth-child(1) { -webkit-transform: rotate(27deg) translate(23px, -51px); transform: rotate(27deg) translate(23px, -51px); fill: #000; } .st0-active > g > rect:nth-child(2) { fill: #000; } .st0-active > g > rect:nth-child(3) { -webkit-transform: rotate(-21deg) translate(-48px, 15px); transform: rotate(-21deg) translate(-48px, 15px); fill: #000; } <body> <svg class="mo-icon__svg" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 200 200" style="enable-background:new 0 0 200 200;" xml:space="preserve" id="burger"> <g id="icon_x5F_hamburger"> <rect x="0.11206" y="46.3329" class="st0" width="200" height="8"/> <rect x="0.11206" y="96.22083" class="st0" width="200" height="8"/> <rect x="0.11206" y="146.10876" class="st0" width="200" height="8"/> </g> </svg> </body> Try to add this code. #burger{ transition: transform 1s; } Additionally CSS3 transitions allows you to change property values smoothly (from one value to another), over a given duration.
Save SVG as PNG using javascript Unknown DOM exception
I am trying to convert an SVG to PNG through browser using javascript I've been following the answer on this question Save inline SVG as JPEG/PNG/SVG It works for the given XML in that answer Unfortunately, I got Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. when trying to convert my SVG. Here's the snippet to my code. Can anybody tell me why it's not working? var btn = document.querySelector('button'); var svg = document.querySelector('svg'); var canvas = document.querySelector('canvas'); function triggerDownload (imgURI) { var evt = new MouseEvent('click', { view: window, bubbles: false, cancelable: true }); var a = document.createElement('a'); a.setAttribute('download', 'MY_COOL_IMAGE.png'); a.setAttribute('href', imgURI); a.setAttribute('target', '_blank'); a.dispatchEvent(evt); } btn.addEventListener('click', function () { var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var data = (new XMLSerializer()).serializeToString(svg); var DOMURL = window.URL || window.webkitURL || window; var img = new Image(); img.crossOrigin = 'anonymous' var svgBlob = new Blob([data], {type: 'image/svg+xml;charset=utf-8'}); var url = DOMURL.createObjectURL(svgBlob); img.onload = function () { ctx.drawImage(img, 0, 0); DOMURL.revokeObjectURL(url); var imgURI = canvas .toDataURL('image/png') .replace('image/png', 'image/octet-stream'); triggerDownload(imgURI); }; img.src = url; }); <button>svg to png</button> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="161px" height="91px" version="1.1" style="background-color: rgb(255, 255, 255);"><defs/><g transform="translate(0.5,0.5)"><rect x="0" y="0" width="160" height="90" fill="#ffffff" stroke="#000000" pointer-events="none"/><path d="M 0 26 L 0 0 L 160 0 L 160 26 Z" fill="#dae8fc" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(48.5,7.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="63" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; white-space: nowrap; font-weight: bold; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Classname</div></div></foreignObject><text x="32" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica" font-weight="bold">Classname</text></switch></g><g transform="translate(5.5,32.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="62" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; overflow: hidden; max-height: 22px; max-width: 148px; width: 63px; white-space: normal; word-wrap: normal;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">+ field: type</div></div></foreignObject><text x="31" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">+ field: type</text></switch></g><path d="M 0 56 L 160 56" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(5.5,66.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="111" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; overflow: hidden; max-height: 22px; max-width: 148px; width: 112px; white-space: normal; word-wrap: normal;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">+ method(type): type</div></div></foreignObject><text x="56" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">+ method(type): type</text></switch></g></g></svg> <canvas id="canvas"></canvas>
You have issues in your SVG's foreignObject on removing this will solve your issue, var btn = document.querySelector('button'); var svg = document.querySelector('svg'); var canvas = document.querySelector('canvas'); function triggerDownload (imgURI) { var evt = new MouseEvent('click', { view: window, bubbles: false, cancelable: true }); var a = document.createElement('a'); a.setAttribute('download', 'MY_COOL_IMAGE.png'); a.setAttribute('href', imgURI); a.setAttribute('target', '_blank'); a.dispatchEvent(evt); } btn.addEventListener('click', function () { var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var data = (new XMLSerializer()).serializeToString(svg); var DOMURL = window.URL || window.webkitURL || window; var img = new Image(); img.crossOrigin = 'anonymous' var svgBlob = new Blob([data], {type: 'image/svg+xml;charset=utf-8'}); var url = DOMURL.createObjectURL(svgBlob); img.onload = function () { ctx.drawImage(img, 0, 0); DOMURL.revokeObjectURL(url); var imgURI = canvas .toDataURL('image/png') .replace('image/png', 'image/octet-stream'); triggerDownload(imgURI); }; img.src = url; }); <button>svg to png</button> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="161px" height="91px" version="1.1" style="background-color: rgb(255, 255, 255);"> <defs/> <g transform="translate(0.5,0.5)"> <rect x="0" y="0" width="160" height="90" fill="#ffffff" stroke="#000000" pointer-events="none"/> <path d="M 0 26 L 0 0 L 160 0 L 160 26 Z" fill="#dae8fc" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/> <g transform="translate(48.5,7.5)"> <switch> <text x="32" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica" font-weight="bold">Classname</text> </switch> </g> <g transform="translate(5.5,32.5)"> <switch> <text x="31" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">+ field: type</text> </switch> </g> <path d="M 0 56 L 160 56" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(5.5,66.5)"> <switch> <text x="56" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">+ method(type): type</text> </switch> </g> </g> </svg> <canvas id="canvas"></canvas> You can also try Canvas2Image plugin
Save result from html2canvas library
I used html2canvas library to get screenshot of the html content using jvascript. That is what html2canvas library does. What I tried to do is to get a screenshot of the output from html2canvas library and save it in any image format(say jpeg). But was not able to achieve it. Here is what I've tried so far: HTML <svg width="500" height="350"> <circle id="orange-circle" r="30" cx="50" cy="50" fill="orange" /> <rect id="blue-rectangle" width="50" height="50" x="25" y="200" fill="#0099cc"></rect> <animate xlink:href="#orange-circle" attributeName="cx" from="50" to="450" dur="5s" begin="0s" repeatCount="2" fill="freeze" id="circ-anim"/> <animate xlink:href="#blue-rectangle" attributeName="x" from="50" to="425" dur="5s" begin="0s" repeatCount="indefinite" fill="freeze" id="rect-anim"/> </svg> CSS svg { border: 3px solid #eee; display: block; margin: 1em auto; } p { color: #aaa; text-align: center; margin: 2em 0; } JS(with html2canvas lib) <script type="text/javascript" src="html2canvas.js"></script> <script type="text/javascript"> html2canvas(document.body).then(function(canvas) { document.body.appendChild(canvas); }); </script>
The only thing you need to do is wrapping the function by a window.onload Here are the example window.onload = function() { $("#convert").click(function(){ html2canvas($('.svgElement')).then(function(canvas) { var imgLink = canvas.toDataURL("image/png"); var img = document.createElement('img'); img.src = imgLink; document.body.appendChild(img); }); }); } https://jsfiddle.net/t1fw7pgy/1/ In your code, the function is called before render the element, therefore it will just give you a blank canvas page.