svg rect fill background image performance issue - image

I want to draw an image as a background for SVG rect. I did as follows,
<pattern id = "HappySmile" width="97" height="40" >
<image width="97" height="30" xlink:href="resources/images/HappySmile.png"></image>
</pattern>
It works but performance has drastically dropped.I am applying on 36 rects. Any suggestions will be very helpful.
The image explaing the scenario can be found in the following link.
http://i.stack.imgur.com/Jo6b2.png
Thanks.

If patterns are proving too slow for you. Try using a <mask> or a <clipPath> instead.
Below is an example of how to use a mask to make your "brick" shape. In your case, you would replace the sample I have used with your "HappySmile" image.
<svg width="600" height="400">
<defs>
<mask id="lozenge">
<circle cx="15" cy="15" r="15" fill="white"/>
<rect x="15" y="0" width="67" height="30" fill="white"/>
<circle cx="82" cy="15" r="15" fill="white"/>
</mask>
<image id="brick1" width="97" height="30" xlink:href="http://lorempixel.com/output/abstract-q-c-97-30-9.jpg" mask="url(#lozenge)"/>
</defs>
<use xlink:href="#brick1" x="50" y="50"/>
<use xlink:href="#brick1" x="150" y="50"/>
<use xlink:href="#brick1" x="250" y="50"/>
<use xlink:href="#brick1" x="350" y="50"/>
<use xlink:href="#brick1" x="450" y="50"/>
<use xlink:href="#brick1" x="50" y="100"/>
<use xlink:href="#brick1" x="150" y="100"/>
<use xlink:href="#brick1" x="250" y="100"/>
<use xlink:href="#brick1" x="350" y="100"/>
<use xlink:href="#brick1" x="450" y="100"/>
<use xlink:href="#brick1" x="50" y="150"/>
<use xlink:href="#brick1" x="150" y="150"/>
<use xlink:href="#brick1" x="250" y="150"/>
<use xlink:href="#brick1" x="350" y="150"/>
<use xlink:href="#brick1" x="450" y="150"/>
</svg>

Related

SVG animation (blinking) inside of animation (blinking)

So i have page 1 and page 2 which are animated, inside of page 2 there is also animation but problem is that this object shows when page 2 is "hidden". How to prevent that ??
Black square should only be visible when page 2 is visible, but it ignores parent style.
<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 612 792" style="enable-background:new 0 0 612 792;" xml:space="preserve">
<rect x="0.5" y="0.167" fill="#ccc" stroke="#000" width="100" height="100"/>
<!-- square -->
<g>
<!-- page 1 -->
<g id="page_one" style="z-index:1">
<rect x="25" y="5" width="50" height="50" fill="red" style=""></rect>
</g>
<!-- page 2 -->
<g id="page_two" style="z-index:-1">
<rect x="25" y="5" width="50" height="50" fill="white" style=""></rect>
<g transform="scale(2.9) translate(6,0)">
<g transform="scale(0.205)translate(1,1)">
<!-- animation inside page 2 -->
<g style="z-index:-1">
<animate attributeName="visibility" dur="2" repeatCount="indefinite" keyTimes="0;0.5;1" values="visible;hidden;visible"></animate>
<rect x="25" y="15" width="50" height="50" fill="black" style=""></rect>
</g>
</g>
</g>
</g>
<!-- animate page 1 & 2 -->
<animate xlink:href="#page_one" attributeName="visibility" values="visible;hidden" dur="4s" begin="0s" repeatCount="indefinite"></animate>
<animate xlink:href="#page_two" attributeName="visibility" values="hidden;visible" dur="4s" begin="0s" repeatCount="indefinite"></animate>
</g>
</svg>
Tried some css styling, z-index but nothing solved issue.
animate the display property instead.
<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 612 792" style="enable-background:new 0 0 612 792;" xml:space="preserve">
<rect x="0.5" y="0.167" fill="#ccc" stroke="#000" width="100" height="100"/>
<!-- square -->
<g>
<!-- page 1 -->
<g id="page_one" style="z-index:1">
<rect x="25" y="5" width="50" height="50" fill="red" style=""></rect>
</g>
<!-- page 2 -->
<g id="page_two" style="z-index:-1">
<rect x="25" y="5" width="50" height="50" fill="white" style=""></rect>
<g transform="scale(2.9) translate(6,0)">
<g transform="scale(0.205)translate(1,1)">
<!-- animation inside page 2 -->
<g style="z-index:-1">
<animate attributeName="display" dur="2" repeatCount="indefinite" keyTimes="0;0.5;1" values="block;none;block"></animate>
<rect x="25" y="15" width="50" height="50" fill="black" style=""></rect>
</g>
</g>
</g>
</g>
<!-- animate page 1 & 2 -->
<animate xlink:href="#page_one" attributeName="display" values="block;none" dur="4s" begin="0s" repeatCount="indefinite"></animate>
<animate xlink:href="#page_two" attributeName="display" values="none;block" dur="4s" begin="0s" repeatCount="indefinite"></animate>
</g>
</svg>

