Advertisment

Vector Graphics for the Web

author-image
PCQ Bureau
New Update

If you’re a developer who creates serious Web applications, you would surely be having a list of pet peeves that you wished could be done on the Web but wasn’t possible due to limitations in technology. One of my pet wishes was that my Web applications be able to generate graphics on the fly, say for drawing graphs, charts or other applications. This is to an extent possible using server-side technologies and clever GIF manipulation. (This method, however, is a different story and requires an article on its own). But for performance reasons, the graphics should take place at the client-end (the Web browser, that is). 

Advertisment

Before I get into the technology that allows you to do this, let me tell you a bit about graphics. Graphics in computers are of two types–raster and vector. Raster graphics store the exact location and color of every individual pixel in the picture. Vector graphics on the other hand store mathematical information about the structure that makes up a picture. That is, no pixels are stored, only the formulae that make up the pixel structure for the graphics. Vector graphics are therefore much smaller and more efficient that

raster graphics, but can’t store the richness of a photograph or painted image.

Now, Web pages allow you to render and display vector graphics quite easily. This technology is called the Vector Markup Language (VML). VML is based on the Extensible Markup Language (XML) and is a joint proposal by Microsoft, HP, Adobe, and some others to the World Wide Web Consortium. 



VML is currently supported by the IE 5 HTML rendering engine. Therefore, it can be used in other browsers that use this engine, such as NeoPlanet. 

VML tags follow the syntax . Note that the closing tag is not optional and nesting of tags is allowed as long as they follow the XML convention. Let’s quickly create a small

VML-enhanced page and see the result. Start off with a normal HTML template that contains a head, title, and body. Change the

<html i-amphtml-layout i-amphtml-no-boilerplate transformed="self;v=1"></html> start tag to the following:

<html i-amphtml-layout i-amphtml-no-boilerplate transformed="self;v=1"><html xmlns:v="”urn:schemas-microsoft-com:vml”" i-amphtml-layout i-amphtml-no-boilerplate transformed="self;v=1"></html></html>





