I want to create an SVG donut shape (circle with another empty circle inside). I want to be able to access & resize both circles, eg via their id attributes. This will allow for animation.
I have considered three approaches but none are that great:
- plex path: does not allow for access of the inner circle via #id
- outline stroke: possible but plicated for my purpose (would have to reposition as I increase stroke)
- clippath/mask: Doesn't work like a pound path, only an outer box
Is there a way of doing this?
I want to create an SVG donut shape (circle with another empty circle inside). I want to be able to access & resize both circles, eg via their id attributes. This will allow for animation.
I have considered three approaches but none are that great:
- plex path: does not allow for access of the inner circle via #id
- outline stroke: possible but plicated for my purpose (would have to reposition as I increase stroke)
- clippath/mask: Doesn't work like a pound path, only an outer box
Is there a way of doing this?
Share Improve this question edited Oct 13, 2014 at 10:39 MachineElf asked Oct 12, 2014 at 19:56 MachineElfMachineElf 1,2812 gold badges15 silver badges28 bronze badges 2-
2
What's wrong with using a
circle
and itsstroke
? – Zach Saucier Commented Oct 13, 2014 at 0:14 - @Zach it's a headache to maintain the cx/cy position of the circle as you move the inner & outer independently of each other – MachineElf Commented Oct 13, 2014 at 10:44
2 Answers
Reset to default 3Probably the easiest way would be with masks.
If you are working with a set of discrete donut sizes, you could use CSS and a mask for each size:
<svg width="500" height="500">
<defs>
<mask id="bigmask">
<rect width="100%" height="100%" fill="white"/>
<circle cx="250" cy="250" r="50"/>
</mask>
<mask id="smallmask">
<circle cx="250" cy="250" r="150" fill="white"/>
<circle cx="250" cy="250" r="100"/>
</mask>
</defs>
<circle id="donut" cx="250" cy="250" r="200" mask="url(#bigmask)"/>
</svg>
CSS:
#donut:hover
{
mask: url(#smallmask);
}
Demo here
Unfortunately you can't modify the size of circles with CSS. "r" is not (yet) a property that can be manipulated with CSS. So you will need to either use SMIL (SVG) animation, or manipulate your mask circles with javascript:
<svg width="500" height="500">
<defs>
<mask id="donutmask">
<circle id="outer" cx="250" cy="250" r="200" fill="white"/>
<circle id="inner" cx="250" cy="250" r="50"/>
</mask>
</defs>
<circle id="donut" cx="250" cy="250" r="200" mask="url(#donutmask)"/>
</svg>
JS
$("#donut").mouseenter(function(evt) {
$("#outer").attr("r", 100 + Math.random() * 100);
$("#inner").attr("r", 100 - Math.random() * 50);
});
Demo here
Although BigBadaboom's answer is the best way IMO, if you want to use a pound path, it's possible to animate by rewriting the path's d
attribute each frame like this:
// get svg path coordinates for a ring
ring:function(x, y, ir, or) {
var path =
'M'+x+' '+(y+or)+'A'+or+' '+or+' 0 1 1 '+(x+0.001)+' '+(y+or) // outer
+ 'M'+x+' '+(y+ir)+'A'+ir+' '+ir+' 0 1 0 '+(x-0.001)+' '+(y+ir) // inner
;
return path;
}
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744737205a4590820.html
评论列表(0条)