SVG—bbox to large for group from nested svg - svg

I am building an svg-based application which uses one, »root« svg as Viewport/Canvas. Within this one I load one SVG which sets up all the graphics, that one is quiet large (~18.000px * 800px, 4MB). I am trying to create a parallax effect, which is working for primitive graphic element like <rect>. But it does not work for <g> elements.
It is difficult to post relevant code, since the graphic has grown very big, so below you can see an example for the basic setup:
<svg class="root" width="1000" height="800">
<g class="container" transform="matrix(1,0,0,1,<dx>,<dy>)">
<svg width="16000" height="800">
<!-- a lot of graphics here -->
<g>
<!-- the group with all the graphics for the parallax -->
<g class="parallax" transform="matrix(<crazy inkscape values here>);">
</g>
</g>
<!-- a lot of graphics here -->
</svg>
</g>
</svg>
All in all I need to access the width of the whole group to calculate the parallax offset, therefore I am using:
<g>.getBBox();
what returns a value whose width is about 2.5 times too big. I replaced the group with a <Rect> in the same dimensions at the same place in the DOM and everything works alright.
What could cause the returned bounding bounding box grow, probably <gradient>-, <symbol>-, or <use>- elements ?
I appreciate any Idea.
btw: The conversion of coordinates is already taken into account here, at least as far a possible. I tested this in FF and Chromium — the same thing everywhere…
Thanks in ahead!
Edit
I guess I found the reason for the error. This time it wasn't mine. The Graphics were delivered by an Illustrator, using Illustrator and in the original file I found several empty path. They spanned the bbox to 0/0, even if no real point was there...

I don't think the following is the full solution, but let's start here for discussion purposes.
The following is an inline svg with a width=400 height=400, but contains a <g> element with some elements that exceed those sizes. I want to fit the elements in the <g> to my 400x400 inline svg.
Try this:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body style='font-family:arial'>
<center>
<div id="svgDiv" style='background-color:lightgreen;width:400px;height:400px;'>
<svg id="mySVG" width="400" height="400" xmlns="http://www.w3.org/2000/svg" >
<g id="myG">
<circle cx=1000 cy=500 r=300 fill="red" />
<rect x=300 y=200 width=500 height=300 fill="blue" />
</g>
</svg>
</div>
<button onClick=fitG() >fit G</button>
<br />SVG Source:<br />
<textarea id=svgSourceValue style='font-size:110%;font-family:lucida console;width:90%;height:200px'></textarea>
<br />Javascript:<br />
<textarea id=jsValue style='border-radius:26px;font-size:110%;font-weight:bold;color:midnightblue;padding:16px;background-color:beige;border-width:0px;font-size:100%;font-family:lucida console;width:90%;height:400px'></textarea>
</center>
<div id='browserDiv' style='padding:5px;position:absolute;top:5px;left:5px;background-color:gainsboro;'>OK in:IE11/CH32/FF28<br /></div>
<script id=myScript>
//---button--
function fitG()
{
var bb=myG.getBBox()
var bbx=bb.x
var bby=bb.y
var bbw=bb.width
var bbh=bb.height
//---center of import---
var cx=bbx+.5*bbw
var cy=bby+.5*bbh
//---create scale: ratio of desired width vs current width--
var width=390
var scale=width/bbw
//---where to move it---
var targetX=200
var targetY=200
//---move its center to target x,y ---
var transX=(-cx)*scale + targetX
var transY=(-cy)*scale + targetY
myG.setAttribute("transform","translate("+transX+" "+transY+")scale("+scale+" "+scale+")")
svgSourceValue.value=svgDiv.innerHTML
}
</script>
<script>
document.addEventListener("onload",init(),false)
function init()
{
svgSourceValue.value=svgDiv.innerHTML
jsValue.value=myScript.text
}
</script>
</body>
</html>

Related

Hover transform not removed when mouse leaves svg element, Safari only

I have a minimal piece of code that should result in a rectangle being transformed when hovering over it. It works fine on Chrome and Edge but Safari leaves the rectangle in its transformed state when the mouse has left it.
<html>
<head>
<style>
#rect:hover{
transform: scale(0.9);
}
</style>
</head>
<body>
<div id="divRect">
<svg width="400" height="110">
<rect id="rect" width="300" height="100" style="fill:rgb(0,0,255)" />
</svg>
</div>
</body>
</html>
Can workaround by adding initial transform like this-
<style>
#rect{
transform: scale(1);
}
#rect:hover{
transform: scale(0.9);
}
</style>

