1
votes

I need to make the following shape with shadows using SVG: enter image description here

I have the following SVG for the shape:

<svg style="overflow:visible; margin-left:136px; margin-top:59px; " height="188" width="212">
    <path d=" M 105.3,0  C 47.2,0 0,41.8 0,93.3  C 0,144.9 47.2,186.7 105.3,186.7  C 163.5,186.7 210.7,144.9 210.7,93.3  C 210.7,41.8 163.5,0 105.3,0  L 105.3,0 " x="0.5" y="0.5" style="fill:yellow; stroke-width:1; stroke:#548dd4; "></path>
    <path d=" M 71.6,55.7  C 65.5,55.7 60.6,60 60.6,65.4  C 60.6,70.8 65.5,75.1 71.6,75.1  C 77.6,75.1 82.6,70.8 82.6,65.4  C 82.6,60 77.6,55.7 71.6,55.7  L 71.6,55.7 " x="0.5" y="0.5" style="fill:yellow; stroke-width:1; stroke:#548dd4; fill:none; "></path>
    <path d=" M 139.1,55.7  C 133,55.7 128.1,60 128.1,65.4  C 128.1,70.8 133,75.1 139.1,75.1  C 145.1,75.1 150.1,70.8 150.1,65.4  C 150.1,60 145.1,55.7 139.1,55.7  L 139.1,55.7 " x="0.5" y="0.5" style="fill:yellow; stroke-width:1; stroke:#548dd4; fill:none; "></path>
    <path d=" M 48.4,134  C 86.3,157.2 124.3,157.2 162.3,134 " x="0.5" y="0.5" style="fill:yellow; stroke-width:1; stroke:#548dd4; fill:none; "></path>
</svg>

But now I am having trouble with making the shadow for my shape? I know how to make a drop shadow for a single shape but in this case my shape is a combination of many paths. Even if I can manage to make a shadow for the shape using filters but how do I skew the shadow to look like an ellipse using filters?

Note: My SVGs are being generated by a code so solutions like: "use the path of the biggest shape to make shadows" won't work. I can't know for sure which path would make the shadow or whether the shadow would be a result of multiple overlapping paths forming a shadow matching none of the paths.

I am thinking of putting all my paths inside a group and somehow making a shadow of it but I don't know how to do that.

2
Many games cheat and just put a blurred ellipse under the item as a shadow. You may be able to use css to create a dropshadow, then transform it ... never tried but sounds fun. - Ruskin
@Ruskin I considered doing that but it won't work for me. Read the note in my question. - Surender Thakran
Unfortunately svg does not have area union methods, or I would suggest using those. You may have to programatically duplicate the shape then set all paths and fills to grey, then transform that to act as shadow ... similar to nixkuroi's answer - Ruskin
@Ruskin I was afraid someone would say that. Duplicating the shape programatically is doable but setting the bounds of the svg element so as not to truncate the new shape would be a challenge. Not all browsers respect the overflow:visible; property. - Surender Thakran
you can set svg to zoom to fit container ... not sure how, but sure a guru was talking about it on podcast ... 5by5.tv/webahead/67 - Ruskin

2 Answers

4
votes

You can probably make it work like this:

<defs>
  <filter id="getalpha">
    <feOffset in="SourceAlpha"/>
  </filter>
</defs>
<g id="shapes">
  ... your shapes ...
</g>
<use xlink:href="#shapes" 
     transform="... your translate/skew here ..." 
     filter="url(#getalpha)"/>

The <use> is for skewing the filter results. The filter is for extracting the alphachannel of the <g> element (the shapes you have). You may want to use feColorMatrix or similar instead of feOffset to tweak how black you want the shadow to be.

0
votes

First of all I'd recommend getting rid of all the paths except the smile and replacing them with circles. They're a lot easier to read and more efficient to use.

In order to achieve the shadow you want, you should be able to paste this code at the bottom beneath your paths.

<ellipse cx="-50" cy="230" rx="100" ry="50"
style="fill:lightgrey;stroke:lightgrey;stroke-width:2" 
transform="rotate(-15 0 0)" />