Dynamically find the path of SVG - css
I have this SVG file
I want to know the equation of the line. is it possible? I need the equation to dynamically add some SVG points on this line in different positions. So, in that case, I know the x value but I need to calculate the y value.
Here is the source of the SVG file:
<?xml version="1.0" encoding="UTF-8"?>
<svg width="1366px" height="332px" viewBox="0 0 1366 332" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 55.1 (78136) - https://sketchapp.com -->
<title>#0.5xTimeline - Deactivated</title>
<desc>Created with Sketch.</desc>
<g id="🖥-Design---Desktop" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="02-About-Us" transform="translate(0.000000, -989.000000)" fill-rule="nonzero" stroke="#EFEFEF" stroke-width="11">
<g id="HISTORY" transform="translate(-28.000000, 813.000000)">
<g id="Graphic---Timeline" transform="translate(0.000000, 182.000000)">
<path d="M0,38.8855723 C99.4313478,-10.5096141 202.976477,-12.845873 310.635387,31.8767959 C472.123752,98.9607991 512.237609,231.556286 773.130376,301.214063 C1034.02314,370.871839 1355.95795,229.12379 1417,164.042295" id="Timeline---Deactivated"></path>
</g>
</g>
</g>
</g>
</svg>
If you know that you have a function, that is a path that only ever goes left-to-right and never doubles back on itself, then you can scan along its length until you find the x-value that you want.
const x = 100; // known x-value
const path = document.getElementById('Timeline---Deactivated');
const pathLength = path.getTotalLength();
const range = [0, pathLength];
let guess, result;
for( let iterations = 0; iterations < 11; iterations++) {
guess = (range[0]+range[1])/2;
result = path.getPointAtLength(guess);
if( result.x < x) {
// target is to the right
range[0] = guess;
}
else range[1] = guess;
}
return result; // SVGPoint with result.x and result.y
The ideal number of iterations is based on the possible range of X values. In your case the path ends at (1417,164), so iterations should go to ceil(log_2(1417)) which is 11. If you have bigger graphs, you might need to make it 12, or you can just set it to 20 or something. It's not like it takes that many more steps to keep a high accuracy result.
Related
SVG with marker having an issue on mouse over
I have a button with svg inside like: <button> Checkout <ArrowSvg /> </button> And ArrowSvg looks like this (line has class: svg-line): <svg fill="none" stroke="#000"> <defs> <marker id="m" overflow="visible"> <path d="M-4,-4L0,0 -4,4" /> </marker> </defs> <line x1="0" y1="50%" x2="100%" y2="50%"marker-end="url(#m)" class="svg-line" /> </svg> When button is hovered, I change the stroke color: btn:hover > .svg-line { stroke: blue; } It's working well - when I hover the button, the arrow (line and arrow head) turns blue. But when I display the multiple buttons (more than 1), hovering 1 button affects arrows in other buttons. The arrow head part (which is marker/path in svg?) of all the buttons get affected when hovering the first button. I am also working with the arrow width, so I need line. I can't make everything with path because I won't be able to expand the arrow width. Am I missing anything? Why am I seeing this issue?
Wrap it in a native JS Web Component, supported in all modern browsers, to create the <svg> because every SVG requires a unique marker ID note: the SVG is created for every instance, no need for a marker at all, use the path by itself customElements.define("svg-button",class extends HTMLElement{ connectedCallback(){ let id = "id" + (Math.floor(Math.random() * 1e10)); let stroke = this.getAttribute("stroke") || "#000"; this.innerHTML = ` <button> Checkout <svg fill="none" stroke="${stroke}" viewBox="0 0 10 10"> <defs> <marker id="${id}" overflow="visible"> <path d="M-4,-4L0,0 -4,4"/> </marker> </defs> <line x1="0" y1="5" x2="9" y2="5" marker-end="url(#${id})"/> </svg> </button>` } }); <style> button:hover svg { stroke:gold; } </style> <svg-button></svg-button> <svg-button stroke="red"></svg-button> <svg-button stroke="green"></svg-button> <svg-button stroke="blue"></svg-button>
What you are writing looks like .JSX syntax, but the question is lacking a react tag. I will assume it for this answer anyway, but other frameworks using the format will probably work comparably. All you need is a unique id for the <marker> element. This is easily done if you spell out the <ArrowSvg> as a function. Then, wrap it in a factory function to form a closure over a running number: const ArrowSvg = (() => { let id = 0; return function (props) { return ( const ref = 'arrowMarker' + ++id; <svg fill="none" stroke="#000"> <defs> <marker id=(ref) overflow="visible"> <path d="M-4,-4L0,0 -4,4" /> </marker> </defs> <line x1="0" y1="50%" x2="100%" y2="50%" marker-end=(`url(#${ref})`) class="svg-line" /> </svg> ); } })();
Having many SVG DomMarkers in HERE maps causes lag
I'm using HERE maps 3.0 (also tried 3.1 and have the same issue) with the default layers in an angular project. The map has DomMarkers using a complex SVG icon with many paths inside a div. I noticed that adding many markers (over 200) causes a lag when zooming or moving around the map. I'm using SVG instead of static image files to be able to change the colour and modify the shape of the icon before adding it to the map. Using a dom icon with multiple divs shaped with CSS instead of the SVG, results in the same lag. If I use a more simple SVG or a simple div, the lag is reduced significantly. What's causing the lag? Is it caused by the complexity of the SVG, or the large and many paths it has? Is there a way to have complex SVG markers and eliminate the lag? My SVG: <?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_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-656 895.2 221.2 259.8" style="enable-background:new -656 895.2 221.2 259.8;" xml:space="preserve"> <g> <path fill="white" d="M-489.9,937.4c-15.8-16.3-36.6-25.3-58.5-25.3c-46.8,0-84.8,41.1-84.8,91.6c0,13.3,2.5,25.9,7.4,37.2 c12.9,30.9,48.3,84.6,68,109.5c2.3,2.9,5.7,4.6,9.4,4.6c3.5,0,6.7-1.5,9.1-4.2l0.1-0.2l0.1-0.2c19.5-24.5,54.8-77.9,68-109.4 c4.9-11.9,7.3-24.4,7.3-37.1C-463.6,978.7-472.9,954.9-489.9,937.4z M-478.3,1037.8c-12.5,29.9-47,82.5-66.8,107.4 c-0.9,1-2,1.6-3.3,1.6c-1.3,0-2.5-0.6-3.3-1.6c-19.7-24.9-54.3-77.6-66.8-107.6c-4.5-10.5-6.7-21.9-6.7-34 c0-46,34.5-83.5,76.9-83.5s76.9,37.4,76.7,83.7C-471.6,1015.9-473.9,1027.4-478.3,1037.8z"/> <path fill="#775DD0" d="M-548.3,920.4c-42.4,0-76.9,37.4-76.9,83.5c0,12,2.2,23.4,6.7,34c12.5,30,47.1,82.6,66.8,107.6 c0.8,1,2,1.6,3.3,1.6c1.3,0,2.4-0.6,3.3-1.6c19.9-24.8,54.4-77.5,66.9-107.5c4.4-10.6,6.7-22.1,6.7-34 C-471.4,957.7-505.9,920.4-548.3,920.4z"/> </g> <g> <path fill="white" d="M-454.5,1067.8h-47.8c-10.9,0-19.7,8.9-19.7,19.7v47.8c0,10.9,8.9,19.7,19.7,19.7h47.8 c10.9,0,19.7-8.9,19.7-19.7v-47.8C-434.8,1076.7-443.6,1067.8-454.5,1067.8z M-444.8,1135.4c0,5.4-4.3,9.7-9.7,9.7h-47.8 c-5.4,0-9.7-4.4-9.7-9.7v-47.8c0-5.4,4.3-9.7,9.7-9.7h47.8c5.3,0,9.7,4.4,9.7,9.7V1135.4z"/> <path fill="#775DD0" d="M-454.5,1077.8h-47.8c-5.4,0-9.7,4.4-9.7,9.7v47.8c0,5.4,4.3,9.7,9.7,9.7h47.8c5.4,0,9.7-4.4,9.7-9.7v-47.8 C-444.8,1082.2-449.2,1077.8-454.5,1077.8z"/> <path fill="white" d="M-461.6,1094.7l-22,24.8l-11-12.4c-2-2.2-5.3-2.2-7.4,0c-2,2.2-2,6,0,8.3l14.7,16.5 c2,2.2,5.3,2.2,7.4,0l25.7-29c2.1-2.3,2.1-6.1,0-8.3C-456.2,1092.4-459.5,1092.4-461.6,1094.7z"/> </g> <g> <path fill="white" d="M-478.1,941.6c-6.7,0-19.9,3.7-20,10.3c4.3,6.5,11.7,10.7,20,10.7s15.7-4.3,20-10.7 C-458.2,945.2-471.5,941.6-478.1,941.6z M-478.1,952.6c-1.3,0-2.6-0.2-3.9-0.6c1.4-0.3,2.7-0.5,3.9-0.5s2.5,0.2,3.9,0.5 C-475.5,952.4-476.8,952.6-478.1,952.6z"/> <path fill="white" d="M-478.1,895.2c-23.9,0-43.3,19.4-43.3,43.4s19.4,43.3,43.3,43.3s43.3-19.4,43.3-43.3S-454.2,895.2-478.1,895.2 z M-478.1,971.9c-18.4,0-33.3-14.9-33.3-33.4c0-18.4,14.9-33.3,33.3-33.3s33.3,14.9,33.3,33.3C-444.8,957-459.7,971.9-478.1,971.9z "/> <path fill="white" d="M-478.1,935.2c5.5,0,10-4.5,10-10c0-5.5-4.5-10-10-10s-10,4.5-10,10C-488.2,930.7-483.7,935.2-478.1,935.2z"/> <path d="M-478.1,905.2c-18.4,0-33.3,14.9-33.3,33.3c0,18.4,14.9,33.4,33.3,33.4s33.3-14.9,33.3-33.4 C-444.8,920.1-459.7,905.2-478.1,905.2z M-478.1,915.2c5.5,0,10,4.5,10,10c0,5.5-4.5,10-10,10s-10-4.5-10-10 C-488.2,919.7-483.7,915.2-478.1,915.2z M-478.1,962.6c-8.4,0-15.7-4.3-20-10.7c0.1-6.6,13.4-10.3,20-10.3s19.9,3.7,20,10.3 C-462.5,958.3-469.8,962.6-478.1,962.6z"/> </g> <g> <path fill="white" d="M-572.4,927.7c0.3-1,0.5-2.1,0.5-3.2c0-2.7-1.1-5.2-2.9-7.1l-4.8-4.7c-1.2-1.2-2.7-2-4.2-2.5 c-0.5-1.5-1.3-3-2.5-4.2l-4.7-4.8c-1.9-1.9-4.4-2.9-7.1-2.9c0,0,0,0,0,0c-1.1,0-2.2,0.2-3.2,0.5c-1.8-2.2-4.6-3.6-7.7-3.6h-6.7 c-3.1,0-5.9,1.4-7.7,3.6c-1-0.3-2.1-0.5-3.2-0.5c0,0,0,0,0,0c-2.7,0-5.2,1.1-7.1,2.9l-4.7,4.8c-1.2,1.2-2,2.7-2.5,4.2 c-1.5,0.5-3,1.3-4.2,2.5l-4.8,4.7c-1.9,1.9-2.9,4.4-2.9,7.1c0,1.1,0.2,2.2,0.5,3.2c-2.2,1.8-3.6,4.6-3.6,7.7v6.7 c0,3.1,1.4,5.9,3.6,7.7c-0.3,1-0.5,2.1-0.5,3.2c0,2.7,1.1,5.2,2.9,7.1l4.8,4.7c1.2,1.2,2.7,2,4.2,2.5c0.5,1.5,1.3,3,2.5,4.2 l4.7,4.8c1.9,1.9,4.4,2.9,7.1,2.9c0,0,0,0,0,0c1.1,0,2.2-0.2,3.2-0.5c1.8,2.2,4.6,3.6,7.7,3.6h6.7c3.1,0,5.9-1.4,7.7-3.6 c1,0.3,2.1,0.5,3.2,0.5c0,0,0,0,0,0c2.7,0,5.2-1.1,7.1-2.9l4.7-4.8c1.2-1.2,2-2.7,2.5-4.2c1.5-0.5,3-1.3,4.2-2.5l4.8-4.7 c1.9-1.9,2.9-4.4,2.9-7.1c0-1.1-0.2-2.2-0.5-3.2c2.2-1.8,3.6-4.6,3.6-7.7v-6.7C-568.8,932.3-570.2,929.6-572.4,927.7z M-578.8,942.2h-14l10.9,10.9l-4.8,4.7l-15.6-15.6h-6.7v6.7l15.6,15.6l-4.7,4.8l-10.9-10.9v14h-6.7v-14l-10.9,10.9l-4.7-4.8 l15.6-15.6v-6.7h-6.7l-15.6,15.6l-4.8-4.7l10.9-10.9h-14v-6.7h14l-10.9-10.9l4.8-4.7l15.6,15.6h6.7v-6.7l-15.6-15.6l4.7-4.8 l10.9,10.9v-14h6.7v14l10.9-10.9l4.7,4.8l-15.6,15.6v6.7h6.7l15.6-15.6l4.8,4.7l-10.9,10.9h14V942.2z"/> <polygon points="-581.9,924.5 -586.7,919.8 -602.3,935.4 -609,935.4 -609,928.7 -593.4,913.1 -598.1,908.3 -609,919.2 -609,905.2 -615.8,905.2 -615.8,919.2 -626.7,908.3 -631.4,913.1 -615.8,928.7 -615.8,935.4 -622.5,935.4 -638.1,919.8 -642.9,924.5 -632,935.4 -646,935.4 -646,942.2 -632,942.2 -642.9,953.1 -638.1,957.8 -622.5,942.2 -615.8,942.2 -615.8,948.9 -631.4,964.5 -626.7,969.3 -615.8,958.4 -615.8,972.4 -609,972.4 -609,958.4 -598.1,969.3 -593.4,964.5 -609,948.9 -609,942.2 -602.3,942.2 -586.7,957.8 -581.9,953.1 -592.8,942.2 -578.8,942.2 -578.8,935.4 -592.8,935.4 "/> </g> <g> <path fill="white" d="M-537.3,987.5c-1.9,0-3.4,1.5-3.4,3.4c0,1.9,1.5,3.4,3.4,3.4c1.9,0,3.4-1.5,3.4-3.4 C-533.9,989-535.4,987.5-537.3,987.5z"/> <path fill="white" d="M-557.5,987.5c-1.9,0-3.4,1.5-3.4,3.4c0,1.9,1.5,3.4,3.4,3.4s3.4-1.5,3.4-3.4 C-554.2,989-555.7,987.5-557.5,987.5z"/> <path fill="white" d="M-513.8,997.6c0-6.7-2.1-13.3-5.8-18.8l0.3-0.3c3.9-3.9,3.9-10.2,0-14.1l-2.8-2.8c-1.9-1.9-4.4-2.9-7.1-2.9 s-5.2,1.1-7.1,2.9l-3.3,3.3c-2.6-0.6-5.2-1-7.9-1c-2.7,0-5.3,0.3-7.9,1l-3.3-3.3c-2-2-4.5-2.9-7.1-2.9s-5.1,1-7.1,2.9l-2.8,2.8 c-3.9,3.9-3.9,10.2,0,14.1l0.3,0.3c-3.7,5.5-5.8,12-5.8,18.8v3.4c0,0.6,0,1.1,0.1,1.7c-0.1,0.5-0.1,1.1-0.1,1.7v13.5 c0,18.5,15.1,33.6,33.6,33.6s33.6-15.1,33.6-33.6v-13.5c0-0.6,0-1.1-0.1-1.7c0.1-0.5,0.1-1.1,0.1-1.7V997.6z M-523.8,1017.9 c0,13.1-10.6,23.6-23.6,23.6c-13.1,0-23.6-10.6-23.6-23.6v-13.5h47.3V1017.9z M-523.8,1001H-571v-3.4c0-7.8,3.9-14.7,9.7-19 l-7.1-7.1l2.8-2.8l7.8,7.8c3.2-1.6,6.7-2.5,10.5-2.5s7.3,1,10.5,2.5l7.8-7.8l2.8,2.8l-7.1,7.1c5.9,4.3,9.7,11.2,9.7,19V1001z"/> <path fill="#775DD0" d="M-571,1017.9c0,13.1,10.6,23.6,23.6,23.6c13.1,0,23.6-10.6,23.6-23.6v-13.5H-571V1017.9z"/> <path fill="#775DD0" d="M-533.5,978.6l7.1-7.1l-2.8-2.8l-7.8,7.8c-3.2-1.6-6.7-2.5-10.5-2.5s-7.3,1-10.5,2.5l-7.8-7.8l-2.8,2.8l7.1,7.1 c-5.9,4.3-9.7,11.2-9.7,19v3.4h47.3v-3.4C-523.8,989.8-527.6,982.9-533.5,978.6z M-557.5,994.2c-1.9,0-3.4-1.5-3.4-3.4 c0-1.9,1.5-3.4,3.4-3.4s3.4,1.5,3.4,3.4C-554.2,992.7-555.7,994.2-557.5,994.2z M-537.3,994.2c-1.9,0-3.4-1.5-3.4-3.4 c0-1.9,1.5-3.4,3.4-3.4c1.9,0,3.4,1.5,3.4,3.4C-533.9,992.7-535.4,994.2-537.3,994.2z"/> </g> </svg> The markers are added from a for loop to a group (H.map.Group) that was already added in the map. The lag is happening not while loading the markers, but when trying to move around the map or zoom in and out. It's very laggy especially when zoomed out and many markers are visible. adding the group in the map: this.map.addObject(this.markerGroup); adding a marker: addMarker(data) { const id = data.id; if (!mapObjects[id]) { let coords; coords = { lat: data.lat, lng: data.lon }; const icon = new H.map.DomIcon(this.createMarkerIcon(data)); this.mapObjects[id] = new H.map.DomMarker(coords, { icon: icon }); this.mapObjects[id].setData(data); this.markerGroup.addObject(this.mapObjects[id]); } else if (this.markerChanged(data)) { this.updateMarker(data); } } loop that adds the markers: markers.forEach(markerData => { this.addMarker(markerData); }); edit: svg added, snippets added
Caching could help you to avoid this zoom out lag. reading larger marker data again and again with complex svg making it laggy. you can try to store the markers in one variable and cache it if the data is not changing all the time, like below var testObject = { 'one': 1, 'two': 2, 'three': 3 }; // Put the object into storage localStorage.setItem('testObject', JSON.stringify(testObject)); // Retrieve the object from storage var retrievedObject = localStorage.getItem('testObject');
The problem was that I used H.map.DomMarker instead of H.map.Marker and the many html elements caused the map to lag. H.map.Markers are rendered on the map and don't cause zooming and moving lag.
Animating SVG Path using CSS instead of <animateMotion>
I am trying to place an arrow on the midpoint of the bezier curve. The solution using <animateMotion> in the question How properly shift arrow head on cubic bezier in SVG to its center , which moves a <path> which is the arrow and freezes it at the middle of the bezier curve, works only in Firefox. As the curve's points keep changing frequently in my case, I didn't want to use marker-mid as it is costly for me to calculate the midpoint of the bezier curve everytime. <svg viewBox="0 0 500 500"> <g> <path id="path1" d="M291.698 268.340 C321.698 268.340, 411.904 93.133 441.904 93.133"></path> <path class="path_arrow" d="M0,0 L6,6 L0,12" transform="translate(-3,-6)"> <animateMotion dur="0s" rotate="auto" fill="freeze" keyTimes="0;1" keyPoints="0.5;0.5"> <mpath xlink:href="#path1"></mpath> </animateMotion> </path> </g> <g transform="translate(166.698,243.340)"> <circle r="5" class="p1"></circle> </g> <g transform="translate(441.904,68.133)" > <circle r="5" class="p2"></circle> </g> </svg> Is there any way to do this using CSS Animations so as to avoid using <animateMotion> ? EDIT 1: The endpoints of the curve here is draggable and so the points of the curve tend to change frequently. The animation is to move the arrow to the center of the curve without calculating the midpoints. EDIT 2: Thanks to Kaiido's comment, I added calcMode="linear" and the arrow is now placed on the path as expected. But When I reposition the end point by dragging, the arrow stays in its initial position(as shown) in Chrome but it is expected to move along the parent path. In Firefox this is working fine as before.
You could achieve the same with CSS offset-path, offset-distance and offset-rotate properties: #path1 { fill: none; stroke: black; } .path_arrow { transform: translate( -3px, -6px ); offset-path: path("M220 104C220 144,400 180,400 224"); offset-rotate: auto; offset-distance: 50%; } body { background: white; } <svg width="500" height="500" > <path id="path1" d="M 220 104 C 220 144 400 180 400 224" fill="none" stroke-width="2" stroke="black" /> <path class="path_arrow" d="M0,0 L0,12 L12,6 z" /> </svg> But their browser support is far lower than the one of SMIL, so I wouldn't recommend it. Note that I did fix the answer there where they were missing a calcMode="linear" attribute to make Blink browsers happy. If you need IE support, you may want to try this js implementation which seems to support <animateMotion> and rotate, keeping in mind I didn't test it myself. Regarding the question's "EDIT 2": Chrome indeed seems to need an explicit call to update the <mpath>. This can be done by calling the beginElement() method of the <animationMotion> element after each update: document.querySelector('svg').onmousemove = function(e) { const rect = this.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; path1.setAttribute( 'd', `M ${x} ${y} C 220 144 400 180 400 224` ); // Chrome requires an explicit update document.querySelector('animateMotion').beginElement(); } <pre style="position: absolute;pointer-events:none">move your mouse to change the path</pre> <svg width="500" height="500" > <path id="path1" d="M 220 104 C 220 144 400 180 400 224" fill="none" stroke-width="2" stroke="black" /> <path d="M0,0 L0,12 L12,6 z" transform="translate(-3,-6)"> <animateMotion dur="0s" rotate="auto" fill="freeze" keyTimes="0;1" keyPoints="0.5;0.5" calcMode="linear" > <mpath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#path1"/> </animateMotion> </path> </svg>
You have to use webkit animation inside the css. Also i would recommend https://codepen.io/collection/yivpx/. Is an open source project for SVG optimization. I also encourage you to name all your classes within your SVG in order to do cool CSS stuff with animate, like: animation: kaboom 5s ease alternate infinite;
Snap.svg: How to select all children of outermost SVG element but not from (possibly) nested SVG elements
I'm trying to get all (direct) children from the outermost SVG element of the fragment - or in other words: all 2nd-leves elements of the fragment. Im using this code: fragment.selectAll("svg>*") This works as long as there is only one SVG element in the given fragment. But if there are nested SVG elements (which is ok according to https://developer.mozilla.org/en-US/docs/Web/SVG/Element/svg ) this returns also elements that are further down in the hierarchical structure - meaning that are 3rd, 4th or of higher levels. <svg id="svg_1" height="380mm" width="490mm" viewBox="0 0 490 380" version="1.0"> <g id="g_1" transform="translate(57.5,47.5)"> <svg id="svg_2" version="1.1" height="5" width="5" viewBox="0 0 5 5"> <path d="m 4.9997035,2.4940359 ... z"/> </svg> </g> <g id="g_2" transform="translate(57.5,97.5)"> <svg id="svg_3" version="1.1" height="5" width="5" viewBox="0 0 5 5"> <path d="m 4.9997035,2.4940359 ... z"/> </svg> </g> ... </svg> I my result, I want only the g elements (ids: g_1 and g_2) but I'm getting also the two path elements. It seems promising to replace the line above with this one: fragment.select("svg").children() However, this one includes a bunch of #text elements which is not included by the original one and I don't know how to remove them from the query result.
Using an svg image with inline data uri
I'm pretty sure this isn't possible, but before giving up I wanted to throw it out there. Here's a fiddle, http://jsfiddle.net/sqszuzep/6/ <svg version="1.1" viewBox="0 0 2 1" width="100%"> <image xlink:href="http://fillmurray.com/600/300" x="0" y="0" height="100%" width="100%"/> </svg> <div id="bg" class="bg"></div> <div id="bg2" class="bg"></div> <h2>IE10/11</h2> <div id="bg3" class="bg"></div> <div id="bg4" class="bg"></div> js: // Chrome/Firefox/Safari var x = encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400"><circle fill="#000000" stroke="#000000" stroke-width="20" cx="105" cy="105" r="90"></circle> <circle fill="none" stroke="#0000FF" stroke-width="10" cx="300" cy="105" r="90"></circle></svg>'); var y = encodeURIComponent('<svg version="1.1" viewBox="0 0 2 1" width="100%"><image xlink:href="http://fillmurray.com/600/300" x="0" y="0" height="100%" width="100%"/></svg>'); $(function () { $('#bg').css('background-image', 'url("data:image/svg+xml;utf8,'+ x +'")'); $('#bg2').css('background-image', 'url("data:image/svg+xml;utf8,'+ y +'")'); }); // IE 10/11 // Chrome/Firefox/Safari var x = btoa('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400"><circle fill="#000000" stroke="#000000" stroke-width="20" cx="105" cy="105" r="90"></circle> <circle fill="none" stroke="#0000FF" stroke-width="10" cx="300" cy="105" r="90"></circle></svg>'); var y = btoa('<svg version="1.1" viewBox="0 0 2 1" width="100%"><image xlink:href="http://fillmurray.com/600/300" x="0" y="0" height="100%" width="100%"/></svg>'); $(function () { $('#bg3').css('background-image', 'url("data:image/svg+xml;base64,'+ x +'")'); $('#bg4').css('background-image', 'url("data:image/svg+xml;base64,'+ y +'")'); }); Essentially I was attempting to use a svg image, encode the svg element and use it in css on an element. This works for vectors, but not for images loaded via svg. I believe this pertains, https://bugs.webkit.org/show_bug.cgi?id=63548 saying that "Images are not allowed to load further resources". What I see is that no browser supports this feature, or I'm doing something wrong. It is possible to base64 encode image data and use that, as demonstrated in this fiddle I wrote: http://jsfiddle.net/N2n27/3/. On browsers that support svg filters (non-IE) this is a handy way to do blurring and other filter effects. Am I missing something here?
There are two issues with the y version. a) the svg element has no namespaces (it does in the x version) but in the y version it also needs the xlink namespace as the image href attribute is in the xlink namespace. b) the image in the SVG is external. A css background is an image itself so any SVG it references cannot load external resources. You therefore need to URI encode the inner image data and then uri encode the outer SVG (thereby doubly encoding the inner image data) So you need something like this... var y = encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 2 1" width="100%"><image xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAA.... Which I've completed here for the Firefox/Chrome case