SVG clipPath rendering bug in Firefox - javascript

First of all, look at images:
Before:
After:
Circle is made by dynamic included SVG.
Generated circle SVG code:
http://jsfiddle.net/n9nb7/
Used libraries:
jQuery, svgweb
What I do:
First, after page load, I dynamically created inline SVG with using svgweb for IE8.
Then I fully removed it with it's parent div conteinter.
Then I re-created this SVG code and I get that you see on second picture.
Why I need this: for fully AJAXed site.
Problem:
You see it on second picture. Problem occupies only in Firefox. Even in IE8 it works normal.
In fact clipPath stopped to work.
UPDATE
Live code http://vseslava.ru/?firefox=1.
My solution you can see here: http://vseslava.ru/ but I need solution without any timeouts.

Just to clarify the above, I was able to resolve the issue using underscore's defer function.
Here's a D3 snippet that works in Firefox (23, at least):
var clippedRect = svg.append('rect');
_.defer(function(){
clippedRect.attr('clip-path', function(d,i){
return "url(#clippingPath"+i+")";
});
});

Related

SVG problems with Google Chrome

I have been making a simple website with AngularJS and D3JS and created a custom circle mesh library (very crude). It all works fine in Firefox but it doesn't work in Chrome. The website is up at petoknm.github.io . In my homepage I have this circle mesh thing that displays the circles. But when I transition (directly) to another page with this circle mesh (programmming page) it starts behaving differently. And when I go from programming to home it starts to ignore the clipPath on the first two images (two probably because of the two images in the programming page). The svg is identical (I checked only the first three 'a' tags with the images and the first three clipPaths) to the correct svg that was there first... I don't know what happens.
This is a screenshot just after first loading the page
http://i.stack.imgur.com/2fAI6.png
This is a screenshot after coming from the programming page
http://i.stack.imgur.com/JLO3r.png
As you can see the clipPath is still in the svg and "shown" by Chrome but is not actually used (or is ignored).
Please help, I have no idea why it happens and why it's no problem for Firefox
I'll make an educated guess and say it's because your programming page is reusing ids "#clippath0" and "#clippath1". Because it's a single page site and you are replacing the parts of the DOM that contain those references, perhaps there is a bug in Chrome where it getting confused over what they point to.
Try using different sets of ids for each page and see if that fixes it. Maybe you could add different prefixes for each page (eg "#homeclippath0" and "#programmingclippath0").
It does seem like a bug in Chrome though. Perhaps you might want to report it.

Animating gradients in SVG using JavaScript. Weird behaviour of Internet Explorer

I am trying to animate a ratings control (star) by updating the gradient coordinates.
Please find the svg here. This is perfectly working in firefox. but in Internet explorer (IE 11), it is not getting rendered. I tried by removing polygons and adding them back. But nothing worked. In chrome, for first second first star is filled, then erased and getting animated! Please look into this.
Thanks in advance :)
[Update]:
I am able to produce animation in the control I referred above. check the link. I donot know y, but in IE (ie11) updating a gradient using JavaScript is not updating the polygon using the gradient. In ff & chrome , after updating gradient data we can observe the change in poolygon or some other object using the gradient. So, in IE, rather than updating existing svg oibjects, I started removing object, creating a new object with updated data and added to SVG tree. It started working. But it is an overhead. Anyone can suggest be a better approach! And, initial blink in chrome and IE still exists. As of now, I am hiding the initial blink by using timer function in code after calling animate() object. Can anyone help in solving this?
thanks

Creating a d3 selection over an existing, detached SVG element