Why this SVG not working in the EPUB file

I have the bellow pandoc generated xhtml in my EBUP file:
cat EPUB/text/ch001.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="en-US">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<title>ch001.xhtml</title>
<link rel="stylesheet" type="text/css" href="../styles/stylesheet1.css" />
</head>
<body epub:type="bodymatter">
<section id="valami" class="level1 unnumbered">
<h1 class="unnumbered">valami</h1>
<html>
<body>
<svg xmlns="http://www.w3.org/2000/svg">
<circle r="50"> </circle>
</svg>
<svg class="svg-preview" height="13" id="m_s2tex_0" style="--latex_align: -0.31706pt; --latex_height: 13px; vertical-align:-0.31706pt; opacity: 1" viewbox="1872.019782 1482.72797 4.782067 7.770859" width="8" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs> <path d="m3.207272-6.981816c0-.261818 0-.283636-.250909-.283636c-.676363 .698182-1.636363 .698182-1.985454 .698182v.338182c.218182 0 .861818 0 1.429091-.283636v5.650908c0 .392727-.032727 .523636-1.014545 .523636h-.349091v.338182c.381818-.032727 1.330909-.032727 1.767272-.032727s1.385454 0 1.767272 .032727v-.338182h-.349091c-.981818 0-1.014545-.12-1.014545-.523636v-6.119998z" id="s7g0-49"> </path> </defs> <g id="s7page1"> <!--start 1872.019782 1490.246126 --> <use x="1872.019782" xlink:href="#s7g0-49" y="1490.246126"> </use> </g>
<script type="text/ecmascript">
if(window.parent.postMessage)window.parent.postMessage("0.31706|6|9.75|"+window.location,"*");
</script>
</svg>
</body>
</html>
</section>
</body>
</html>
It is basically 2 simple SVG object. The first one is a hand written just for the test and it is working:
<svg xmlns="http://www.w3.org/2000/svg">
<circle r="50"> </circle>
</svg>
The second is automatically generated and it is not working.
<svg class="svg-preview" height="13" id="m_s2tex_0" style="--latex_align: -0.31706pt; --latex_height: 13px; vertical-align:-0.31706pt; opacity: 1" viewbox="1872.019782 1482.72797 4.782067 7.770859" width="8" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs> <path d="m3.207272-6.981816c0-.261818 0-.283636-.250909-.283636c-.676363 .698182-1.636363 .698182-1.985454 .698182v.338182c.218182 0 .861818 0 1.429091-.283636v5.650908c0 .392727-.032727 .523636-1.014545 .523636h-.349091v.338182c.381818-.032727 1.330909-.032727 1.767272-.032727s1.385454 0 1.767272 .032727v-.338182h-.349091c-.981818 0-1.014545-.12-1.014545-.523636v-6.119998z" id="s7g0-49"> </path> </defs> <g id="s7page1"> <!--start 1872.019782 1490.246126 --> <use x="1872.019782" xlink:href="#s7g0-49" y="1490.246126"> </use> </g>
<script type="text/ecmascript">
if(window.parent.postMessage)window.parent.postMessage("0.31706|6|9.75|"+window.location,"*");
</script>
</svg>
I have tried to simplified down the second one to see why is not working, but without luck. Anybody have an idea what could be the reason?
update1: The file can be opened in Safari and it is rendering both SVG image correctly. I have uploaded a screenshot here. The first SVG is the quarter circle, the second one is the number 1.
You've written the viewBox attribute as viewbox.
SVG and XHTML are case sensitive languages whereas HTML is not so if the EPUB importer is expecting XHTML then this will be a problem.
Most epub viewers that I'm familiar with use a web engine for rendering. So to get your SVG to be visible in an epub, it probably needs to be visible in a web browser.
Trying your second SVG, I don't see anything in Chrome or Firefox. Or in a generic image viewer.
If I add a stroke= value to your path, I see "something" in the browser, but it's a tiny little thing. As if the viewbox and/or the use settings are confusing the browser.

Modify SVG color without using CSS or modifying SVG file

