SVG filterRes alternative/replacement strategy - javascript

When you create an SVG with a shadow, then zoom in/out on your SVG you'll get some serious performance issues due to re-computing the shadows.
In the past, you could use filterRes='' to get around this. However, filterres has been deprecated and removed from the SVG spec.
I'm seeking an alternative to filterRes='', which will allow me to work with things like SVG shadows in a performant way when doing things like zooming in/out which causes shadows to be re-computed.
Does anyone have any experience overcoming performance obstacle that surfaced once filterres was deprecated? Any examples of strategies for replacing the functionality that filterres use to provide?

The easiest thing to do, is to render the shadow to an image an include that in your svg. Starting from that there could be solutions which generate that shadow in different resolutions and pull in the appropriate size on demand. You could as well use a <canvas> to create the shadow client side and hand it over to the svg as base64 encoded image source.
It strongly depends on your application and the performances requirements, so it can be sufficient to have three or for "steps of resultion" pre rendered, or something more complicated needs to be applied...
Btw. You can also reference the <filter> element with Javascript and manipulate the filter attributes directly...

If you can convince the browser to do scaling on the GPU rather than the CPU, this will make things far more performant, so using CSS 3D Transforms rather than JavaScript or viewBox animation to zoom in and out on SVG may do the trick.

Related

Should I be animating SVG elements by updating attributes?

I've just started out with SVG and have gathered enough information to see that animating these objects is not the same as animating canvas objects. With canvas objects, the canvas is redrawn on every frame, but it seems like with SVG you aren't supposed to be thinking in terms of frames and FPS, but rather in terms of seconds and delays by using the built in <animate> tag.
While I appreciate all the out of the box functionality for SVG animations, I've built up quite an understanding (and library) for how to get my animations working together on canvas using the frames and a timeline paradigm.
I know there is timeline and scheduling support for SVG with libraries like GSAP or SVG.js but I much prefer thinking in terms of FPS and and frameCount.
I was wondering if I might be able to continue using this paradigm, but instead simply update the attributes of my SVG objects on each frame iteration and let the DOM re-render the positions instead of figuring out a way to describe the animation in the <animate> tag.
I'm completely open to suggestions if using the <animate> tag isn't as finicky as I think it is for scheduling my animations/getting them to move together and any suggestions would be much appreciated.
My animation needs aren't to the likes of high performance websites, I just want to step through them to show people some math concepts as they progress.
Updating SVG element attributes is a completely fine way to go about animating them. It can be more performant than clearing all elements in your main SVG tag, and redrawing - but that depends on the drawing, browser, and animation details. But, SVG renders surprisingly quickly, so if you are just stepping through tailored frames to demonstrate a concept, and if it would be more convenient to think of each frame independently, you should be completely fine to also clear and redraw. If your project is intended for a website, make sure to test your implementation on Chrome and Firefox at least as they have slight differences.

d3.js - maintain interaction with use of canvas

As far as I read about this topic d3.js uses for the main part SVG and not HTML5's Canvas. The advantages and disadvantages of SVG and Canvas are clear and already discussed. Now I found out that it is possible to use Canvas instead or in combination with SVG in d3.js. The main reason should be to get a better performance for large datasets (like cubism.js does for realtime data visualization). My question is: When I do use Canvas over SVG to get a better performance, do I have still the possibilities of interaction? I know that Canvas itself allows manipulation, but it is much harder to implement than it is for SVG. So can I maintain the interaction of SVGs when I use the d3.js Canvas approach?
First of all, D3 doesn't require any specific rendering technology as such. It is mostly (except for some specialised helpers) agnostic of whether you use HTML, SVG, Canvas or something completely different for rendering.
One of the main differences between SVG and Canvas, as you've pointed out, is that SVG has the interaction "built in", i.e. it provides facilities for event listeners and such. Canvas has none of this.
You can however get the same kind of interactivity as in SVG in Canvas. The trick is to use Javascript to monitor what the user does in relation to the various elements. For an introduction to this, see e.g. here.
Note that, depending on what kind of interaction you want exactly, there may be significant implementation effort to achieve the same as SVG already provides. Also note that this incurs a performance penalty which may negate some of the benefits of Canvas over SVG.

Drawing lots of hexagons and distorting them

