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)?
Related
I am trying to fix a rendering bug with my program, which currently works perfectly in Chrome and Edge. Firefox does not render the foreignObjects at all
I am using the SVG.js library, which produces the code below for one of my foreignObjects. I have tried a fix from an earlier question, which was to use the css code below to no effect.
<foreignObject width="256" height="66" x="76" y="1113">
<span id="run" xmlns="http://www.w3.org/1999/xhtml">
<button type="button" id="runButton" class="userButtons" style="width:133px;height:65px">RUN</button>
</span>
</foreignObject>
svg {
overflow: visible;
}
If anyone has any ideas I would be very grateful.
Quite likely, your svg doesn't have a explicit height.
Try to add a viewBox and height/width properties:
svg{
overflow: visible;
border:1px solid red;
}
.scroll{
height:900px;
overflow:auto;
}
<div class="scroll">
<svg viewBox="0 0 256 66" width="256px" height="66">
<foreignObject width="256" height="66" x="76" y="500">
<span id="run" xmlns="http://www.w3.org/1999/xhtml">
<button type="button" id="runButton" class="userButtons" style="width:133px;height:65px">RUN</button>
</span>
</foreignObject>
</svg>
</div>
I have the following html element:
<div id="main_track" onscroll="update_current_position(this)" height=50
style="width:901px;margin: auto;overflow-x: scroll;overflow-y: hidden;position: relative; " >
<canvas height=50 style="width:901px;" id='timeLine'></canvas>
</div>
<br><p style="margin-top: 0;">current position: <a id="current_pos"></a> ms</p>
and the following javascript function:
function update_current_position(track){
var time = track.scrollLeft;
time=time*10;
document.getElementById("current_pos").innerHTML=time.toString();
}
The canavas element width is editable by another input element.
I set the width of the canavas to something wider than the div, then I scroll the div and I find the function not giving the right out put. for example: if the scollLeft is 10 , the function returns 9.600001564.
I tried to change the scroll from the browser console and it gives the same result.
When I scroll by mouse I get many floats in current_pos element, but scrollLeft is supposed to be an integer.
I need an accurate detection of scroll, where every pixel represents 10 ms, how can I fix that?
EDIT: I tried that on firefox and it worked fine, seems to be a problem with chrome.
I just tried your code and find its working fine as you can check below code of mine,
I just increase canvas width by 1 px and after scrolling, we got 10 ms as expected
<!DOCTYPE html>
<html>
<head>
<title> testing </title>
</head>
<body style="width:100%">
<h1>Hello there</h1>
<div id="main_track" onscroll="update_current_position(this)" height=50
style="width:901px;margin: auto;overflow-x: scroll;overflow-y: hidden; border:1px solid black;position: relative; " >
<canvas height=50 style="width:902px;" id='timeLine'></canvas>
</div>
<br><p style="margin-top: 0;">current position: <a id="current_pos"></a> ms</p>
<script type="text/javascript">
function update_current_position(track){
var time = track.scrollLeft;
time=time*10;
document.getElementById("current_pos").innerHTML=time.toString();
}
</script>
</body>
</html>
check below screenshot also
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 ... >).
<!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>