I have a component in JavaScript that will provide an <svg> element to its host. I want to populate the SVG element using d3.js.
If I let d3.js create the SVG element and add it to the <body>, then things work as expected:
var chart = d3.select('body').append('svg');
However I already have an SVG element. I want my code to more closely resemble:
var svg = document.createElement('svg'),
chart = d3.select(svg);
This latter approach populates the SVG element (as seen in the elements panel of Chrome's developer tools) but it does not render properly.
Am I going about this incorrectly?
I don't mind if d3 creates the SVG element, so long as it doesn't attach it to the DOM and I can access it.
EDIT I've created a jsFiddle that reproduces my problem. You can toggle the APPROACH variable between 1 and 2 to see alternate approaches. I see this issue in both Chrome and Firefox (latest versions on Ubuntu 13.04.)
EDIT 2 I've created a screenshot showing the working and non-working versions side by side:
You can see that the element trees are largely the same. However on the non-working version (left) the Styles panel (to the right of the element tree) is missing some user agent rules. I have no idea why this should be different. I'd suggest it was a bug in Chrome, but the same behaviour is visible in Firefox.
The problem is that you're creating the SVG element in the HTML namespace where it gets interpreted incorrectly. If you replace
var svg = document.createElement('svg');
with
var svg = document.createElementNS("http://www.w3.org/2000/svg", 'svg');
it works fine. D3 takes care of this for you by setting the namespace automatically.

update SVG dynamically

I have some objects inside of svg that can be clicked by user.
Is there any way to:
- send information about object (id) that was clicked by user to the 'main html document'?
- draw from outside document in the svg file.
Probably, my description is unclear,... I want to implement something like this:
user click on any object inside of svg-image;
main document will receive id of the clicked object and:
display some information about that object;
draw additional object inside of the svg-image.
Questions: how to communication from svg to document and from document to svg?
Thanks a lot, any thoughts are welcome!
P.S. Probably SVG is not the best way do that? What is better then?
EDIT: I saw recommendation regarding use of Raphael,.. but I would like to see 'native' options. (For now I'm analyzing Raphaels implementation to see that, but don't think it is doing exactly what I need).
See this example for how to get the DOM of a referenced svg from the parent document.
And here's an example of how you can call from an svg file to the parent document.
SVG is very well suited for doing what you describe.
I'd suggest using a library like Raphaël to support your SVG building. You can attach events to DOM objects that you can get through the node property of an image component.
Raphaël.js is indeed a good solution if you want to stick to SVG / VML. Now you can use canvas (new HTML 5 functionality) as well. Canvas is a new html tag (that can have id, events, ...) that allows you to draw free shapes a bit like SVG does. IE doesn't support canvas natively, of course, and you will need "excanvas.js" (this one or another, but this one works pretty well...) to make it IE compatible.
Only one restriction I know of regarding canvas: using background images makes IE be very slow. I would use Raphaël.js if it was something you'd consider doing.
Good luck
Nobody suggested, but accidentally I've found that svg is already supported by jQuery!
http://plugins.jquery.com/project/svg
Probably that is not the best approach, but I will try to work with svg using jquery. And actually, that seems like reasonable

Is it possible to use webkit css masks with SVG without an external file?

Webkit allows the use of an external SVG file as a mask for any HTML element. Ie:
<img src="kate.png" style="-webkit-mask-image: url(circle.svg)">
Resulting in:
(More information here: http://webkit.org/blog/181/css-masks/)
Does anyone know if there's a way to do it without an external SVG file? More specifically, can it be done with SVG generated from javascript?
Well, two years have passed since I asked this question and the browser landscape changed a lot. Here's an example of exactly what I wanted to do, which works only in Firefox for now: http://mozilla.seanmartell.com/persona/
As you can see there's a div with id chameleon which has the following style:
<div id="chameleon" style="clip-path:url(#clip1); -webkit-mask-box-image: url(mask.png);">
#clip1 points to a clipPath element inside an inline SVG element which links to a shape.
<clipPath id="clip1"><use xlink:href="#shape1"/></clipPath>
So now it's doable in Firefox.
Thanks #mart3ll for the practical example!
I'm not sure about the WebKit specific extension but Mozilla allow you to apply SVG effects like masks and filters on HTML elements. These can be defined in external files or directly in the markup. See this post. This isn't in any spec at the moment, but the SVG and CSS working groups are working together to spec this approach. See the Working Group's page (although only filters, not masks are mentioned explicitly there).
You can usually link to something in SVG by including the id of the element in the url value (e.g. url(#someID)). You could try generating the SVG via JS, giving it an id and inject it into the document and see if it works. There is no spec as it is a WebKit extension so it is hard to say without trying it out.
Yes I believe it's possible. Recently I used PHP to generate the SVG file.
Here is an example that I made:
http://jsfiddle.net/brokeneye/ygsKm/
Also check out http://raphaeljs.com/

Categories

Resources