SVG bump point when animated line hover it

below i create a simple fiddle with svg animation:
<svg width="250" height="250" viewbox="0 0 20 20">
<line x1="10" y1="0" x2="10" y2="10"style="stroke:rgb(255,0,0); stroke-width:1">
<animateTransform attributeType="xml" attributeName="transform" type="rotate" from="0 10 10" to="360 10 10" dur="7.5s" repeatCount="indefinite" />
</line>
<circle cx="5" cy="5" r="1" style="fill:rgb(0,255,0);"/>
<circle cx="15" cy="15" r="1" style="fill:rgb(0,0,255);"/>
</svg>
My question is: is there a way that I can make blue and red point bump (change their color for example) when red line hover them?
Thank you
This is my solution: I'm creating a mask with the line. There are 2 extra circles (fill:gold) that are masked by the line.
I'm putting the animated line inside a <g stroke="red"> because I want the used line to be white.
svg{border:1px solid;}
<svg width="250" height="250" viewbox="0 0 20 20">
<circle cx="5" cy="5" r="1" style="fill:rgb(0,255,0);" />
<circle cx="15" cy="15" r="1" style="fill:rgb(0,0,255);"/>
<mask id="mask">
<use xlink:href="#L" style="stroke:white"/>
</mask>
<g stroke="red">
<line id="L" x1="10" y1="0" x2="10" y2="10" >
<animateTransform attributeType="xml" attributeName="transform" type="rotate" from="0 10 10" to="360 10 10" dur="7.5s" repeatCount="indefinite" />
</line>
</g>
<g style="fill:gold;mask: url(#mask)">
<circle cx="5" cy="5" r="1" />
<circle cx="15" cy="15" r="1"/>
</g>
</svg>

Rotate the direction of motion of a rect using animateMotion in SVG

I want the yellow rectangle to be rotated 45 degrees (which it is), but I also want the direction of motion to rotate, so that the yellow rectangle appear to go "downhill" (down the blue line). I don't want it to keep moving horizontally.
<svg width="800" height="400" viewBox="0 0 800 400"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" >
<!-- decorative circles for the ends of the blue line. -->
<g transform="rotate(45, 400, 200)">
<path id="myPath" d="M150,200 L650,200" fill="none"
stroke="blue" stroke-width="5.6" />
<circle cx="150" cy="200" r="8.94" fill="blue" />
<circle cx="650" cy="200" r="8.94" fill="blue" />
</g>
<g>
<rect x="0" y="0"
fill="yellow" stroke="red" width="84" height="56"></rect>
<animateMotion dur="4s" repeatCount="1" rotate="45"
path="M150,200 L650,200" >
</animateMotion>
</g>
</svg>
Another way to do this is to put <mpath xlink:href="#myPath" /> as a sub-element of the animateMotion SVG element. In that case you can leave out path="M150,200 L650,200".
You mean like this? I've moved the animateMotion so it only applies to the rect and added a transform to the containing <g> element. I could have just put the rect in the other <g> element I guess which would have been simpler.
<svg width="800" height="400" viewBox="0 0 800 400"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" >
<!-- decorative circles for the ends of the blue line. -->
<g transform="rotate(45, 400, 200)">
<path id="myPath" d="M150,200 L650,200" fill="none"
stroke="blue" stroke-width="5.6" />
<circle cx="150" cy="200" r="8.94" fill="blue" />
<circle cx="650" cy="200" r="8.94" fill="blue" />
</g>
<g transform="rotate(45, 400, 200)">
<rect x="0" y="0"
fill="yellow" stroke="red" width="84" height="56">
<animateMotion dur="4s" repeatCount="1"
path="M150,200 L650,200" >
</animateMotion>
</rect>
</g>
</svg>

