Polygon in HTML SVG is clipped - html

I create a star via an SVG polygon. It draws fine when the stroke width is 1, but with wider strokes, the bottom left (and only the bottom left) vertex gets cut off. Does anyone know why this happens (and how to fix it)?
The following snippets (which I displayed using https://www.w3schools.com 'try it') show the problem, both with the original star and with just the bottom 'arm' isolated as a simple triangle:
<svg height="200" width="200">
<polygon points="16,53 23,35 8,25 25,25 30,8 36,25 53,25 38,35 45,53 30,41" style="fill:none;stroke:purple;stroke-width:7" />
Sorry, your browser does not support inline SVG.
</svg>
<svg height="300" width="300">
<polygon points="120,164 64,212 92,140" style="fill:none;stroke:purple;stroke-width:9" />
Sorry, your browser does not support inline SVG.
</svg>

The default stroke-miterlimit is 4. You need a larger number than that because your star is quite pointy.
<svg height="200" width="200">
<polygon transform="translate(10, 10)" points="16,53 23,35 8,25 25,25 30,8 36,25 53,25 38,35 45,53 30,41" style="fill:none;stroke:purple;stroke-width:7; stroke-miterlimit:10" />
Sorry, your browser does not support inline SVG.
</svg>

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.

SVG rectangle with SVG "def" fill, becomes black during re-paint

though it's one of the most corner cases ever, maybe one of you saw that...
for some reason, when you drag an SVG rectangle with fill that is pointed to a SVG def, the whole rectangle becomes black! (something wrong in the browser re-paint I think...)
if someone has a clue for a fix or a workaround, it will be highly appreciated
when dragging the below, it becomes black.
http://jsfiddle.net/d11k5bxg/5/
<div class="content">
<svg width="100%" height="100%">
<defs>
<pattern id="Triangle" width="5" patternUnits="userSpaceOnUse" height="5">
<rect fill-opacity="0.5" width="5" fill="#DDD" height="5"></rect>
<path stroke="#000" stroke-width="0.5" d="M0 5L5 0ZM6 4L4 6ZM-1 1L1 -1Z" stroke-opacity="0.2"></path>
</pattern>
</defs>
<g class="chart-content">
<g class="layer10">
<g class="bar-chart compare_items" transform="translate(0,5)">
<g class="bar-group">
<rect class="bar" height="165" width="120" fill="url(#Triangle)" ></rect>
</g>
</g>
</g>
</g>
</svg>
$("div").draggable({
helper: function (e) {
var draggedElement = $(e.currentTarget).clone(true);
return draggedElement;
}
});
(also opened a Chromium ticket on that: https://code.google.com/p/chromium/issues/detail?id=428174)
In general, I suspect that the drag-and-drop API you're using has not been tested on SVG. However, what is happening is definitely very buggy, since the DOM still after the drag looks fine but the graphic doesn't.
The problem seems to stem from the fact that JQuery duplicates the entire SVG during the drag operation. Which means there are temporarily two different patterns with id="triangle" (which is bad). My guess is that the rectangle gets associated with the second instance of that pattern, and then when that instance disappears, it doesn't re-attach to the original pattern
If you're only dragging and dropping within a single SVG, you can probably implement your own drag behaviour, just duplicating the rect and positioning it using SVG attributes, instead of duplicating the entire SVG.
Another workaround would be to separate out all your <defs> content into an SVG that isn't displayed on screen. That way, it wouldn't be duplicated when you drag the visible SVG, and you avoid the duplicated id values.

SVG Pattern Doesn't Show on Page

I am completely clueless, what is going wrong with my svg pattern. I defined it in the def section of the svg and then tried to reference it. But it doesn't show up once I include the svg in an img-tag. If I open it on itself in the browser everything is good though.
See the following examples:
http://kijani.co/img/sketch/index.html
http://kijani.co/img/sketch/livingroom.svg
And my code:
<defs>
<pattern id="paper" patternUnits="userSpaceOnUse" width="200" height="200">
<image xlink:href="http://kijani.co/img/pattern/paper.jpg" width="200" height="200"/>
</pattern>
</defs>
<g id="background">
<path id="paper" fill="url(#paper)" d="..."/>
</g>
This might be a really stupid question, but I am fairly new to svg and couldn't find a solution anywhere so far.
This is svg's referencing mode probrem.
Using img element to display svg image is restrected for refering outer resources.
So you should use object element to display svg image, or embed pattern image into svg by data scheme format.

Define a source rectangle for an SVG <image> like you can in HTML Canvas or CSS

In HTML5 Canvas you can draw an image as a whole, or draw only a piece of it, or draw only a piece of it to an arbitrary rectangle (which may scale it).
Here's an example of all three:
Here's the code used to draw those three examples:
ctx.drawImage(img, 0, 0);
ctx.drawImage(img,
// source rect
50, 50, 70, 70,
// destination rect
0, 200, 70, 70
);
ctx.drawImage(img,
// source rect
50, 50, 70, 70,
// destination rect
0, 270, 30, 30
);
This is also relatively easy to do in CSS.
My question is, for a given image, how can you achieve the same effects using SVG <image> elements?
How do I, for instance, make an Image that occupies 50x50 pixels, that shows a portion of the referenced href, as in the first crop?
One could use a clipping path to crop part of the image, but then you (seemingly) cannot use a clipping path of a larger image while defining the width and height of the <image> element to be small.
Here's a fiddle with the above code plus a sample SVG element:
http://jsfiddle.net/wcjVd/
You don't need a clipPath at all, you can use the viewBox to do what you want
<svg width="70px" height="70px" viewBox="50 50 70 70">
<image x="0" y="0" width="200" height="200"
xlink:href="http://placekitten.com/200/200" clip-path="url(#myClip)">
</image>
</svg>
The value of the viewBox attribute is a list of four numbers <min-x>, <min-y>, <width> and <height>, separated by whitespace and/or a comma, which specify a rectangle in user space which should be mapped to the bounds of the viewport established by the given element, taking into account attribute preserveAspectRatio.
Demo Here
Glad I can help you here because you helped me with a Canvas project a few months ago!
Edit
You said that you needed to transform them also, so after an hour I came up with these couple options:
If you can, transform the original image and do the same effect. Demo here If you are wanting the cropped image at the origin (0,0) then the code would look like
<defs>
<clipPath id="myClip">
<rect x="0" y="0" width="70" height="70"/>
</clipPath>
</defs>
<image x="-50" y="-50" width="200" height="200" clip-path="url(#myClip)"
xlink:href="http://placekitten.com/200/200"></image>
OR, more satisfactorily, you could do it using a use
<defs> <!-- Your original clip -->
<clipPath id="myClip">
<rect x="50" y="50" width="70" height="70"/>
</clipPath>
</defs>
<image id="myImage" x="0" y="0" width="200" height="200"
xlink:href="http://placekitten.com/200/200" clip-path="url(#myClip)" />
<!-- Hide the original (I made a layer of white) -->
<!-- This is the part that you could probably find a better way of doing -->
<rect x="0" y="0" width="200" height="200" style="fill:white" />
<!-- Create what you want how you want where you want it -->
<use x="-50" y="-50" width="200" height="200" xlink:href="#myImage" transform="scale(1.3)"/>
</svg>
Demo for that approach here

Fill SVG element with with a background-image with an offset

I want to do something similar to this Fill SVG path element with a background-image
However, I want to shift/offset the image. With CSS, it can easily done by setting background-image and background-position. How do I do it with SVG?
You can use patternTransform on the pattern element to transform the pattern; it works just like the transform attribute you may already be familiar with. See the documentation for details.
You can use a pattern and a SVG element with the fill attribute.
Here is an example: insert an image at position (10, 10) with a (40, 550) offset and a size (420, 340). Note that you must set the correct x/y and transform="translate(-x1 -y2)".
<p>
Original image
</p>
<svg version="1.1" width="500" height="400" style="background-color: #EEE;">
<defs>
<pattern id="europe" patternUnits="userSpaceOnUse"
width="1456px" height="1094px">
<image xlink:href="https://i.imgur.com/MQHYB.jpg"/>
</pattern>
</defs>
<rect fill="url(#europe)" transform="translate(-30 -540)"
x="40" y="550" width="420" height="340"/>
</svg>