Using .setAttribute() to Resize SVG not Working - javascript

I have a page displaying a d3 graph. This page also supports PDF exporting, and I am using the pdfkit library with the SVG-to-PDFKit extension. The issue I am having is that the graph on the page is very large to fill the width of the page, but this makes it too large when generating it to PDF. I have spent a lot of time researching how to resize the SVG's content (not just the view the SVG resides in) and there doesn't seem to be an already created function in the SVG-to-PDFKit library.
I found an answer that makes sense, but only occasionally works whenever chrome tools is up:
How can I resize an SVG?
If there is a better solution, I would love to know. My main issue is that the graph has to be resized after it is generated on the page, so that it doesn't skew the graph on the page, but only alters the graph on the PDF.
The code I have that occasionally works is:
var chartSVG = document.getElementById('chartSVG');
chartSVG.setAttribute("style", "viewBox: 0 0 32 32;");
SVGtoPDF(doc, chartSVG, 20, 170);
Is there possibly another attribute out there that would be better for the scenario? And does the line of code look like it's written correctly? I don't understand why it will only work when Chrome tools are up. Thanks in advance.

You definitely can resize SVG with setAttribute as well as with style property or via css:
var red = document.getElementById('red');
red.setAttribute('height', '50');
var green = document.getElementById('green');
green.style.width = '100px';
#blue {width:60px}
<svg id="red" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="50" r="49" fill="red"/></svg>
<svg id="green" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="50" r="49" fill="green"/></svg>
<svg id="blue" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="50" r="49" fill="blue"/></svg>

Related

SVG convert <g> tag to an <image> tag containing base64 PNG URI (read more)

I got an interesting problem (I hope!)
I have noticed that there are two "types" of SVGs
First we have the conventional SVG file with and tags for example:
<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 841.89 1190.55" style="enable-background:new 0 0 841.89 1190.55;" xml:space="preserve">
<g id="Background">
<rect id="Color1" class="st3" width="840.94" height="1190.55"/>
<g id="Texture" class="st4">
<path class="st5" d="M843.67,410.13c-73.29 ...
Secondly we have embedded tags in the image, not sure what to call them, so I've just named them "fake SVG", an example:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="3718" height="4899" viewBox="0 0 3718 4899">
<image id="Lager_1" data-name="Lager 1" width="185.9" height="244.95000000000002" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUh ...
My question is: Is there is any smooth way to convert a conventional SVG into a "fake" SVG? (please tell me if they have a real name). Also keep in mind that I would like to keep the groupings so each <g> should convert to a <image> tag
My thoughts: I am thinking about loading the conventional SVG into a <canvas> tag, it seems to be able to understand the <g> groupings in the conventional SVG well and consistently, and from there, somehow, convert those groups individually into base64 PNG URI, and reconstruct it into a fake SVG, perhaps there should be some library out there that can help out, does anyone have any ideas?
I'm not sure if this will exactly answer what you are trying to do, but you can do this:
<image id="something" href='data:image/svg+xml;utf8,<svg version="1.1" xmlns="http://www.w3.org/2000/svg" .../>' />
Where you can just embed the original SVG as a string in the href when the encoding is set to data:image/svg+xml;utf8.
This will render the SVG in an <image> tag, but not in Base64 (I could not get this working, but there may be a way).
Source: https://css-tricks.com/probably-dont-base64-svg/
It is possible to convert an inline SVG with tags in the DOM to an image data-url. You just need to turn it into one like this:
imageTag.src = 'data:image/svg+xml,' + window.escape(svgTag.outerHTML);
The imageTag version can not have external links embedded in the SVG. It also needs width and height attributes on the SVG tag otherwise it will not show in some browsers. You could also draw this image to a canvas to rasterize the image, but as the comment mentioned that would only make it uglier if scaled.
If you want to convert it to a SVG file you should add this as a first line and then add the outerHTML of the svgTag.
<?xml version="1.0" encoding="UTF-8"?>
You can save the file with the .svg extension

move image using java script and html css

I want to move a image in a path using js and html.
is that doable?
please check the image to get better idea about my question. are there any example codes or libraries? so I can study and edit to match into my case.
There are multiple ways to approach this problem.
Modify html image css styling via javascript.
add css styling via javascript.
styling to move/rotate : transform: translate(20px,10px) rotate(0.5turn);
change styling using pure css animations #keyframes more here
Display stuff on <canvas> element via javascript more here
Animated svg, or svg with css animation.
Inline svg animated via javascript or css.
I am for now just going to demonstrate the svg approach.
SVG approach (no javascript)
My preferred approach would be to create a svg containing multiple images, and then animate it. The bellow example is just using circle objects, but images should work too using <image href="">.
<svg viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<path id="movepath" d="M 5 5 C 10 10, 20 10, 25 5" stroke="#aaa" stroke-width="1" fill="none" />
<circle cx=5 cy=5 r=2 fill="#aaa"/>
<circle cx=25 cy=5 r=2 fill="#aaa"/>
<circle r=1.5 fill="#000">
<animateMotion dur="1s" repeatCount="indefinite">
<mpath xlink:href="#movepath"/>
</animateMotion>
</circle>
</svg>
I don't know if I had understood your question, but I try to answer you.
If I should to do this, "move rocket from earth to sun" I would do it like this:
I'll create 3 img.
img rocket;
img earth;
img sun;
With CSS I will set the Rocket img movement from img earth to sun. Html is not request.