This informs the HTML engine that the page contains VML elements. Next add the following lines to the <head><style amp-runtime i-amphtml-version="012403142137000">html{overflow-x:hidden!important}html.i-amphtml-fie{height:100%!important;width:100%!important}html:not([amp4ads]),html:not([amp4ads]) body{height:auto!important}html:not([amp4ads]) body{margin:0!important}body{-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;text-size-adjust:100%}html.i-amphtml-singledoc.i-amphtml-embedded{-ms-touch-action:pan-y pinch-zoom;touch-action:pan-y pinch-zoom}html.i-amphtml-fie>body,html.i-amphtml-singledoc>body{overflow:visible!important}html.i-amphtml-fie:not(.i-amphtml-inabox)>body,html.i-amphtml-singledoc:not(.i-amphtml-inabox)>body{position:relative!important}html.i-amphtml-ios-embed-legacy>body{overflow-x:hidden!important;overflow-y:auto!important;position:absolute!important}html.i-amphtml-ios-embed{overflow-y:auto!important;position:static}#i-amphtml-wrapper{overflow-x:hidden!important;overflow-y:auto!important;position:absolute!important;top:0!important;left:0!important;right:0!important;bottom:0!important;margin:0!important;display:block!important}html.i-amphtml-ios-embed.i-amphtml-ios-overscroll,html.i-amphtml-ios-embed.i-amphtml-ios-overscroll>#i-amphtml-wrapper{-webkit-overflow-scrolling:touch!important}#i-amphtml-wrapper>body{position:relative!important;border-top:1px solid transparent!important}#i-amphtml-wrapper+body{visibility:visible}#i-amphtml-wrapper+body .i-amphtml-lightbox-element,#i-amphtml-wrapper+body[i-amphtml-lightbox]{visibility:hidden}#i-amphtml-wrapper+body[i-amphtml-lightbox] .i-amphtml-lightbox-element{visibility:visible}#i-amphtml-wrapper.i-amphtml-scroll-disabled,.i-amphtml-scroll-disabled{overflow-x:hidden!important;overflow-y:hidden!important}amp-instagram{padding:54px 0px 0px!important;background-color:#fff}amp-iframe iframe{box-sizing:border-box!important}[amp-access][amp-access-hide]{display:none}[subscriptions-dialog],body:not(.i-amphtml-subs-ready) [subscriptions-action],body:not(.i-amphtml-subs-ready) [subscriptions-section]{display:none!important}amp-experiment,amp-live-list>[update]{display:none}amp-list[resizable-children]>.i-amphtml-loading-container.amp-hidden{display:none!important}amp-list [fetch-error],amp-list[load-more] [load-more-button],amp-list[load-more] [load-more-end],amp-list[load-more] [load-more-failed],amp-list[load-more] [load-more-loading]{display:none}amp-list[diffable] div[role=list]{display:block}amp-story-page,amp-story[standalone]{min-height:1px!important;display:block!important;height:100%!important;margin:0!important;padding:0!important;overflow:hidden!important;width:100%!important}amp-story[standalone]{background-color:#000!important;position:relative!important}amp-story-page{background-color:#757575}amp-story .amp-active>div,amp-story .i-amphtml-loader-background{display:none!important}amp-story-page:not(:first-of-type):not([distance]):not([active]){transform:translateY(1000vh)!important}amp-autocomplete{position:relative!important;display:inline-block!important}amp-autocomplete>input,amp-autocomplete>textarea{padding:0.5rem;border:1px solid rgba(0,0,0,.33)}.i-amphtml-autocomplete-results,amp-autocomplete>input,amp-autocomplete>textarea{font-size:1rem;line-height:1.5rem}[amp-fx^=fly-in]{visibility:hidden}amp-script[nodom],amp-script[sandboxed]{position:fixed!important;top:0!important;width:1px!important;height:1px!important;overflow:hidden!important;visibility:hidden} /*# sourceURL=/css/ampdoc.css*/[hidden]{display:none!important}.i-amphtml-element{display:inline-block}.i-amphtml-blurry-placeholder{transition:opacity 0.3s cubic-bezier(0.0,0.0,0.2,1)!important;pointer-events:none}[layout=nodisplay]:not(.i-amphtml-element){display:none!important}.i-amphtml-layout-fixed,[layout=fixed][width][height]:not(.i-amphtml-layout-fixed){display:inline-block;position:relative}.i-amphtml-layout-responsive,[layout=responsive][width][height]:not(.i-amphtml-layout-responsive),[width][height][heights]:not([layout]):not(.i-amphtml-layout-responsive),[width][height][sizes]:not(img):not([layout]):not(.i-amphtml-layout-responsive){display:block;position:relative}.i-amphtml-layout-intrinsic,[layout=intrinsic][width][height]:not(.i-amphtml-layout-intrinsic){display:inline-block;position:relative;max-width:100%}.i-amphtml-layout-intrinsic .i-amphtml-sizer{max-width:100%}.i-amphtml-intrinsic-sizer{max-width:100%;display:block!important}.i-amphtml-layout-container,.i-amphtml-layout-fixed-height,[layout=container],[layout=fixed-height][height]:not(.i-amphtml-layout-fixed-height){display:block;position:relative}.i-amphtml-layout-fill,.i-amphtml-layout-fill.i-amphtml-notbuilt,[layout=fill]:not(.i-amphtml-layout-fill),body noscript>*{display:block;overflow:hidden!important;position:absolute;top:0;left:0;bottom:0;right:0}body noscript>*{position:absolute!important;width:100%;height:100%;z-index:2}body noscript{display:inline!important}.i-amphtml-layout-flex-item,[layout=flex-item]:not(.i-amphtml-layout-flex-item){display:block;position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.i-amphtml-layout-fluid{position:relative}.i-amphtml-layout-size-defined{overflow:hidden!important}.i-amphtml-layout-awaiting-size{position:absolute!important;top:auto!important;bottom:auto!important}i-amphtml-sizer{display:block!important}@supports (aspect-ratio:1/1){i-amphtml-sizer.i-amphtml-disable-ar{display:none!important}}.i-amphtml-blurry-placeholder,.i-amphtml-fill-content{display:block;height:0;max-height:100%;max-width:100%;min-height:100%;min-width:100%;width:0;margin:auto}.i-amphtml-layout-size-defined .i-amphtml-fill-content{position:absolute;top:0;left:0;bottom:0;right:0}.i-amphtml-replaced-content,.i-amphtml-screen-reader{padding:0!important;border:none!important}.i-amphtml-screen-reader{position:fixed!important;top:0px!important;left:0px!important;width:4px!important;height:4px!important;opacity:0!important;overflow:hidden!important;margin:0!important;display:block!important;visibility:visible!important}.i-amphtml-screen-reader~.i-amphtml-screen-reader{left:8px!important}.i-amphtml-screen-reader~.i-amphtml-screen-reader~.i-amphtml-screen-reader{left:12px!important}.i-amphtml-screen-reader~.i-amphtml-screen-reader~.i-amphtml-screen-reader~.i-amphtml-screen-reader{left:16px!important}.i-amphtml-unresolved{position:relative;overflow:hidden!important}.i-amphtml-select-disabled{-webkit-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.i-amphtml-notbuilt,[layout]:not(.i-amphtml-element),[width][height][heights]:not([layout]):not(.i-amphtml-element),[width][height][sizes]:not(img):not([layout]):not(.i-amphtml-element){position:relative;overflow:hidden!important;color:transparent!important}.i-amphtml-notbuilt:not(.i-amphtml-layout-container)>*,[layout]:not([layout=container]):not(.i-amphtml-element)>*,[width][height][heights]:not([layout]):not(.i-amphtml-element)>*,[width][height][sizes]:not([layout]):not(.i-amphtml-element)>*{display:none}amp-img:not(.i-amphtml-element)[i-amphtml-ssr]>img.i-amphtml-fill-content{display:block}.i-amphtml-notbuilt:not(.i-amphtml-layout-container),[layout]:not([layout=container]):not(.i-amphtml-element),[width][height][heights]:not([layout]):not(.i-amphtml-element),[width][height][sizes]:not(img):not([layout]):not(.i-amphtml-element){color:transparent!important;line-height:0!important}.i-amphtml-ghost{visibility:hidden!important}.i-amphtml-element>[placeholder],[layout]:not(.i-amphtml-element)>[placeholder],[width][height][heights]:not([layout]):not(.i-amphtml-element)>[placeholder],[width][height][sizes]:not([layout]):not(.i-amphtml-element)>[placeholder]{display:block;line-height:normal}.i-amphtml-element>[placeholder].amp-hidden,.i-amphtml-element>[placeholder].hidden{visibility:hidden}.i-amphtml-element:not(.amp-notsupported)>[fallback],.i-amphtml-layout-container>[placeholder].amp-hidden,.i-amphtml-layout-container>[placeholder].hidden{display:none}.i-amphtml-layout-size-defined>[fallback],.i-amphtml-layout-size-defined>[placeholder]{position:absolute!important;top:0!important;left:0!important;right:0!important;bottom:0!important;z-index:1}amp-img[i-amphtml-ssr]:not(.i-amphtml-element)>[placeholder]{z-index:auto}.i-amphtml-notbuilt>[placeholder]{display:block!important}.i-amphtml-hidden-by-media-query{display:none!important}.i-amphtml-element-error{background:red!important;color:#fff!important;position:relative!important}.i-amphtml-element-error:before{content:attr(error-message)}i-amp-scroll-container,i-amphtml-scroll-container{position:absolute;top:0;left:0;right:0;bottom:0;display:block}i-amp-scroll-container.amp-active,i-amphtml-scroll-container.amp-active{overflow:auto;-webkit-overflow-scrolling:touch}.i-amphtml-loading-container{display:block!important;pointer-events:none;z-index:1}.i-amphtml-notbuilt>.i-amphtml-loading-container{display:block!important}.i-amphtml-loading-container.amp-hidden{visibility:hidden}.i-amphtml-element>[overflow]{cursor:pointer;position:relative;z-index:2;visibility:hidden;display:initial;line-height:normal}.i-amphtml-layout-size-defined>[overflow]{position:absolute}.i-amphtml-element>[overflow].amp-visible{visibility:visible}template{display:none!important}.amp-border-box,.amp-border-box *,.amp-border-box :after,.amp-border-box :before{box-sizing:border-box}amp-pixel{display:none!important}amp-analytics,amp-auto-ads,amp-story-auto-ads{position:fixed!important;top:0!important;width:1px!important;height:1px!important;overflow:hidden!important;visibility:hidden}amp-story{visibility:hidden!important}html.i-amphtml-fie>amp-analytics{position:initial!important}[visible-when-invalid]:not(.visible),form [submit-error],form [submit-success],form [submitting]{display:none}amp-accordion{display:block!important}@media (min-width:1px){:where(amp-accordion>section)>:first-child{margin:0;background-color:#efefef;padding-right:20px;border:1px solid #dfdfdf}:where(amp-accordion>section)>:last-child{margin:0}}amp-accordion>section{float:none!important}amp-accordion>section>*{float:none!important;display:block!important;overflow:hidden!important;position:relative!important}amp-accordion,amp-accordion>section{margin:0}amp-accordion:not(.i-amphtml-built)>section>:last-child{display:none!important}amp-accordion:not(.i-amphtml-built)>section[expanded]>:last-child{display:block!important} /*# sourceURL=/css/ampshared.css*/</style></head> section of your document:






