Rotate an object in SVG - svg

I am just getting started with SVG and am now trying out rotating objects.
I have the initial canvas and have created my own drag and drop function so on mousedown the drag is initialized and mouseup it stops. The problem i'm having is when I rotate an object, it seems to change the x and y. This is visible when i'm trying to drag an object. Does anyone know how to get around this so the x and y get "normalized" in relation to the rotate angle?
Here's my code.
<svg version="1.1" width="900" height="400"><text x="10" y="10" id="text_0" width="200" height="40" transform="rotate(45, 0, 0)">SVG test</text></svg>
Thanks

rotate parameters give you the angle and the center of the rotation (see MDN for example). And what about the width and height attributes in your text anyways? This is not part of the standard as of here. If you want to change the size of your text, do so using font-size in the style.
If you want to rotate the text around its (the text element's) center you may use for example the following:
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" width="900" height="400" xmlns="http://www.w3.org/2000/svg">
<text x="10" y="10" id="text_0" transform="rotate(45, 10, 10)" style="dominant-baseline: middle; text-anchor: middle;">
SVG test
</text>
</svg>

Related

How to use a transformed path in textPath?

Consider following code:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="2000" height="2000" viewBox="-1000 -1000 2000 2000"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<style>text { font-size: 60px; }</style>
<style>path { fill: none; stroke: black; }</style>
<style>textPath { text-anchor: middle; }</style>
<path d="M -258.8190, -965.9258 a 1000, 1000 0 0,1 517.6381, 0" id="ttO"/>
<use xlink:href="#ttO" transform="scale(.85)" id="ttI"/>
</defs>
<use xlink:href="#ttO"/>
<text dy="55"><textPath xlink:href="#ttO" startOffset="50%">Hello</textPath></text>
<use xlink:href="#ttI"/>
<text dy="25"><textPath xlink:href="#ttI" startOffset="50%">World!</textPath></text>
</svg>
... and the resulting image:
.
The explicitly defined path (ttO) and the textPath (Hello) using that path works fine. To define the smaller concentric arc (ttI), rather than calculating coordinates, I like to use transform. This works fine. However, I cannot use this second arc 'ttI' in the second textPath, at least Chrome doesn't render the second textPath. Is this because 'use' cannot be used to define new ids? What is the best way to do this?
If it was just this example, probably I can define one path halfway between two arcs and use that to draw textPaths with +/- offsets and draw the two arcs as transforms of the defied path. My goal is to extend the pattern I attempted to create more paths/textPaths at other angles / distances from the center with different languages to form a circular graphic. Without defining transformed paths, I have to explicitly specify at least one arc for each language.
This is how I would do it: I would create a text element using the same text path and I would scale the text - in this case transform="scale(.7,.7)". Also since I want the text to be the same size as the unscaled one I would use a different font size: 1em for the scaled text and .7em for the unscaled. Of coarse this is just an example. You can pick your font size making sure the font size for the scaled text is bigger than the font-size of the unscaled one by the same amount as the transformation.
Please observe that for the path I'm using vector-effect="non-scaling-stroke"so that that stroke appears the same in both the scaled and unscaled one.
svg{border:solid}
path{fill:none;stroke:black;}
<svg viewBox="-110 -110 220 220" >
<g>
<path id="path0" d="M90,0A90,90 0 0 1 -90,0A90,90 0 0 1 90,0" vector-effect="non-scaling-stroke"/>
<text font-size=".7em" >
<textPath xlink:href="#path0" startOffset="75%" text-anchor="middle">Hello World!</textPath>
</text>
</g>
<g transform="scale(.7,.7)">
<text font-size="1em" >
<textPath xlink:href="#path0" startOffset="75%" text-anchor="middle">Hello World!</textPath>
</text>
<use xlink:href="#path0"/>
</g>
</svg>

SVG or HTML text that scales to fully fit a container so it stretches, bot vertically and horizontally, disregarding aspect ratio

I need to make text automatically stretch in both dimensions, to fill a container. It will distort.
This shows the the container space in red
This shows what a long name would normally resize to put in that space and maintaining aspect ratio
.
This shows what my client wants to happen
.
I would prefer to use SVG but I will work with what works.
I have searched for a solution to the best of my abilities but all seem to either refer to maintaining aspect ratio or stretching text when the page or viewbox changes dimensions.
That's quite a broad question, but yes you can do it with svg, I'll let you implement it though since you didn't provided anything to chew on.
The key point is to set your svg's preserveAspectRatio to "none":
svg{
height: 100vh;
width: 50vw;
}
body{
margin:0;
}
<div>
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 300 40" preserveAspectRatio="none">
<text x="0" y="35" font-family="Verdana" font-size="35">
Hello, out there
</text>
</svg>
</div>
If your text is already part of an SVG (as it appears in your example), you will probably need to use a nested <svg> element.
<svg width="400" height="400">
<rect width="400" height="400" fill="rebeccapurple"/>
<!-- rect representing area that our text has to squeeze into -->
<rect x="20" y="50" width="200" height="50" fill="white"/>
<!-- x y width height match above rect -->
<!-- viewBox values need to match text bounds -->
<svg x="20" y="50" width="200" height="50"
viewBox="0 8 244 28" preserveAspectRatio="none">
<text x="0" y="35" font-family="Verdana" font-size="35">
HELLO THERE
</text>
</svg>
</svg>
The hardest part is workoing out the correct values for viewBox. It needs to match the bounds of the (normal unsqueezed) text.

Force SVG tooltip appear when mouse over unfilled area

Here is a simple SVG code with a tooltip embedded:
<?xml version="1.0" encoding="utf-8"?>
<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 100 100" enable-background="new 0 0 100 100"
xml:space="preserve">
<g>
<title>Blue Frame</title>
<path
fill="#2E3192"
d="M75,25v50H25V25H75 M100,0H0v100h100V0L100,0z"
/>
</g>
</svg>
It draws blue frame and does nothing more.
The problem is tooltip appears only when the mouse pointer is over the frame. When it moves to unfilled center of the SVG image, then tooltip disappears.
Moving <title> tag over the <g> tag leads to no tooltip at all.
What have I missed to make tooltip appear always when the mouse pointer is over any point of this SVG, not just over filled parts?
It is just a quick and short preview to show the problem. For example it is very difficult to catch the tooltip on any large image with only a few thin lines.
I know I can place a rectangle that will cover all available SVG space and put anything over it. But this rectangle also needs some color while I need transparent parts of my SVGs to remain strictly transparent.
You could always put a hidden rect in the background to catch those mouse events you'd otherwise miss like so:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 100 100" xml:space="preserve">
<g>
<title>Blue Frame</title>
<rect width="100%" height="100%" visibility="hidden" pointer-events="all"/>
<path
fill="#2E3192"
d="M75,25v50H25V25H75 M100,0H0v100h100V0L100,0z"
/>
</g>
</svg>
I would also suggest to define X and Y positions to the rectangle offered by Mr.Longson. Otherwise the rectangle may appear outside of your drawing partially or completely and you would have to catch the tooltip again.
You may get X and Y values at the <svg> tag's viewBox parameter, they are the first two groups of digits, the very first one is for the X and the second one is Y. Other two describes the initial size of the SVG and not needed for this case.
According to your example you don't need to define either X or Y as they are both equal to 0:
<rect x="0" y="0" width="100%" height="100%" visibility="hidden" pointer-events="all"/>
But as soon as they are for example viewBox="-123 456 100 100" you'll immediately notice that some parts of your SVG still don't show any tooltip. In such case the <rect> tag should look like this:
<rect x="-123" y="456" width="100%" height="100%" visibility="hidden" pointer-events="all"/>

SVG rotate text with % as Unit

I try to rotate a svg text. i get the position of the text as % i.e. 15% by calling a php function from xslt. the problem is that i can not rotate a svg object using %. it works if i use a digit number instead.
Below i present the problem as simplified:
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://ww.w3.org/2001/xml-events" xmlns:php="http://php.net/xsl" version="1.1" baseProfile="full">
<text x="50%" y="50%" transform="rotate(-90 50% 50%)">rotateMe</text>
<line x1="50%" y1="47%" x2="60%" y2="47%" stroke="black" stroke-width="2px"/>
</svg>
this pic is in the middle of my browser screen
And i want that it looks like this:
but it dont work because of %
transform="rotate(-90 **50% 50%**)"
it is a requirement for me to use % for the coordinates. Any ideas or solution to my problem?
Thank you in advanced.
You can translate the co-ordinates using an inner <svg> element. The example below displays as per your "i want that it looks like this" bitmap on Firefox.
If you can't see the text on whatever browser you are using, try adding overflow="visible" to the inner <svg> element so you can see where it ends up. Not all browsers support the dominant-baseline attribute so you may need to fiddle about with the text's y attribute instead.
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg x="50%" y="50%" width="100" height="100">
<text text-anchor="end" dominant-baseline="text-before-edge" transform="rotate(-90 0 0)">rotateMe</text>
</svg>
<line x1="50%" y1="47%" x2="60%" y2="47%" stroke="black" stroke-width="2px"/>
</svg>

Scale uniform on X axis

I dynamically generate an svg, which can result in a very high height value. (It's a table.)
My aim is to have:
ratio on x axis
scrollbar to scroll the image down
I know I have to play with svg's height and width, viewBox and preserveAspectRatio, but to achieve my goal I'm using a dirty trick which leaves a lot of white space at the bottom: I set the height of the image to a very high value.
The problem is that I have no certainty that the table (image) will never exceed this value (and I don't want to end up setting it to something like 100000).
Can anybody help me?
Here's the example I'm working on to find a solution:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
width="100%"
height="2000"
viewBox="0 0 1366 768"
preserveAspectRatio="xMinYMin meet">
<rect
width="1359.5181"
height="42.065403"
x="3"
y="3"
id="rect2985"
style="fill:#ffff78;stroke:#000000;stroke-width:10" />
<rect
width="719.58691"
height="805.50775"
x="316.83304"
y="177.29433"
id="rect2987"
style="fill:#ffff78;stroke:#000000;stroke-width:10" />
<text
x="15"
y="30"
id="text2989"
style="font-size:23px">LOL</text>
</svg>
Yeah, I guess I should.
I'll use this for now (still gotta be fully tested):
function fixHeight()
{
node = document.getElementById("table");
node.setAttribute("height", node.getBBox().width);
}

Resources