Firefox renders SVG rotated patterns with lines along the seams

So the goal here is to have a 2 color diagonal hatch pattern that can be rotated to arbitrary angles dynamically (fyi it's being applied to a D3 map w/zooming).
I found the "SVG Pattern Contains Whitespace Between Repetitions in Firefox(1) question, however the solution is not very flexible rotation-wise and I couldn't make it work with the 2 colors bars.
Here's a jsfiddle test case.. The first 4 are my technique rotated differently. The last one is an attempt to adapt follow the previously mentioned answer's advice.
Chrome renders it fine(2) (as does Safari and IE).
But Firefox has these nasty lines where it tiles, but only when the pattern is rotated to something other than 90deg increments.
Any ideas?
Here's the contents of the Jsfiddle:
<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd">
<svg xml:space="preserve" width="925" height="810" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<pattern id="hatch" width="10" height="10" patternUnits="userSpaceOnUse">
<line x1="0" y1="0" x2="0" y2="10" style="stroke:black; stroke-width:16" />
<line x1="13" y1="0" x2="13" y2="10" style="stroke:gray; stroke-width:16" />
</pattern>
<pattern id="hatch45" width="10" height="10" patternTransform="rotate(5 0 0)" patternUnits="userSpaceOnUse">
<line x1="-2" y1="-2" x2="-2" y2="12" style="stroke:black; stroke-width:16" overflow="visible" />
<line x1="12" y1="-2" x2="12" y2="12" style="stroke:gray; stroke-width:16" overflow="visible" />
</pattern>
<pattern id="hatch80" width="10" height="10" patternTransform="rotate(80 0 0)" patternUnits="userSpaceOnUse">
<line x1="0" y1="0" x2="0" y2="10" style="stroke:black; stroke-width:16" />
<line x1="13" y1="0" x2="13" y2="10" style="stroke:gray; stroke-width:16" />
</pattern>
<pattern id="hatch90" width="10" height="10" patternTransform="rotate(90 0 0)" patternUnits="userSpaceOnUse">
<line x1="0" y1="0" x2="0" y2="10" style="stroke:black; stroke-width:16" />
<line x1="13" y1="0" x2="13" y2="10" style="stroke:gray; stroke-width:16" />
</pattern>
<pattern x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" id="line-fill" viewBox="0 0 20 20" overflow="visible" patternTransform="rotate(80 0 0)">
<g stroke-width="20">
<line x1="0" y1="-10" x2="0" y2="30" stroke="black" />
<line x1="20" y1="-10" x2="20" y2="30" stroke="gray" />
</g>
</pattern>
</defs>
<g>
<rect style="fill:url(#hatch45);" x="10" y="0" width="200" height="130" />
<rect style="fill:url(#hatch80);" x="10" y="150" width="200" height="130" />
<rect style="fill:url(#hatch90);" x="10" y="300" width="200" height="130" />
<rect style="fill:url(#hatch);" x="10" y="450" width="200" height="130" />
<rect style="fill:url(#line-fill);" x="10" y="600" width="200" height="130" />
</g>
</svg>
1: stackoverflow.com/questions/19391071/svg-pattern-contains-whitespace-between-repetitions-in-firefox
2: imgur.com/c8SxdGG

Does SVG support embedding of bitmap images?

Is an SVG image purely vectorial or can we combine bitmap images into an SVG image ?
How about transforms applied on the bitmap images (perspective, mappings, etc.) ?
Edit: Images may be included in an SVG by link reference. See http://www.w3.org/TR/SVG/struct.html#ImageElement. My question was in fact if bitmap images may be included inside the svg so that the svg image would be self contained. Otherwise, whenever the svg image is displayed the link must be followed and the image downloaded. Apparently .svg files are simply xml files.
Yes, you can reference any image from the image element. And you can use data URIs to make the SVG self-contained. An example:
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
...
<image
width="100" height="100"
xlink:href="data:image/png;base64,IMAGE_DATA"
/>
...
</svg>
The svg element attribute xmlns:xlink declares xlink as a namespace prefix and says where the definition is. That then allows the SVG reader to know what xlink:href means.
The IMAGE_DATA is where you'd add the image data as base64-encoded text. Vector graphics editors that support SVG usually have an option for saving with images embedded. Otherwise there are plenty of tools around for encoding a byte stream to and from base64.
Here's a full example from the SVG testsuite.
I posted a fiddle here, showing data, remote and local images embedded in SVG, inside an HTML page:
http://jsfiddle.net/MxHPq/
<!DOCTYPE html>
<html>
<head>
<title>SVG embedded bitmaps in HTML</title>
<style>
body{
background-color:#999;
color:#666;
padding:10px;
}
h1{
font-weight:normal;
font-size:24px;
margin-top:20px;
color:#000;
}
h2{
font-weight:normal;
font-size:20px;
margin-top:20px;
}
p{
color:#FFF;
}
svg{
margin:20px;
display:block;
height:100px;
}
</style>
</head>
<body>
<h1>SVG embedded bitmaps in HTML</h1>
<p>The trick appears to be ensuring the image has the correct width and height atttributes</p>
<h2>Example 1: Embedded data</h2>
<svg id="example1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<image x="0" y="0" width="5" height="5" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="/>
</svg>
<h2>Example 2: Remote image</h2>
<svg id="example2" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<image x="0" y="0" width="275" height="95" xlink:href="http://www.google.co.uk/images/srpr/logo3w.png" />
</svg>
<h2>Example 3: Local image</h2>
<svg id="example3" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<image x="0" y="0" width="136" height="23" xlink:href="/img/logo.png" />
</svg>
</body>
</html>
You could use a Data URI to supply the image data, for example:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<image width="20" height="20" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="/>
</svg>
The image will go through all normal svg transformations.
But this technique has disadvantages, for example the image will not be cached by the browser
You can use a data: URL to embed a Base64 encoded version of an image. But it's not very efficient and wouldn't recommend embedding large images. Any reason linking to another file is not feasible?
If you want to use that image multiple times inside SVG (Ref.):
<image id="img" xlink:href="data:image/png;base64,BASE64_DATA" />
<use href="#img" />
<use href="#img" />
It is also possible to include bitmaps. I think you also can use transformations on that.
I've come up with multiple solutions for drawing a space invader in SVG:
The first method makes use of a path with stroke-width="1". By repeatedly stopping and starting the line we can construct a bitmap image by traversing the scanlines. This has the drawback that the y-coordinate of each "dot" is shifted up by 0.5 pixels because the "y" coordinate is treated as the middle of stroke-width="1".
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<path
stroke="black"
fill="none"
d="M 4 4 l 1 0
M 10 4 l 1 0
M 5 5 l 1 0
M 9 5 l 1 0
M 4 6 l 7 0
M 3 7 l 2 0
M 6 7 l 3 0
M 10 7 l 2 0
M 2 8 l 11 0
M 2 9 l 1 0
M 4 9 l 7 0
M 12 9 l 1 0
M 2 10 l 1 0
M 4 10 l 1 0
M 10 10 l 1 0
M 12 10 l 1 0
M 5 11 l 2 0
M 8 11 l 2 0"
/>
</svg>
The second is through the use of <marker> with marker-start, marker-mid, and marker-end attributes:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<defs>
<marker
id="dot"
viewBox="0 0 1 1"
refX="0.5"
refY="0.5"
markerWidth="1"
markerHeight="1">
<rect width="1" height="1" />
</marker>
</defs>
<polyline
points="4 4 10 4
5 5 9 5
4 6 5 6 6 6 7 6 8 6 9 6 10 6
3 7 4 7 6 7 7 7 8 7 10 7 11 7
2 8 3 8 4 8 5 8 6 8 7 8 8 8 9 8 10 8 11 8 12 8
2 9 4 9 5 9 6 9 7 9 8 9 9 9 10 9 12 9
2 10 4 10 10 10 12 10
5 11 6 11 8 11 9 11"
fill="none"
stroke="none"
marker-start="url(#dot)"
marker-mid="url(#dot)"
marker-end="url(#dot)" />
</svg>
The third method is by defining a <rect> and then refer to it repeatedly with <use>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<g fill="none"><rect id="dot" width="1" height="1"/></g>
<g fill="black">
<use href="#dot" x="4" y="4"/>
<use href="#dot" x="10" y="4"/>
<use href="#dot" x="5" y="5"/>
<use href="#dot" x="9" y="5"/>
<use href="#dot" x="4" y="6"/>
<use href="#dot" x="5" y="6"/>
<use href="#dot" x="6" y="6"/>
<use href="#dot" x="7" y="6"/>
<use href="#dot" x="8" y="6"/>
<use href="#dot" x="9" y="6"/>
<use href="#dot" x="10" y="6"/>
<use href="#dot" x="3" y="7"/>
<use href="#dot" x="4" y="7"/>
<use href="#dot" x="6" y="7"/>
<use href="#dot" x="7" y="7"/>
<use href="#dot" x="8" y="7"/>
<use href="#dot" x="10" y="7"/>
<use href="#dot" x="11" y="7"/>
<use href="#dot" x="2" y="8"/>
<use href="#dot" x="3" y="8"/>
<use href="#dot" x="4" y="8"/>
<use href="#dot" x="5" y="8"/>
<use href="#dot" x="6" y="8"/>
<use href="#dot" x="7" y="8"/>
<use href="#dot" x="8" y="8"/>
<use href="#dot" x="9" y="8"/>
<use href="#dot" x="10" y="8"/>
<use href="#dot" x="11" y="8"/>
<use href="#dot" x="12" y="8"/>
<use href="#dot" x="2" y="9"/>
<use href="#dot" x="4" y="9"/>
<use href="#dot" x="5" y="9"/>
<use href="#dot" x="6" y="9"/>
<use href="#dot" x="7" y="9"/>
<use href="#dot" x="8" y="9"/>
<use href="#dot" x="9" y="9"/>
<use href="#dot" x="10" y="9"/>
<use href="#dot" x="12" y="9"/>
<use href="#dot" x="2" y="10"/>
<use href="#dot" x="4" y="10"/>
<use href="#dot" x="10" y="10"/>
<use href="#dot" x="12" y="10"/>
<use href="#dot" x="5" y="11"/>
<use href="#dot" x="6" y="11"/>
<use href="#dot" x="8" y="11"/>
<use href="#dot" x="9" y="11"/>
</g>
</svg>
A refinement of the <rect> <use> solution above is to define binary permutations that can be reused later. This style kinda harks back to the days of 8-bit programming with sprites:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<g fill="none">
<g id="s0001"><rect x="3" width="1" height="1"/></g>
<g id="s0010"><rect x="2" width="1" height="1"/></g>
<g id="s0011"><rect x="2" width="2" height="1"/></g>
<g id="s0100"><rect x="1" width="1" height="1"/></g>
<g id="s0110"><rect x="1" width="2" height="1"/></g>
<g id="s1000"><rect width="1" height="1"/></g>
<g id="s1011"><rect width="1" height="1"/><rect x="2" width="2" height="1"/></g>
<g id="s1100"><rect width="2" height="1"/></g>
<g id="s1101"><rect width="2" height="1"/><rect x="2" width="1" height="1"/></g>
<g id="s1110"><rect width="3" height="1"/></g>
<g id="s1111"><rect width="4" height="1"/></g>
</g>
<g fill="black">
<use href="#s1000" x="4" y="4"/>
<use href="#s0010" x="8" y="4"/>
<use href="#s0100" x="4" y="5"/>
<use href="#s0100" x="8" y="5"/>
<use href="#s1111" x="4" y="6"/>
<use href="#s1110" x="8" y="6"/>
<use href="#s0001" x="0" y="7"/>
<use href="#s1011" x="4" y="7"/>
<use href="#s1011" x="8" y="7"/>
<use href="#s0011" x="0" y="8"/>
<use href="#s1111" x="4" y="8"/>
<use href="#s1111" x="8" y="8"/>
<use href="#s1000" x="12" y="8"/>
<use href="#s0010" x="0" y="9"/>
<use href="#s1111" x="4" y="9"/>
<use href="#s1101" x="8" y="9"/>
<use href="#s1000" x="12" y="9"/>
<use href="#s0010" x="0" y="10"/>
<use href="#s1000" x="4" y="10"/>
<use href="#s0010" x="8" y="10"/>
<use href="#s1000" x="12" y="10"/>
<use href="#s0110" x="4" y="11"/>
<use href="#s1100" x="8" y="11"/>
</g>
</svg>

Resources