<html i-amphtml-layout i-amphtml-no-boilerplate transformed="self;v=1"><br> <style> v\:* { behavior: url(#default#VML);} </style></br></html>

Advertisment








This informs the parser that the VML is to be rendered as default. These two additions to your HTML page will make the page ready to contain VML elements.

To create a smiley face using VML, insert the following code into the

<body></body>:






<html i-amphtml-layout i-amphtml-no-boilerplate transformed="self;v=1"><v:group height:100px’="" id="”face”" style="’width:100px;"><br> <v:oval style="’width:100pt;height:100pt’"> </v:oval><br></br> <v:oval 10''''''''="" 25pt;="" height:10pt;="" left:="" style="’position:absolute;" top:="" width:10pt;="" z-index:=""> </v:oval><br></br> <v:oval 10''''''''="" 25pt;="" 55pt;="" height:10pt;="" left:="" style="’position:absolute;" top:="" width:10pt;="" z-index:=""> </v:oval><br></br> <v:arc 25pt;="" 35pt;="" left:="" sty__le="’position:absolute;" top:="" width:50pt;height:50pt’<br=""></v:arc> startangle=”90" endangle=”270"<br></br> strokecolor=”red” strokeweight=”2pt”/&gt;<br></br> </br></v:group></html>


Advertisment
A list of predefined shapes
Tag  Attributes Example
line  from,to

&lt; v:line from=”20pt,20pt” to=”100pt,20pt”&gt;

rect  none reqd  &lt; v:rect style=’width:100pt;height:75pt’&gt;
roundrect arcsize &lt; v:roundrect style=’width:100pt;height: 75pt”<br></br> arcsize=”0.3"&gt;
polyline  points  &lt; v:polyline points=”18pt,54pt,90pt,-9pt, 180pt,63pt,261pt,27pt” &gt; 
curve from, to, control2 control1, from=”0,0" &lt; v:curve style=’position:absolute’<br></br> control1=”100pt,100pt” control2=”200pt, 100pt” to=”300pt,0" 
arc startangle, endangle &lt; v:arc style=’width:100pt;height:100pt’startangle=”0"<br></br> endangle=”90"&gt; 





This code is pretty simple. All it does is create a large oval of equal height and width (therefore a circle) for the face, a couple of smaller circles for the eyes and an arc for the smiling mouth. This entire shape is “grouped” under a single ID called “face” to allow manipulation by client script if required. 

Advertisment

You may have noticed that the elements are positioned as well as sized using the STYLE attribute. And yes, this is the same STYLE attribute used for setting CSS values in your Web pages. You can use CSS to customize your VML as you like. 

The code also shows some other attributes in the arc element. The startangle and endangle let you define the angles for the arc. These attributes are specific to the arc element. However, elements like strokecolor and strokeweight are generic and can be used with almost all other elements. 

So, what are the shapes you can draw? Well, the table shows you a list of predefined shapes, their most common attributes, and an example of usage.

Advertisment

Each of these can be highly customized with colors, filling, positioning, and sizing. They can also be grouped together to form more complex shapes. However, sometimes you need to create a shape that doesn’t fit into any of the above cases. This is where the element comes handy. 

We’ll look at the shape element, how it’s used, and a practical application of VML in the next and final part of this series. Till then, have fun experimenting.

Vinod Unny

is a technology Consultant at iSquare Technologies Pvt Ltd.

Advertisment