The applying order of SVG transforms - html

In W3C's spec, it says:
The value of the ‘transform’ attribute is a <transform-list>, which is defined as a list of transform definitions, which are applied in the order provided.
...
If a list of transforms is provided, then the net effect is as if each transform had been specified separately in the order provided
When I tried out the follow markups in firefox, chrome and IE10, all three rendered by doing translate first, then following by rotate! See the codepen snippet. What have I missed here? Or the implementations from the 3 browsers are not W3C compliant?
<svg width="180" height="200"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- This is the element before translation and rotation are applied -->
<rect x="0" y="0" height="100" width="100" style="stroke:#000; fill: #0086B2" fill-opacity=0.2 stroke-opacity=0.2></rect>
<!-- Now we add a text element and apply rotate and translate to both -->
<rect x="0" y="0" height="100" width="100" style="stroke:#000; fill: #0086B2" transform="rotate(45 100 50) translate(50)"></rect>
</svg>

The specification is pretty clear about the order which is that the rightmost transform is applied first.
If a list of transforms is provided, then the net effect is as if each transform had been specified separately in the order provided.
I.e,
<g transform="translate(-10,-20) scale(2) rotate(45) translate(5,10)">
<!-- graphics elements go here -->
</g>
is functionally equivalent to:
<g transform="translate(-10,-20)">
<g transform="scale(2)">
<g transform="rotate(45)">
<g transform="translate(5,10)">
<!-- graphics elements go here -->
</g>
</g>
</g>
</g>

If you want to sequentially change these transformations
you have to try this one
<g transform="translate(-10,-20) onmouseover=changeTransform(evt)">
function changeTransfrom(evt)
{
var id=evt.target;
id.setAttribute('transform',scale(0.5));
id.setAttribute('transform',rotate(30));
id.setAttribute('transform',skewY(45));
id.setAttribute('transform',matrix(2,2));
}

Related

svg not sharp, but blurry

