I wanted to learn more about SVG. So I decided to try to draw a power-up mushroom without using any graphic design tools.
I had been using SVG icons and graphing tools for a while, but I was a little intimidated by SVG for some reason and had never taken a close look at how it works.
Scaled Vector Graphics (SVG) are an XML format for describing 2D images. An <svg>
element can hold a set of shapes. I started off my mushroom picture with a black rectangle (rect
) inside of a 1000 x 1000 viewBox
.
<svg version='1.1' baseProfile='full' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 1000 1000'>
<!-- Black Rectangle -->
<rect width="100%" height="100%" fill="#000000" />
</svg>
SVG uses a grid with points specified in the format x y
. 0 0
is the upper left corner.
As shapes are added, they are stacked on top of each other. To draw a red mushroom cap on top of the black rectangle, I started to draw a path
.
The data (d
) for a path
takes a set of commands. The commands I need are:
M
- MoveC
- Draw a cubic Bézier curveFor my path I wanted to:
M 0 550
)C 0 -175, 1000 -175, 1000 550
)To determine the control points for for the Bézier curve, I experimented with different values for a few minutes until it looked right.
I added fill
to color in the area of the path in red. Since I hadn't yet made a complete loop, a straight line connected the end of the path back to the beginning.
<svg version='1.1' baseProfile='full' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 1000 1000'>
<!-- Black Rectangle -->
<rect width="100%" height="100%" fill="#000000" />
<!-- Mushroom Cap -->
<path d='M 0 550
C 0 -175, 1000 -175, 1000 550' fill='#eb3434' />
</svg>
To complete the bottom side of the cap, I added a curve from 1000 550
back to 0 550
.
<svg version='1.1' baseProfile='full' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 1000 1000'>
<!-- Black Rectangle -->
<rect width="100%" height="100%" fill="#000000" />
<!-- Mushroom Cap -->
<path d='M 0 550
C 0 -175, 1000 -175, 1000 550
C 1000 1000, 0 1000, 0 550' fill='#eb3434' />
</svg>
Next, I needed to add the white dots to the cap. So I added a circle
, choosing a position for the center (cx
and cy
) and a length for the radius (r
).
<svg version='1.1' baseProfile='full' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 1000 1000'>
<!-- Black Rectangle -->
<rect width="100%" height="100%" fill="#000000" />
<!-- Mushroom Cap -->
<path d='M 0 550
C 0 -175, 1000 -175, 1000 550
C 1000 1000, 0 1000, 0 550' fill='#eb3434' />
<!-- White Dots -->
<circle cx='500' cy='300' r='225' fill='#ffffff' />
</svg>
This next step was the hardest part. I needed to draw a white dot on the left side of the cap.
First, I temporarily added a circle
where I wanted the dot to go. I started a path
and matched its curve with the circle. Then I removed the circle
and adjusted the curve to follow the left side of the cap. This took a bit of fiddling. I was determined to figure out how to draw this from scratch, but in the future I'll definitely invest some time in learning a graphic design tool like Inkscape.
After the left dot was ready, I mirrored it on the right.
<svg version='1.1' baseProfile='full' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 1000 1000'>
<!-- Black Rectangle -->
<rect width="100%" height="100%" fill="#000000" />
<!-- Mushroom Cap -->
<path d='M 0 550
C 0 -175, 1000 -175, 1000 550
C 1000 1000, 0 1000, 0 550' fill='#eb3434' />
<!-- White Dots -->
<circle cx='500' cy='300' r='225' fill='#ffffff' />
<path d='M 78.5 240
C 210 340, 200 560, 11.5 630
C -12 585, -6 350, 78.5 240' fill='#ffffff' />
<path d='M 921.5 240
C 790 340, 800 560, 988.5 630
C 1012 585, 1006 350, 921.5 240' fill='#ffffff' />
</svg>
To draw the face, I needed one more command to use in the path: L
to draw a straight line. The full path was:
M 200 770
)C 250 550, 750 550, 800 770
)L 800 830
)C 800 1050, 200 1050, 200 830
)L 200 770
)<svg version='1.1' baseProfile='full' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 1000 1000'>
<!-- Black Rectangle -->
<rect width="100%" height="100%" fill="#000000" />
<!-- Mushroom Cap -->
<path d='M 0 550
C 0 -175, 1000 -175, 1000 550
C 1000 1000, 0 1000, 0 550' fill='#eb3434' />
<!-- White Dots -->
<circle cx='500' cy='300' r='225' fill='#ffffff' />
<path d='M 78.5 240
C 210 340, 200 560, 11.5 630
C -12 585, -6 350, 78.5 240' fill='#ffffff' />
<path d='M 921.5 240
C 790 340, 800 560, 988.5 630
C 1012 585, 1006 350, 921.5 240' fill='#ffffff' />
<!-- Face -->
<path d='M 200 770
C 250 550, 750 550, 800 770
L 800 830
C 800 1050, 200 1050, 200 830
L 200 770' fill='#ffd7b3' />
</svg>
Next, I added some eyes quick using rect
and defining an x-axis radius (rx
) to round the edges.
<svg version='1.1' baseProfile='full' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 1000 1000'>
<!-- Black Rectangle -->
<rect width="100%" height="100%" fill="#000000" />
<!-- Mushroom Cap -->
<path d='M 0 550
C 0 -175, 1000 -175, 1000 550
C 1000 1000, 0 1000, 0 550' fill='#eb3434' />
<!-- White Dots -->
<circle cx='500' cy='300' r='225' fill='#ffffff' />
<path d='M 78.5 240
C 210 340, 200 560, 11.5 630
C -12 585, -6 350, 78.5 240' fill='#ffffff' />
<path d='M 921.5 240
C 790 340, 800 560, 988.5 630
C 1012 585, 1006 350, 921.5 240' fill='#ffffff' />
<!-- Face -->
<path d='M 200 770
C 250 550, 750 550, 800 770
L 800 830
C 800 1050, 200 1050, 200 830
L 200 770' fill='#ffd7b3' />
<!-- Eyes -->
<rect x='380' y='680' width='55' height='150' rx='55' fill='#000000' />
<rect x='398' y='700' width='20' height='50' rx='20' fill='#ffffff' />
<rect x='565' y='680' width='55' height='150' rx='55' fill='#000000' />
<rect x='582' y='700' width='20' height='50' rx='20' fill='#ffffff' />
</svg>
At this point, I realized that the picture was squished against the left and right side. I hadn't meant to do this and had wanted a little bit of a black border there. This mistake led to a good lesson in how to adjust the viewBox
to reposition its contents. I changed the starting coordinates from 0 0
to -10 -10
and added 20
to the width and height. Then I anchored the black rect
at -10 -10
.
To finish it off, I tossed in a few gradients to provide some depth. The final version is:
<svg version='1.1' baseProfile='full' xmlns='http://www.w3.org/2000/svg'
viewBox='-10 -10 1020 1020'>
<defs>
<linearGradient id='cap' x1='0%' y1='50%' x2='0%' y2='80%'>
<stop offset='0%' style='stop-color:#eb3434;' />
<stop offset='100%' style='stop-color:#8b0e0e;' />
</linearGradient>
<linearGradient id='face' x1='0%' y1='0%' x2='0%' y2='55%'>
<stop offset='0%' style='stop-color:#ffb066;' />
<stop offset='100%' style='stop-color:#ffd7b3;' />
</linearGradient>
</defs>
<!-- Black Rectangle -->
<rect x='-10' y='-10' width="100%" height="100%" fill="#000000" />
<!-- Mushroom Cap -->
<path d='M 0 550
C 0 -175, 1000 -175, 1000 550
C 1000 1000, 0 1000, 0 550' fill='url(#cap)' />
<!-- White Dots -->
<circle cx='500' cy='300' r='225' fill='#ffffff' />
<path d='M 78.5 240
C 210 340, 200 560, 11.5 630
C -12 585, -6 350, 78.5 240' fill='#ffffff' />
<path d='M 921.5 240
C 790 340, 800 560, 988.5 630
C 1012 585, 1006 350, 921.5 240' fill='#ffffff' />
<!-- Face -->
<path d='M 200 770
C 250 550, 750 550, 800 770
L 800 830
C 800 1050, 200 1050, 200 830
L 200 770' fill='url(#face)' />
<!-- Eyes -->
<rect x='380' y='680' width='55' height='150' rx='55' fill='#000000' />
<rect x='398' y='700' width='20' height='50' rx='20' fill='#ffffff' />
<rect x='565' y='680' width='55' height='150' rx='55' fill='#000000' />
<rect x='582' y='700' width='20' height='50' rx='20' fill='#ffffff' />
</svg>