I am trying to make my drawing application work well in Firefox.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.list {
background-color: blanchedalmond;
}
.list-item {
width: 50px;
height: 25px;
background-color: coral;
}
foreignObject {
overflow: visible;
}
</style>
</head>
<body>
<svg width="300" height="200" fill="blue">
<foreignObject width="300" height="25">
<div class="list">
<div class="list-item">a</div>
<div class="list-item">b</div>
<div class="list-item">c</div>
</div>
</foreignObject>
</svg>
<svg class="svg2" width="300" height="200" fill="blue">
<foreignObject width="300" height="25">
<div class="list">
</div>
</foreignObject>
</svg>
<script>
let svg = document.querySelector('.svg2');
svg.addEventListener('mousemove', handleMouseMove)
function handleMouseMove(e) {
console.log(e.offsetX, e.offsetY);
}
setTimeout(() => {
let el = document.querySelector('.svg2 .list');
let a = document.createElement('div')
let b = document.createElement('div');
let c = document.createElement('div');
a.innerHTML = 'a';
b.innerHTML = 'b';
c.innerHTML = 'c';
a.classList.add('list-item')
b.classList.add('list-item')
c.classList.add('list-item')
el.appendChild(a);
el.appendChild(b);
el.appendChild(c);
}, 1000);
</script>
</body>
</html>
In Chrome, both svg show all 3 items.
In Firefox(developer version 78.0b4 (64-bit)), in the first svg, all 3 items are visible, in the second svg, only the first item is visible. Why does the second svg not show all 3 items?
Setting style="overflow: visible" on <svg> solved the same issue for me.
SVG and sub-elements also support overflow="visible" as an attribute (so you can try <foreignObject overflow="visible ... >).
Related
I've got 3 files: test.html, test.js and test.svg
I'm trying to call the different files into HTML but the file svg don't work
test.html
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Using SVG as an object</title>
<link href="index.css" rel="stylesheet" />
</head>
<body>
<h1>Test</h1>
<script type="text/javascript" src="test.js"></script>
<object data="test.svg" width="300" height="300"> </object> <!-- Not working -->
<input type="button" value="Start Animation" onclick="startAnimation();">
<input type="button" value="Stop Animation" onclick="stopAnimation();">
</body>
</html>
test.js
var timerFunction = null;
function startAnimation() {
if(timerFunction == null) {
timerFunction = setInterval(animate, 20);
}
}
function stopAnimation() {
if(timerFunction != null){
clearInterval(timerFunction);
timerFunction = null;
}
}
function animate() {
var circle = document.getElementById("circle1");
var x = circle.getAttribute("cx");
var newX = 2 + parseInt(x);
if(newX > 500) {
newX = 20;
}
circle.setAttribute("cx", newX);
}
test.svg
<svg width="500" height="100">
<circle id="circle1" cx="20" cy="20" r="10"
style="stroke: none; fill: #ff0000;"/>
</svg>
I don't understand why I can't insert svg file with object
Thanks for your help
See Dev.To Post: <load-file> Web Component
Use a modern, native W3C standard Web Component <load-svg>
it reads the SVG as text
adds SVG to shadowDOM as DOM element
moves the style element from lightDOM to shadowDOM
So style is only applied to one SVG
<load-svg shadowRoot src="//graphviz.org/Gallery/directed/fsm.svg">
<style>
svg { height:150px } text { stroke: green } path { stroke: red ; stroke-width:3 }
</style>
</load-svg>
<load-svg src="//graphviz.org/Gallery/directed/fsm.svg">
<!-- all HTML here is overwritten -->
</load-svg>
<script>
customElements.define('load-svg', class extends HTMLElement {
async connectedCallback() {
this.style.display = 'none'; // prevent FOUC (provided Custom Element is defined ASAP!)
let src = this.getAttribute("src");
let svg = await (await fetch(src)).text();
if (this.hasAttribute("shadowRoot")) {
this.attachShadow({mode:"open"}).innerHTML = svg;
this.shadowRoot.append(this.querySelector("style") || []);
} else {
this.innerHTML = svg;
}
this.style.display = 'inherit';
}
});
</script>
More complex example: How to make an svg interactive to gather comments/annotations on depicted elements
You can use svgs directly in the HTML. Easiest is to just use the SVG inside the HTML. You can also re-use an svg shape on a page but then the icons have a shadow-dom boundary.
If you use an object or svg tag, it will render just fine but you will lose all information about classes, IDs and so on in the SVG.
Further Information on SVG on css-tricks
More information about how to group and re-use shapes in SVG on css-tricks (and one more, also on css-tricks)
var timerFunction = null;
function startAnimation() {
if (timerFunction == null) {
timerFunction = setInterval(animate, 20);
}
}
function stopAnimation() {
if (timerFunction != null) {
clearInterval(timerFunction);
timerFunction = null;
}
}
function animate() {
var circle = document.getElementById("circle1");
var x = circle.getAttribute("cx");
var newX = 2 + parseInt(x);
if (newX > 500) {
newX = 20;
}
circle.setAttribute("cx", newX);
}
<svg width="500" height="100">
<circle id="circle1" cx="20" cy="20" r="10"
style="stroke: none; fill: #ff0000;"/>
</svg>
<input type="button" value="Start Animation" onclick="startAnimation();">
<input type="button" value="Stop Animation" onclick="stopAnimation();">
<object> tags can be used on many elements, including SVG files, and therefore not recognized as image elements, So:
It's not available on image search. So you can use an <img> tag as fallback (optional but recommended)
You should specify the type of the object
So you can change it like this:
<object type="image/svg+xml" data="test.svg" width="300" height="300">
<img src="test.svg" />
</object>
And another problem is the SVG file. Based on MDN documents :
The xmlns attribute is only required on the outermost SVG element of SVG documents. It is unnecessary for inner SVG elements or inside HTML documents.
so you need to add xmlns parameters to the SVG tag on SVG file like this :
<svg width="500" height="100" xmlns="http://www.w3.org/2000/svg">
<circle id="circle1" cx="20" cy="20" r="10"
style="stroke: none; fill: #ff0000;"/>
</svg>
I made a small simple example that works, checkout this sandBox link
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title></title>
<style>
svg{ display: inline-block; }
</style>
<script src="my.js"></script>
</head>
<body>
<embed src="sprites.svg" type="image/svg+xml" width="0" height="0" />
<svg id="MAIN" xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%" viewBox="0 0 320 208" shape-rendering="crispEdges">
<path d="M0 0h320v208h-320v-208z" fill="#000"/> <!-- Fill screen -->
<svg id="sprite1"><use xlink:href="sprites.svg#SP1" x="64" y="128"</use></svg>
<svg id="sprite2"><use xlink:href="sprites.svg#SP2" x="64" y="128"</use></svg>
<svg id="sprite3"><use xlink:href="sprites.svg#SP3" x="64" y="128"</use></svg>
</svg>
<script>
start( 1 ); // Call Func in my.js
</script>
</body>
</html>
I have hundreds of sprites in "sprites.svg". How do I, in javascript add the sprites I want to the DOM via javascript. I want them added so that they are just like sprite1 to sprite3 in the example html page above, thanks Keith
Worked it out, not as complex as I thought.
var svgURI = "http://www.w3.org/2000/svg";
var mainSVG = document.getElementById( "MAIN" ); // my main SVG
var svg = document.createElementNS( svgURI, 'svg' );
svg.id = "sprite4";
svg.innerHTML = "<use xlink:href='sprites.svg#SP4'></use>";
mainSVG.appendChild( svg );
Thanks to every one who tried to help
INDEX.HTML
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
width: 960px;
padding-top: 40px;
margin: auto;
position: relative;
}
svg {
width: 100%;
max-height: 400px;
}
</style>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script type='text/javascript'>
window.addEventListener('load', function () {
d3.xml('iPhone.svg', 'image/svg+xml', function (error, data) {
d3.select('body').node().appendChild(data.documentElement);
var svg = d3.select('svg');
var appScreen = svg.select('#ScreenBackground');
var screenWidth = +appScreen.attr('width'),
screenHeight = +appScreen.attr('height');
var appButton = svg.select('#AppButton')
.on('mouseenter', function () {
appButton.style('fill', '#AB69C6');
})
.on('mouseleave', function () {
appButton.style('fill', '#9B59B6')
})
.on('click', function () {
var x = Math.random() * screenWidth;
var y = Math.random() * screenHeight;
appButton
.transition()
.duration(1000)
.ease('bounce')
.attr('cx', x)
.attr('cy', y);
});
});
});
</script>
iPhone.svg
<?xml version='1.0' encoding='utf-8'?>
<svg width='400px' height='800px' viewBox='0 0 400 800'
version='1.1' xmlns='http://www.w3.org/2000/svg'>
<title> SafeSignal </title>
<description>Created with Sketch (http:/ / www.bohemiancoding.com / sketch) </description>
<defs>
<!-- Define a clipping path the size of the screen -->
</defs>
<!-- iPhone frame -->
<rect id='iPhone' fill='#000000'
x='0' y='0' width='400' height='800' rx='50' ry='50'></rect>
<!-- iPhone home button -->
<circle id='HomeButton' fill='#202020'
cx='200' cy='730' r='40'></circle>
<!-- Apply the clipping path to the screen group -->
<g id='ScreenGroup' transform='translate(20, 80)'
clip-path='url(#ScreenMask)'>
<!-- Screen background -->
<rect id = "ScreenBackground" x ="214" y ="0" width ="102" height ="568" style = "pointer-events: all;" ></rect>
<!-- An interactive button in the app -->
<circle id='AppButton' fill='#9B59B6' cx='180' cy='290' r='50' style='cursor:pointer;'></circle>
</g>
</svg>
taking help from the google , i have made this SVG . now I am trying to make have background as image but i have tried all the ways but everytime i done this ya add any image I have get this error Uncaught TypeError: Cannot read property 'documentElement' of null I dont know where i am going wrong because i am new to this svg
<object type="image/svg+xml"
width="100" height="100" style="float:right"
data="http://blog.codedread.com/clipart/apple.svgz">
<span/></object>
<object id="E" type="image/svg+xml" data="http://srufaculty.sru.edu/david.dailey/svg/ovals.svg" width="320" height="240">
alt : Your browser has no SVG support. Please install Adobe SVG Viewer
plugin (for Internet Explorer) or use Firefox, Opera or Safari instead.
</object>
<!DOCTYPE html>
<html>
<head>
<title>HTML5 SVG demo</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
</head>
<body>
<h1>HTML5 SVG Demo (embed with iframe)</h1>
<p> A nice green circle that was embeded using the HTML "iframe" tag:
<iframe src="green-circle.svg"
width="64" height="64" style="border:1;"></iframe>
</p>
<p>
Tips:
<iframe src="green-circle.svg" style="float:left;margin-right:1cm;"
width="64" height="40" style="border:1;"></iframe>
</p>
</body>
</html>
I have an incredibly odd case of IE9 displaying blurry graphics when the <svg> is floated next to another element.
Here's the simplest case I could come up with that is similar to our application:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/2000/svg">
<head>
<meta content="IE=Edge,chrome=1" http-equiv="X-UA-Compatible">
<title>IE9 SVG Resize Issue</title>
<script type="text/javascript">
window.onload = function() {
var i = 0;
var increaseWidth = function() {
var w = 500 + i++;
window.resizeTo(w, 500);
document.getElementById('currentWidth').innerHTML = w + 'px';
};
document.getElementById('btn').addEventListener('click', increaseWidth);
increaseWidth();
};
</script>
</head>
<body>
<div style="float: left; width: 20%">
Left
</div>
<div style="float: left; width: 80%">
<svg width="200" height="200" version="1.1">
<rect fill="#fff" stroke="#000" x="0.5" y="0.5" width="100" height="100" />
</svg>
</div>
<span style="color: #999; display: block">NOTE: In IE9 you can only have one tab open to resize the window</span>
<button type="button" id="btn">Increase Width</button>
<span id="currentWidth" style="color: #666; font-size: 15pt"></span>
</body>
</html>
Here's a gallery that shows resizing the window from 500px to 507px. You can see that the lines of the rectangle go from blurry to crisp when resizing by one pixel. The bug seems to occur when having the two columns with a percentage width. It can also happen when the div containing the svg overflows onto a new line (things become slightly blurry). FWIW, in the actual application we're using Raphael.js.
Is there a known issue associated with this and is there an easy fix to keep the lines crisp (with the usual offset by 0.5px fix)?
I have the following document, where I plan to add some horizontal lines, one for each line of a textbox, where lines should have a "name: number" structure.
<!DOCTYPE html>
<html lang="pt-br" xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg">
<head>
<meta charset="UTF-8" />
<meta http-equiv="pragma" content="no-cache"/>
<title>Diagrama Audax</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.js"></script>
<style type="text/css">
#sidebar {float: left; display: inline-block;}
#drawing {left: 330px; position: relative; display: inline-block}
#Locais {width: 300px; height: 500px;}
svg {background: #ddd; width: 500px; height: 500px;}
td, textarea {margin: 0; padding: 0;}
</style>
</head>
<body>
<table>
<tr id="tabela" cols="2">
<td>
<textarea id="Locais"></textarea>
</td>
<td>
<svg id="svg">
<circle stroke="black" fill="red" cx="200" cy="200" r="100" opacity="0.1"/>
<line id="path" x1="0" y1="0" x2="200" y2="200" stroke="black"/>
</svg>
</td>
</tr>
</table>
</body>
<script>
// A função abaixo pega a caixa de texto e associa o evento "draw" a ela
$(function () {
$("#Locais").keyup(function() {
valueString = $("#Locais").val();
if (valueString != "") {
lines = valueString.replace("\r","").split("\n");
CPs = [];
for (i in lines) {
eachLine = lines[i];
tmpDict = {};
values = eachLine.split(":");
for (j in values) {
eachVal = values[j];
tmpDict[j] = eachVal;
}
CPs.push(tmpDict);
}
DrawUsing(CPs);
}
})
});
function DrawUsing (lista) {
var svg = document.getElementById("svg");
for (element in lista) {
refname = lista[element][0];
refdist = lista[element][1];
var line = document.createElement ("line");
line.setAttribute('stroke', "black");
line.setAttribute('stroke-width', 1);
line.setAttribute('x1', 0);
line.setAttribute('x2', 100);
line.setAttribute('y1', refdist);
line.setAttribute('y2', refdist);
svg.appendChild(line);
console.log(document.getElementsByTagName("line").length);
}
}
</script>
</html>
As a "warm up", I tried to manipulate the SVG adding lines to it each time I press a key. Having pasted the following text (just pasting it with control+V is enough to trigger keyup event), but although the svg child list increases, no additional line is seen.
What am I doing wrong? (a lot, I suppose, since I am very n00b with javascript, and direct manipulation of inline <svg> elements (as opposed to <object>) is very poorly documented, it seems...
Any help is most welcome, thanks for reading!
SVG elements go in the http://www.w3.org/2000/svg namespace so instead of
var line = document.createElement ("line");
use
var line = document.createElementNS ("http://www.w3.org/2000/svg","line");