I'm starting a web game, and I would like to know the best way to do it.
The game is a field of hexagons seen from the above, that can be rotated/inclined.
What's the best way to do it? What I was going to do was use a canvas and use 2d transforms to simulate 3d rotations, the problem is that:
The game must work on smartphones
For every rotation i must redraw all the canvas, and there could be 200 hexagons on the screen to redraw many times, so i think canvas are too expensive in terms of resources...
There's two ways I can think of:
Using canvas only. This means quite wide browser support, will have few quirks and generally "just work". Potential problems: Performance on low-end machines like you mentioned. But is rotating the game critical to gameplay? If not, you could consider turning that off on slow smartphones. Users will most likely not miss that feature if it's not important to gameplay.
A combination of canvas and CSS3 transforms (rotating cube example). Could give you better performance than pure canvas solution. Potential problems: requires "mixing" of techniques, which always means a risc of running into unexpected problems or quirks.
You should look at www.kineticjs.com
Canvas is the way to go for drawing 100's of shapes because it doesn't write to the DOM for every path like SVG does.
It has several examples where shapes are programmatically drawn in the 1000s. I recently used it for a similar animation here:
http://movable.pagodabox.com

selectable and movable shapes in html5

I am creating a dynamic, interactive network diagram with php, javascript and either Canvas or SVG
However, with canvas, I don't know how to make each object selectable. i don't want to use the hidden canvas and to detect if a mouse is on an object, because I will have lots of intersecting objects and having lots of layers of canvas will be messy.
I don't know anything about SVG.
Would SVG serves the purpose better? or what is a canvas solution to this.
One advantage of SVG is that it has concrete DOM objects representing the shapes in the drawing, so you automatically get a lot of mouse event handling and event bubbling.
Alternatively, you could use EaselJS, which provides a pretty robust display-list, freeing you from managing hidden canvases.
There are some projects for building diagrams and graphics already. You could try Raphaƫl which is svg based, so it should be ie compatible as well.
I assume by "the hidden canvas" you mean my tutorial. It will still work with multiple objects and multiple layers, you just need to paint them in the proper z-order.
There are of course much faster (but more sophisticated) ways.
If you don't want to deal with it, SVG has all the object selection built in. Give Raphael a try as Zlatev suggests. If the performance gets too bad (Too many objects) you will have to switch to canvas, so it really depends on your number of nodes/links in your diagrams.
You will have to take care of sending data to your server (in whatever way you prefer) yourself though. There's nothing built into SVG/Canvas/Raphael that will do it for you.

Between SVG and canvas, which is better suited for manipulating/animating several images? Maybe neither and just use css3 transforms?

The 2nd part of the question is, which javascript library is better/easier to manipulate images with? I won't be actually drawing any shapes or anything. Other info: I'll be using jQuery and don't need to support all browsers, just webkit.
Edit:
More information: the current design is to layout/draw several rows/columns of images in a grid-like layout, with the image in the center being in "focus" (a little larger, with a border or something and some text next to it). The tricky thing is that we want the whole canvas of images to appear to slide/glide over to bring another random image into focus. So obviously the number of images in this grid needs to exceed what is visible in the viewport so that when the transition occurs there are always images occupying the canvas. Other than moving the images around, I won't be blurring them or otherwise modifying them. Eventually we will add user interactions like clicking/touching on a visible image to bring it to focus manually.
Let me know if this is not clear or still confusing.
I ran across scripty2 which seems like an alternative to using canvas/SVG for my purposes. I also started farting around with EaselJS last night, and it seems like this might work, but I'm wondering if it'll end up being more work/complex than just using standard HTML/CSS and a tool like Scripty2 to aid with animations and click/touch events. Just looking for any suggestions. Thanks!
The answer depends on your manipulation and animation.
If it's just translations, CSS wins for speed compared to canvas. I haven't tested, but I feel confident it easily beats SVG for the same sort of thing.
If you're going to be doing non-affine transformations or otherwise messing with the images (e.g. blurring them) you clearly want Canvas.
If you need event handlers per object, you clearly want a retained-mode drawing system like SVG or HTML+CSS. I haven't done enough CSS3 transforms to say how they compare in terms of speed to SVG, but they clearly do not have the robust transformation DOM of SVG.
This is a rather subjective question (or suite of questions) and you haven't yet given sufficient information for a clear answer to be possible.

Categories