For whatever reason these svg files, seems blurry, and not 100% sharp in all browsers. These are svg files, and are enclosed within elements that are scaled to pixels, in other words using px and not % - hence no browser bitmap errors.
Any idea as to why this is happening?
This is one of the svg files;
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 361.5 192.5" style="enable-background:new 0 0 361.5 192.5;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;}
.st1{fill:#FC5500;}
.st2{fill:#FFFFFF;}
.st3{fill:#FB5500;}
</style>
<g>
<path class="st0" d="M-9.4-6.3c126,0,252,0,378,0c0,68.7,0,137.3,0,206c-126,0-252,0-378,0C-9.4,131-9.4,62.4-9.4-6.3z"/>
<path class="st1" d="M-0.2,112.1c0-8,0-15.9,0-24.4c112.3,0,224.3,0,336.7,0c0-29.4,0-58.4,0-87.7c8.4,0,16.4,0,25,0
c0,46.8,0,93.7,0,140.6c-2.4-0.3-2.5-2.5-3.2-4c-3.7-9-10.3-15-19.3-18.5c-15.2-6-31.2-6.7-47.2-5.5c-7.8,0.6-15.6,1.5-23.1,4.1
c-24.8,8.7-33.9,38-18.3,59.2c5.8,7.8,14.5,10.9,23.4,13.4c2,0.6,4.9-0.1,5.6,3.1c-13.9,0-27.9,0-41.8,0
c-8.1-5.7-14.1-13.6-21.4-20.2c-1.7-1.5-3.8-2.8-4.1-5.5c0.5-2.5,2.8-3.1,4.7-3.9c9.5-4.3,14.3-11.9,14.5-22.1
c0.2-10.1-4.8-17.3-13.9-21.8c-8.5-4.2-17.6-5.3-26.7-5.5c-20.8-0.4-41.6-0.1-62.5-0.1c-1.7,0-3.3,0-4.8,0.8
c-1.6,2.3-1.1,4.9-1.1,7.3c0,21.2,0,42.3,0,63.5c0,2.6,0.5,5.4-1.7,7.6c-32,0-64,0-96.1,0c-3.2-6.9-1.5-13.8-0.9-20.2
c3.1-2.6,6-2.3,8.8-2.3c12.7-0.1,25.3,0,38-0.1c7.8-0.1,15.3-1.6,22.2-5.3c17.8-9.6,18.8-33.3,1.7-44.3c-8.9-5.7-19.1-6.7-29.3-6.9
c-19.3-0.3-38.7,0.1-58-0.1C4.6,113.4,2,113.8-0.2,112.1z"/>
<path class="st2" d="M120.6,192.5c0-26.6,0-53.3,0-80.7c29.5,1.5,58.7-2.6,87.6,2.2c13.5,2.2,24.2,9.5,24.9,25.1
c0.6,14.2-6.8,23.1-20.2,27c8.3,8.8,16.5,17.6,24.7,26.4c-11.2,0-22.5,0-33.7,0c-4-1.4-6-5-8.7-7.9c-12.1-13.2-6.6-11-23.7-11.2
c-5.5-0.1-10.9,0-16.4,0c-2,0-4-0.2-6,1c-1.5,3.5-0.5,7.4-0.8,11.1c-0.2,2.4,0.3,5-1.7,7.1C138,192.5,129.3,192.5,120.6,192.5z"/>
<path class="st2" d="M203.8,0.7c-4.9,6.4-10,13.1-15.2,20c-18.4,0-36.7,0-55,0c-4.1,0-9-0.2-8.9,5.9c0,6.1,4.8,5.9,9,6
c16.8,0.2,33.7-0.4,50.5,0.6c12.5,0.7,22.4,6.1,22.6,20.9c0.2,14.6-7.3,24.7-22.5,25.3c-28.5,1.2-57.1,0.3-85.9,0.3
c5-6.5,10.1-13.2,15.3-20c19.3,0,38.4,0.1,57.6-0.1c4.4,0,11.3,1.9,11.3-5.3c0.1-7.7-7-5.4-11.6-5.5c-16.1-0.4-32.4,0.3-48.4-0.9
c-13-1-21.7-8.1-21.9-22.5c-0.2-14.9,8.5-23.6,22-24.3C149.5-0.2,176.6,0.7,203.8,0.7z"/>
<path class="st2" d="M279.5,192.5c-31.5-9.3-41.2-22.1-36.9-48.9c2.8-17.6,15-26,31-29.7c18.9-4.4,38-4.4,57-0.2
c15.1,3.4,26.5,11.3,31,27c0,7.6,0,15.2,0,22.9c-2.8,16.5-15.6,27.1-34.6,28.6c-1,0.1-2-0.2-2.9,0.3
C309.1,192.5,294.3,192.5,279.5,192.5z"/>
<path class="st2" d="M77.2,20.7c-17.1,0-33.9,0-51.1,0c0,3.2,0,6.3,0,9.8c20.5,0,41.1,0,62.9,0c-5.3,6.7-9.8,12.4-14.4,18.2
c-16.2,0-32.1,0-48.5,0c0,3.6,0,7,0,10.8c22,0,44.1,0,67.6,0c-5.9,7.7-11,14.5-16,21.1c-26,0-51.6,0-77.6,0C0,53.7,0,27,0,0
c30.7,0,61.4,0,93,0C87.6,7.1,82.5,13.8,77.2,20.7z"/>
<path class="st2" d="M-0.2,112.1c25.3,0.1,50.6-0.4,75.9,0.7c20.2,0.9,32.8,13.2,32.7,29.5c-0.1,16.5-13.5,28.5-34.1,29.3
c-16.3,0.6-32.6,0.1-49.7,0.1c0,7.4,0,14.1,0,20.9c-8.1,0-16.3,0-24.8,0C-0.2,165.6-0.2,138.8-0.2,112.1z"/>
<path class="st2" d="M233.3-0.2c18.6,0,37-0.5,55.3,0.1c21,0.7,34.6,13.1,34.6,30.5c0,17.4-13.8,29.5-35.4,30.1
c-15.1,0.5-30.3,0.1-45.9,0.1c0,6.7,0,13.1,0,19.8c-8.6,0-16.6,0-25,0c0-13.4,0-26.6,0-40.7c22.6,0,45.3,0,68.1,0
c5.2,0,10.8-0.6,12.4-6.2c2.6-9.1-3-12.6-11.1-12.7c-22.7-0.2-45.5-0.1-69.4-0.1C222.7,13.3,227.9,6.6,233.3-0.2z"/>
<path class="st1" d="M146.7,192.5c0-6.8,0-13.6,0-20.8c13.2,0,26.1,0,39.7,0c5.6,6.6,11.6,13.7,17.6,20.8
C184.9,192.5,165.8,192.5,146.7,192.5z"/>
<path class="st3" d="M323.9,192.5c17.1-3.7,32.3-9.9,37.6-29c0,9.5,0,18.9,0,29C349,192.5,336.4,192.5,323.9,192.5z"/>
<path class="st3" d="M145.8,150.8c0-5.7,0-11.4,0-17.1c17.9,0,35.6-0.2,53.3,0.2c4.4,0.1,7.8,3.1,7.7,8.3c-0.1,6-4.5,8.4-9.3,8.5
C180.4,151,163.3,150.8,145.8,150.8z"/>
<path class="st1" d="M302.2,173.1c-6-0.4-11.4-0.7-16.9-1.1c-12.8-1.1-18.4-8-18.1-20.9c0.3-12.7,7.6-17.4,19-18.6
c11.1-1.1,22.3-1.2,33.4,0.1c11.3,1.3,17.2,7.1,17.3,19c0.1,11.8-5,18.7-16.7,20C314.1,172.4,307.9,172.7,302.2,173.1z"/>
<path class="st3" d="M25.1,133c15.6,0,30.9-0.2,46.2,0.1c5.6,0.1,11.1,1.8,11.2,8.7c0.2,7.1-5.2,9.3-11.1,9.4
c-15.3,0.3-30.6,0.1-46.3,0.1C25.1,145.5,25.1,139.6,25.1,133z"/>
</g>
</svg>
If you want your SVG to be at its sharpest, then design it so that its shapes - especially the horizontal and vertical parts of the shapes - are on pixel boundaries.
For example, compare the following two examples:
<svg width="50" height="50">
<rect x="9.5" y="9.5" width="31" height="31"/>
</svg>
<svg width="50" height="50">
<rect x="10" y="10" width="30" height="30"/>
</svg>
Here's what this looks like at 4X enlargement.
Any time your shape passes through the middle of pixels, you will get grey pixels due to the anti-aliasing that 2D renderers use.
The response used a slightly modified code #Paul LeBeau
You can use the SVG attribute - shape-rendering =" crispEdges " to disable browser anti-aliasing.
https://developer.mozilla.org/ru/docs/Web/SVG/Attribute/shape-rendering
crispEdges
Indicates that the user agent shall attempt to emphasize the contrast
between clean edges of artwork over rendering speed and geometric
precision. To achieve crisp edges, the user agent might turn off
anti-aliasing for all lines and curves or possibly just for straight
lines which are close to vertical or horizontal. Also, the user agent
might adjust line positions and line widths to align edges with device
pixels.
<svg width="50" height="50">
<rect x="9.5" y="9.5" width="31" height="31" shape-rendering="crispEdges"/>
</svg>
<svg width="50" height="50">
<rect x="10" y="10" width="30" height="30"/>
</svg>
The image is increased 4 times
No gray pixels are observed.
Update 2019 by comments
There is no universal, 100% solution to the pixelation problem.
Since the rendering depends on the installed operating system, its settings, the video card and which browser is used.
You can use an integrated approach made up of all the answers of this topic:
Use integer svg image coordinate values by answer #Paul LeBeau
If you take a finished image with fractional values, you can process
it with SVG optimizer
Set the integer value of viewBox by answer #AKX
Use the attribute shape-rendering ="crispEdges"
If a design change is possible, avoid contrasting border colors.
For example, use a dark gray color instead of a black and white combination or use shades of gray instead of a pure white background.
I tried the SVG on a page and it doesn't look really blurry to me.
However, you could try editing the viewbox to have an integer size -- i.e. turn viewBox="0 0 361.5 192.5" into viewBox="0 0 362 193" -- that might make a difference.
it might be caused by use of borders and shadows in creation of the svg.
I avoid those myself as they are sometimes blurry.
Shadow if needed can be created as another path with transparency and offset.

Putting SVG elements next to each other

I have a <text> and a <rect> element nested in a svg element. I want the <rect> element to begin right after the <text> ends. But it looks like I have to position them using x and y.
Is there any way to put them next to each other like regular HTML elements ?
<svg>
<text>1200</text>
<rect width='120' height='12'></rect>
</svg>
I only seem to be able to get it with this:
<svg height="30" width="100">
<text x="0" y="15" fill="red">SVG TEXT!</text>
</svg>
<svg height="30" width="100">
<rect width='120' height='12'></rect>
</svg>
See the Pen 'SVG Text and Box Test' by James Almeida here: http://codepen.io/jimmyplaysdrums/pen/ZYdEyw/

SVG coordinates - mask & use & x/y attribute combined

I have a problem with SVG coordinates. I'm sure it's not a bug and it's probably explained somewhere in the documentation and therefore I don't question it. But for my needs I can't find other way to resolve the problem. Now to the point.
TL;DR
In SVG, this
<mask id="myMask" x="0" y="0">
...
</mask>
<use xlink:href="..." x="100" y="100" mask="#myMask">
changes the <use> x (or y) position together with the <mask> x (or y) position.
I want to keep the <mask> in its place.
Longer explanation
Background
In my web application I have a SVG path. I use it in multiple places so I decided to use the <use> element. Now, in some places I wanted to hide part of the path so I use <mask> element with a rectangle in it. There's also a situation where there is a stack of the same path placed one below another. To achieve this I used the y attribute for one of the <use> elements.
The question
Unfortunately, when I change the y coordinate of the <use> the <mask> attached to it also changes its y coordinate. The situation doesn't occur on <path> element nor other elements.
Below is an example (for simplicity I used <rect> elements).
Run the snippet to see four squares placed next to each other (two red and two yellow). The grey overlay represents the mask's boundaries. Squares will rather look like rectangles because they're cut in the half of their height by the <mask>. As you can see in the code, red squares are imported by <use> element and yellow ones are placed directly with <rect> element. Also the second and the fourth square are both moved 500 units downwards. My problem is clearly represented by the second square. It should be cut exactly like the fourth square but I need to do it the <use> way.
<svg xmlns="http://www.w3.org/2000/svg" width="200px" height="100px" viewBox="0 0 4000 1000">
<defs>
<rect id="svgRect" width="1000" height="1000"></rect>
<mask id="svgIconMask10">
<rect x="0" y="0" width="4000" fill="#ffffff" height="500"></rect>
</mask>
</defs>
<!-- Rectangle 1 -->
<use xlink:href="#svgRect" y="0" fill="#E5584C" mask="url(#svgIconMask10)"></use>
<!-- Rectangle 2 -->
<use xlink:href="#svgRect" x="1000" y="300" fill="#E5584C" style="mask: url(#svgIconMask10);"></use>
<!-- Rectangle 3 -->
<rect x="2000" y="0" width="1000" height="1000" fill="#E5D24C" style="mask: url(#svgIconMask10);"></rect>
<!-- Rectangle 4 -->
<rect x="3000" y="300" width="1000" height="1000" fill="#E5D24C" style="mask: url(#svgIconMask10);"></rect>
<!-- Mask area boundaries -->
<rect fill="transparent" stroke="#000" stroke-width="6px" x="0" y="0" width="4000" height="500" />
</svg>
You can apply the mask to a <g /> element and have the <use /> positioned independently:
<g style="mask: url(#svgIconMask10);">
<use xlink:href="#svgRect" x="1000" y="300" fill="#E5584C"></use>
</g>
http://jsfiddle.net/yb1q8dwh/

Define an inline svg completely with css instead of in the html file itself

I have an html file that uses inline svg. I use this so I can add classes to my svg and style them with CSS. The following snippet works:
<div>
<svg class="icon" viewbox="0 0 512 512">
<path d=" ... "/>
</svg>
</div>
Howeever, the tag can be quite long if the svg is complex. I'm currently using this svg in 3 different locations, and everytime I need to copy paste the entire path. It would be better if I could define the path only 1 time, preferabvly in a css class like this:
<div>
<svg class="icon" viewbox="0 0 512 512">
<path class="compleximage"/>
</svg>
</div>
.compleximage
{
d: ... ;
}
But this doesn't seem to work. Maybe I'm getting it wrong syntactically, or maybe it can't be done this way. If so, are there ways other to prevent having to copy/paste the svg in my html files? I'm trying to follow the "0,1 or infinite" design pattern, and copy/pasting code 3 times break that.
You can use the use tag to display the path in more than one place. Just give the path an id attribute and then refer to that in the xlink:href of the <use> element.
Something like
<defs>
<path id="image1" d="..." />
</defs>
<use x="20" y="10" xlink:href="#image1" />
<use x="50" y="50" xlink:href="#image1" />
etc.
In HTML5 you can do it.
Please try this:
<svg width="100" height="100">
<circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
</svg>
On the other hand, you can create your own SVG and get it via <img src="" />.
Sample below:
<img class="papa" src="http://s.cdpn.io/3/kiwi.svg">
Reference here:
(1) http://css-tricks.com/using-svg/
Another reference here how to change it via css:
(2) http://codepen.io/chriscoyier/pen/evcBu
You cannot set svg attributes using CSS. You can only set styles like stroke, fill, etc.
The only way would be to use javascript to set those paths dynamically. I would recommend jQuery.
this link should be helpful for using jQuery to modify svg files.
Modify a svg file using jQuery

How do I tell if a DOM element is HTML or SVG?

I am writing a piece of infrastructure that needs to be applied differently to HTML elements versus SVG elements. Given a DOM node, how can I tell if it''s an SVG or HTML element?
You may try something like the following:
if(document.getElementById("el") instanceof SVGElement) {
console.log("It's an SVG element");
}
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="300" height="300">
<g id="firstGroup">
<rect id="el" width="100" height="50" x="40" y="20" fill="blue" />
<text x="40" y="100">This is a basic SVG document!</text>
</g>
</svg>
Note that the <svg> element itself is actually an HTML element containing SVG elements - which means that, perhaps surprisingly, the <svg> HTML element is not an SVG element, hence:
console.log(document.createElement("svg") instanceof SVGElement)) // => false
I'm not sure how cross browser compatible it is but I was poking through the DOM properties and saw a ownerSVGElement which seems promising?
Here goes what I was toying around with: http://jsbin.com/uMIronal/4/edit?html,js,output