I'm developing a small educational tool, for which I'd like to add drop-shadows to SVG paths. To construct my graphics I use the D3.js. This usually works lovely, but with specific shapes I run into problems, especially with small shapes that have horizontal and/or vertical lines.
To illustrate this, I made a JSFiddle example with three triangles. The shadow on the green triangle looks pretty, the shadow on the orange triangle in still alright, but the shadow on the red triangle looks very ugly.
The shadow is created using this code as an example:
var defs = svg.append("defs").attr("height","160%");
var filter = defs.append("filter").attr("id", "schaduw");
filter.append("feGaussianBlur").attr("in", "SourceAlpha")
.attr("stdDeviation", 5).attr("result", "blur");
filter.append("feOffset").attr("in", "blur")
.attr("dx", 3)
.attr("dy", 3)
.attr("result", "offsetBlur");
var feMerge = filter.append("feMerge");
feMerge.append("feMergeNode").attr("in", "offsetBlur");
feMerge.append("feMergeNode").attr("in", "SourceGraphic");
As can be seen in the JSFiddle code, the only meaningful difference between the shapes is their size. How can I prevent the small shapes from having ugly shadows?
Any help is very much appreciated! =)
The quality of the shadow that you refer to is controlled by the standard deviation of the Gaussian blur you use. Using an absolute value there means that the shadow is "spread out" the same amount regardless of the size of the element you're using the filter on. For smaller shapes, this has the effect you're seeing.
There are two ways of fixing this. The quick and easy way is to decrease the standard deviation such that it looks good even for the smallest shapes. I've done this in your example here by setting .attr("stdDeviation", 1)
.
The other option is to have different standard deviations for different shape sizes as I've done here in a hacky way. This would be much more difficult because it would require you to compute the size of a shape, determine a suitable standard deviation and potentially create an appropriate filter if it doesn't exist. Also, the shadows look less consistent.