Does anyone have any tip/knowledge on changing the color/properties of a svgicon without using CSS or directly modifying the file?
For example:
const style = {
somestyle: {
random style configs
}
}
<svgIcon className={somestyle} />
Is it even possible to change that svgIcon into a different color from it's default color without using CSS or directly modifying the file?
Or maybe it would be easier to use and modify svgs provided by matieral-ui?
You can use javascript to modify the style of the respective SVG elements.
<html>
<head>
<script>
function setColor(color)
{
document.getElementById("rect").style.fill = color;
}
</script>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" style="width: 300px; height: 250px">
<rect x="50" y="20" rx="10" ry="10" width="200" height="200" style="fill:red; stroke:black; stroke-width:3" id="rect" />
</svg>
<button onclick="setColor('red');">Red</button>
<button onclick="setColor('green');">Green</button>
<button onclick="setColor('blue');">Blue</button>
</body>
</html>
http://jsfiddle.net/VDzGG/

Using an svg file with a Script tag from within svg

So the devil is in the details in this question.
I want to create some svg components with encapsulated behaviour (and therefore I want to include a script tag inside the external svg file(s)). Now, this works fine from HTML5 when you include via object or embed, etc. But I want to reference these svg files from within an svg tag (inside an svg element).
So, from within svg, the only ways I know of to include an svg file (via xlink:href) is with either an image tag or a use tag. Neither, however, will accept a script tag in their content model, which I assume is why the script tags are not being interpreted (and I'm pretty sure they are not being interpreted). I am escaping the scripts in CData format inside the svgs, so I don't think it is a parsing problem.
Here is a brief example of what I mean.
The Html File:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
</head>
<body>
<div id"top">
<svg id="map" viewBox = "0 0 500 500" version = "1.1" width="250" height="250"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<image x="0" y="110" width="100" height="100" xlink:href="svg/obj/example.svg" />
</svg>
</div>
</body>
</html>
And svg/obj/example.svg:
<?xml version="1.0" encoding="iso-8859-1"?>
<svg viewBox = "0 0 500 500" version = "1.1" width="250" height="250"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<script type="application/ecmascript"> <![CDATA[
function circle_click(evt) {
var circle = evt.target;
var currentRadius = circle.getAttribute("r");
if (currentRadius == 100)
circle.setAttribute("r", currentRadius*2);
else
circle.setAttribute("r", currentRadius*0.5);
}
]]> </script>
<circle cx="200" cy="200" r="100" fill="yellow" stroke="black" stroke-width="3" onclick="circle_click(evt)" onactivate="circle_click(evt)" mouseover="circle_click()"/>
</svg>
To eliminate the likelihood of parsing errors, I cut and paste the above script from a W3C example (iir). I've tried many variations on this theme, but can't seem to get it working. The specifics are sufficiently conflated that searching just brings up different use cases. Hopefully someone here can take me out of my misery ;).

Why is same-document reference in SVG affected by HTML <base> tag?

I have an HTML page with a <base> tag, also containing SVG. Same-document references such as the below within the SVG then fail:
<html>
<head>
<base href="http://my/server/basedir">
</head>
<body>
<svg>
<g>
<path d="M100,100 L150,150" id="path"/>
<text>
<textpath xlink:href="#path"/>
</text>
</g>
</svg>
</body>
</html>
The xlink:href="#path" reference fails to resolve. This works fine without the HTML base element. It also works if I replace the href attribute on the textpath element with an absolute IRI followed by the fragment identifier.
It seems to me that SVG should treat same-document IRI's differently and independent of the HTML base. In http://www.w3.org/TR/xmlbase/#same-document it says "Dereferencing of same-document references is handled specially.", although granted that's in the context of xml:base. By the way, I played with putting an xml:base on the svg element in hopes of overriding the HTML base setting for couldn't figure out how to make that work.
Case 1: without xml:base
Works in IE(Edge),Chrome, but not Firefox.
<html>
<head>
<base href="http://my/server/basedir">
</head>
<body>
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<g>
<path d="M100,100 L150,150" id="path"/>
<text>
<textpath xlink:href="#path">Hello</textpath>
</text>
</g>
</svg>
</body>
</html>
Case 2: with xml:base
Works in IE(Edge),Chrome, Firefox.
If this page url is http://my/thisfile.htm then set xml:base="http://my/thisfile.htm" on the svg tag or textpath tag.
<html>
<head>
<base href="http://my/server/basedir">
</head>
<body>
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:base="http://my/thisfile.htm">
<g>
<path d="M100,100 L150,150" id="path"/>
<text>
<textpath xlink:href="#path">Hello</textpath>
</text>
</g>
</svg>
</body>
</html>

Resources