SVG rect not showing up in firefox but works on chrome

I am drawing a simple two rectangle svg as follows:
<svg width="72px" height="72px" viewBox="0 0 72 72" xmlns="http://www.w3.org/2000/svg">
<rect stroke-dashoffset="0" x="2.4px" y="2.4px"></rect>
<rect ng-class="$ctrl.expiryClass"
x="2.4px" y="2.4px"
stroke-dasharray={{$ctrl.dashlength}}
stroke-dashoffset={{$ctrl.offset}}></rect>
</svg>
This works well in chrome and looks like this:
However, the svg is not showing up in FireFox and I am only seeing the purple 2h box.
Any idea whats going on?
I expect you are setting the rectangle's width and height using CSS. Correct?
If so, that's an SVG 2 thing that currently only works in Chrome. You'll need to use regular width and height attributes if you want this to be cross-browser compatible.
<rect stroke-dashoffset="0" x="2.4px" y="2.4px" width="100px" height="100px"/>

Overflow SVG does not register clicks on OSX/iOS

I have a small SVG canvas in my application which houses a button to click. Upon clicking that button, the small circle does some flashy work and opens up to an appropriate sized bubble to fit all the data. This data is just a list of data with custom bullets off to the left; some of this text is clickable (bound to click events) and causes other functions to be fired off. My problem is that the SVG canvas never changes in size. It's really only big enough to contain the original circle that the user clicks on. The rest of SVG elements that make up this control flow outside the bounds of the SVG canvas, but is all viewable due to the SVG having its overflow set to visible. Everything works fine in all browsers, but things change when I open up the application in an iPad or on a Mac (regardless of browser). It seems the overflow pieces of my SVG are completely invisible to the browser. Any click event that fires fine on the overflowed SVG elements on Window's browsers are completely invisible on OSX/iOS browsers (it seems like any click actually falls through to whatever is behind the overflowed SVG). At first I thought it was an issue with the click binding, but after searching and playing around with it, I think OSX/iOS just doesn't handle overflowed SVG very well.
To explain in its simplest form what's going on in my application, I have a very simple JSFiddle here: https://jsfiddle.net/yno8daka/
HTML:
<svg style="overflow: visible !important" class="canvas" width='70px' height='70px' xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
<circle id="circle1" stroke="black" fill="black" stroke-width="1" cx="10" cy="10" r="10"></circle>
<circle id="circle2" stroke="black" fill="black" stroke-width="1" cx="110" cy="110" r="10"></circle>
</svg>
Javascript:
$('#circle1').click(function() {
alert('yeah');
})
$('#circle2').click(function() {
alert('yeah2');
})
Circle1 is in the bounds of the SVG canvas, while circle2 is not. On Windows browsers, you will be able to click on both circles without any issue. On OSX/iOS browsers, the click event will fire for circle1, but not for circle2.
Does anyone know how to get this to work?

SVG line animation not working in IE

I am using a carousel that animates the stroke-dasharray but it doesnt work in IE.
my SVG:
<svg class="facts__svgs" viewBox="-10 -10 220 220" data-facts-stoke-svg="">
<path d="M200,100 C200,44.771525 155.228475,0 100,0 C44.771525,0 0,44.771525 0,100 C0,155.228475 44.771525,200 100,200 C155.228475,200 200,155.228475 200,100 Z" stroke-dashoffset="651"></path>
</svg>
My JS that changes the stroke:
function calculateDashArray(percentage) {
return (dashOffset * 2) - (segmentOfDashOffset * percentage) - 20;
}
function animateFactsSVG(percentage) {
elPath.style.strokeDasharray = calculateDashArray(percentage);
}
In everything apart from IE this works. In IE the dasharray style is applied but the svg does not change.
I have taken your example and placed it in Internet Explorer and it didn't work. Then I started playing with the various properties to see how I could get to your desired effect. The only way I could make the change in the dasharray reflect graphically was to reset the 'd' attribute: elPath.setAttribute('d',elPath.getAttribute('d')); which made the dasharray show as required, but destroyed the animation. Another way to make the changes appear was to add a second comma separated parameter to dasharray, like '1008.58,100%', but it wouldn't create the desired effect either.
I have to conclude that Internet Explorer doesn't deal well with one value stroke-dasharray and you should probably look for another solution.
I actually made it work with a circle instead of a path like this:
<svg xmlns="http://www.w3.org/2000/svg" style="width:100%;height:100%" >
<circle cx="100" cy="100" r="100" stroke="green" stroke-width="1" fill="none" style="stroke-dasharray:228,628;transition: all .6s ease;" ></circle>
</svg>
<script>
var el=document.getElementsByTagName('circle')[0];
var circumference=2*Math.PI*(+el.getAttribute('r'));
function animatePercentage(per) {
el.style.strokeDasharray=(per/100*circumference)+','+((1-per/100)*circumference);
}
setInterval(function() {
animatePercentage(70);
},2000);
</script>
No animation, though. The value changes instantly on IE. Apparently this doesn't work in Internet Explorer, only Edge (see SVG animation is not working on IE11)
Updated the code and saved it in a CodePen here: http://codepen.io/anon/pen/wGPwYq

Categories