HTML Art

This post demonstrates how jsDraw2D can be used to generate drawings that are displayed strictly in code, with no images. To do this I have modified the file Bezier.html. The latest file can be downloaded from this site. Click the Downloads menu item to get the latest version of the file.

The changes in the file are as follow:

A file input to choose an image: Put the image in the same folder as Bezier.html.

Besides the Trace and Trace Open options, the Image option can also be used for tracing. Clicking the Image button will load the image chosen by the file input. The size displayed is still modified only by changing the values set in Bezier.html. Using any method to trace the outline by clicking points, Open Curve, Closed Curve, Border Curve and now, Polygon will create the figure. The coordinates can then be copied and pasted into the html file of the drawing. When this is done, reload Bezier.html, load the image again, trace another section and again copy and paste the coordinates. To create an original drawing, after each step of pasting coordinates, view the drawing in a browser, capture and save the image from the screen and use the captured image as the template from which to add other figures.

A new radiobutton, to create polygons has been added. It works the same as any of the curves. As soon as the chosen number of vertices is reached, the figure is drawn and the coordinates can be obtained.

To do any kind of drawing, first set the hex value of the fill color and click the fill box if a fill is desired. Then click Image if tracing is desired or an original drawing is being continued. Add the number of points and click the type of figure to be created, either a curve or polygon and click the outline of the figure. After the figure is shown, the outline can be adjusted by dragging the control points, as previously described. Dragging any control point also displays the coordinates, which can be copied and pasted.

Here is an example of a drawing that can be created:

DrawImage

Click image for larger view

Here is the code for that image:

<!DOCTYPE html PUBLIC ‘-//W3C//DTD XHTML 1.0 Transitional//EN’ ‘http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd’>
<html xmlns=’http://www.w3.org/1999/xhtml’>
<head profile=’http://gmpg.org/xfn/11’>
<title>Bezier</title>
<style type=’text/css’>
body {margin-left:0;margin-right:0;font:normal normal normal 12px Arial;}
a{ text-decoration: }
:link { color: rgb(0, 0, 255) }
:visited {color :rgb(100, 0,100) }
:hover { }
:active { }
#canvas{position: absolute; width: 90%; height: 80%; left:10%; top: 0%;}
</style>
<script type=”text/JavaScript” src=”jsDraw2D.js”></script>
<script type=”text/JavaScript”>
var str = “”; var str2=””;
var i = 0;
function draw() {
var gr = new jsGraphics(document.getElementById(“canvas”));
points = new Array(new jsPoint(65,656), new jsPoint(60,595), new jsPoint(65,532), new jsPoint(67,450), new jsPoint(83,375), new jsPoint(92,335), new jsPoint(104,291), new jsPoint(117,241), new jsPoint(135,189), new jsPoint(158,159), new jsPoint(186,112), new jsPoint(227,76), new jsPoint(261,59), new jsPoint(293,58), new jsPoint(345,53), new jsPoint(391,62), new jsPoint(433,77), new jsPoint(470,98), new jsPoint(509,152), new jsPoint(529,200), new jsPoint(556,330), new jsPoint(551,383), new jsPoint(537,420), new jsPoint(522,444), new jsPoint(493,489), new jsPoint(487,537), new jsPoint(502,583), new jsPoint(545,626), new jsPoint(563,661), new jsPoint(563,661));
gr.fillClosedCurve(new jsColor(“#553311”), points);
points2 = new Array(new jsPoint(282,661), new jsPoint(259,588), new jsPoint(218,552), new jsPoint(183,465), new jsPoint(172,415), new jsPoint(163,374), new jsPoint(181,347), new jsPoint(183,291), new jsPoint(217,246), new jsPoint(267,214), new jsPoint(332,204), new jsPoint(381,211), new jsPoint(428,240), new jsPoint(461,285), new jsPoint(493,320), new jsPoint(506,346), new jsPoint(524,319), new jsPoint(538,311), new jsPoint(550,328), new jsPoint(545,362), new jsPoint(543,389), new jsPoint(525,433), new jsPoint(509,438), new jsPoint(494,438), new jsPoint(493,487), new jsPoint(489,521), new jsPoint(488,552), new jsPoint(505,587), new jsPoint(544,623), new jsPoint(561,667));
gr.fillClosedCurve(new jsColor(“#FFEECC”), points2);
points3 = new Array(new jsPoint(251,579), new jsPoint(278,602), new jsPoint(301,620), new jsPoint(324,630), new jsPoint(345,631), new jsPoint(370,625), new jsPoint(385,621), new jsPoint(401,613), new jsPoint(414,603), new jsPoint(427,592), new jsPoint(445,580), new jsPoint(455,570), new jsPoint(466,560), new jsPoint(473,547), new jsPoint(479,534), new jsPoint(483,524), new jsPoint(489,505), new jsPoint(492,491), new jsPoint(493,482), new jsPoint(493,474));
gr.drawCurve(new jsPen( new jsColor(“black”),2), points3);
points4 = new Array(new jsPoint(280,537), new jsPoint(300,537), new jsPoint(319,537), new jsPoint(335,537), new jsPoint(348,536), new jsPoint(361,534), new jsPoint(375,534), new jsPoint(397,529), new jsPoint(394,543), new jsPoint(385,550), new jsPoint(377,558), new jsPoint(370,563), new jsPoint(362,569), new jsPoint(350,572), new jsPoint(338,574), new jsPoint(328,571), new jsPoint(316,570), new jsPoint(307,565), new jsPoint(299,561), new jsPoint(285,555));
gr.fillClosedCurve(new jsColor(“#FF5599”), points4);
gr.drawCurve(new jsPen( new jsColor(“#DD3366”),2), points4);
points5 = new Array(new jsPoint(310,548), new jsPoint(310,548), new jsPoint(337,547), new jsPoint(360,545), new jsPoint(360,549), new jsPoint(346,554), new jsPoint(341,554), new jsPoint(332,556), new jsPoint(310,548), new jsPoint(310,548));
gr.fillClosedCurve(new jsColor(“#EEEEEE”), points5);
/*points6 = new Array(new jsPoint(291,389), new jsPoint(291,389), new jsPoint(304,412), new jsPoint(310,430), new jsPoint(312,446), new jsPoint(308,460), new jsPoint(298,470), new jsPoint(300,485), new jsPoint(311,502), new jsPoint(324,507), new jsPoint(339,507), new jsPoint(354,500), new jsPoint(366,489), new jsPoint(355,461), new jsPoint(346,449), new jsPoint(343,427), new jsPoint(344,401), new jsPoint(354,377), new jsPoint(354,377), new jsPoint(357,371));*/
points6 = new Array(new jsPoint(350,375), new jsPoint(342,414), new jsPoint(351,446), new jsPoint(365,464), new jsPoint(367,485), new jsPoint(358,501), new jsPoint(341,502), new jsPoint(322,502), new jsPoint(308,503), new jsPoint(293,491), new jsPoint(293,475), new jsPoint(300,463), new jsPoint(305,447), new jsPoint(308,435), new jsPoint(306,405), new jsPoint(303,400), new jsPoint(298,392), new jsPoint(295,383));
gr.drawCurve(new jsPen( new jsColor(“#996633”),2), points6);
points7 = new Array(new jsPoint(359,384), new jsPoint(376,376), new jsPoint(392,373), new jsPoint(406,373), new jsPoint(420,374), new jsPoint(437,379), new jsPoint(436,393), new jsPoint(427,399), new jsPoint(417,406), new jsPoint(406,407), new jsPoint(374,403), new jsPoint(374,403));
gr.fillClosedCurve(new jsColor(“#EEEEEE”), points7);
gr.drawClosedCurve(new jsPen( new jsColor(“#333333”),2), points7);
points8 = new Array(new jsPoint(212,406), new jsPoint(212,406), new jsPoint(238,389), new jsPoint(249,388), new jsPoint(266,389), new jsPoint(280,393), new jsPoint(285,404), new jsPoint(272,420), new jsPoint(262,422), new jsPoint(248,423), new jsPoint(227,419), new jsPoint(227,419));
gr.fillClosedCurve(new jsColor(“#EEEEEE”), points8);
gr.drawClosedCurve(new jsPen( new jsColor(“#333333”),2), points8);
points9 = new Array(new jsPoint(502,437), new jsPoint(496,432), new jsPoint(499,416), new jsPoint(500,400), new jsPoint(507,371), new jsPoint(508,360), new jsPoint(505,345));
gr.drawCurve(new jsPen( new jsColor(“black”),2), points9);
gr.fillCircle(new jsColor(“#AAAAFF”),new jsPoint(250,406) , 16);
gr.fillCircle(new jsColor(“#AAAAFF”),new jsPoint(398,390) , 16);
gr.fillCircle(new jsColor(“black”),new jsPoint(250,406) , 5);
gr.fillCircle(new jsColor(“black”),new jsPoint(398,390) , 5);
points10 = new Array(new jsPoint(351,364), new jsPoint(372,359), new jsPoint(395,355), new jsPoint(417,352), new jsPoint(436,353), new jsPoint(452,361), new jsPoint(442,362), new jsPoint(428,362), new jsPoint(415,366), new jsPoint(401,369), new jsPoint(383,372), new jsPoint(364,372));
gr.fillClosedCurve(new jsColor(“#553311”), points10);
points11 = new Array(new jsPoint(189,388), new jsPoint(197,383), new jsPoint(212,375), new jsPoint(238,372), new jsPoint(265,372), new jsPoint(290,380), new jsPoint(282,386), new jsPoint(267,384), new jsPoint(251,384), new jsPoint(237,384), new jsPoint(222,383), new jsPoint(207,387));
gr.fillClosedCurve(new jsColor(“#553311”), points11);
points12 = new Array(new jsPoint(522,352), new jsPoint(528,334), new jsPoint(538,321), new jsPoint(539,340), new jsPoint(537,363), new jsPoint(528,389), new jsPoint(523,418), new jsPoint(507,430), new jsPoint(510,415), new jsPoint(515,387));
gr.drawClosedCurve(new jsPen( new jsColor(“black”),2), points12);}
</script>
</head>
<body>
<div id=’canvas’ onclick=’draw();’></div>
</body></html>I confess that my artistic quotient is close to zero, but I believe an artistic person could create a very nice work of art.

 

I confess that my artistic quotient is close to zero, but I believe an artistic person could create a very nice work of art.

Another HTML Optical Illusion – Parallel Lines?

This is another optical illusion created without any images,

Here is the appearance:

Click image for larger view

parallel

Those gray lines between the black and white boxes are actually parallel.

Here is the code:

<!DOCTYPE html PUBLIC ‘-//W3C//DTD XHTML 1.0 Transitional//EN’ ‘http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd’&gt;
<html xmlns=’http://www.w3.org/1999/xhtml’&gt;
<head profile=’http://gmpg.org/xfn/11′&gt;
<title>Parallel Illusion</title>
<style type=’text/css’>
body {margin-left:0;margin-right:0;font:normal normal normal 12px Arial; }
a{ text-decoration: }
:link { color: rgb(0, 0, 255) }
:visited {color :rgb(100, 0,100) }
:hover { }
:active { }
#frame{position: absolute; width: 1100px ;left: 50%; margin-left: -550px; top: 0; height: 100%; }
#l11,#l12,#l13,#l14,#l15,#l16,#l17,#l18,#l19,#l110{position: absolute; top: 40px; width: 50px; height: 50px; background: black; }
#l21,#l22,#l23,#l24,#l25,#l26,#l27,#l28,#l29,#l210{position: absolute; top: 93px; width: 50px; height: 50px; background: black; }
#l31,#l32,#l33,#l34,#l35,#l36,#l37,#l38,#l39,#l310{position: absolute; top: 146px; width: 50px; height: 50px; background: black; }
#l41,#l42,#l43,#l44,#l45,#l46,#l47,#l48,#l49,#l410{position: absolute; top: 199px; width: 50px; height: 50px; background: black; }
#l51,#l52,#l53,#l54,#l55,#l56,#l57,#l58,#l59,#l510{position: absolute; top: 252px; width: 50px; height: 50px; background: black; }
#l61,#l62,#l63,#l64,#l65,#l66,#l67,#l68,#l69,#l610{position: absolute; top: 305px; width: 50px; height: 50px; background: black; }
#l71,#l72,#l73,#l74,#l75,#l76,#l77,#l78,#l79,#l710{position: absolute; top: 358px; width: 50px; height: 50px; background: black; }
#l81,#l82,#l83,#l84,#l85,#l86,#l87,#l88,#l89,#l810{position: absolute; top: 411px; width: 50px; height: 50px; background: black; }
#l91,#l92,#l93,#l94,#l95,#l96,#l97,#l98,#l99,#l910{position: absolute; top: 464px; width: 50px; height: 50px; background: black; }
#l101,#l102,#l103,#l104,#l105,#l106,#l107,#l108,#l109,#l1010{position: absolute; top: 517px; width: 50px; height: 50px; background: black; }
.line1{position: absolute; left: 90px; top: 90px; height: 3px; width: 1000px; background: gray}
.line2{position: absolute; left: 90px; top: 143px; height: 3px; width: 1000px; background: gray}
.line3{position: absolute; left: 90px; top: 196px; height: 3px; width: 1000px; background: gray}
.line4{position: absolute; left: 90px; top: 249px; height: 3px; width: 1000px; background: gray}
.line5{position: absolute; left: 90px; top: 302px; height: 3px; width: 1000px; background: gray}
.line6{position: absolute; left: 90px; top: 355px; height: 3px; width: 1000px; background: gray}
.line7{position: absolute; left: 90px; top: 408px; height: 3px; width: 1000px; background: gray}
.line8{position: absolute; left: 90px; top: 461px; height: 3px; width: 1000px; background: gray}
.line9{position: absolute; left: 90px; top: 514px; height: 3px; width: 1000px; background: gray}
</style>
<script type=”text/javascript”>
function hide() {
for (var i = 1; i <= 10; i ++){
layr = “l1” + i.toString()
layr2 = “l2” + i.toString();
layr3 = “l3” + i.toString();
layr4 = “l4” + i.toString();
layr5 = “l5” + i.toString();
layr6 = “l6” + i.toString();
layr7 = “l7” + i.toString();
layr8 = “l8” + i.toString();
layr9 = “l9” + i.toString();
layr10 = “l10″ + i.toString();
document.getElementById(layr).style.visibility=”hidden”;
document.getElementById(layr2).style.visibility=”hidden”;
document.getElementById(layr3).style.visibility=”hidden”;
document.getElementById(layr4).style.visibility=”hidden”;
document.getElementById(layr5).style.visibility=”hidden”;
document.getElementById(layr6).style.visibility=”hidden”;
document.getElementById(layr7).style.visibility=”hidden”;
document.getElementById(layr8).style.visibility=”hidden”;
document.getElementById(layr9).style.visibility=”hidden”;
document.getElementById(layr10).style.visibility=”hidden”;
}
}function posit() {
var layr; var layr2; var layr3; var layr4; var layr5; var layr6; var layr7; var layr8; var layr9; var layr10;

for (var i = 1; i <= 10; i ++){
layr = “l1” + i.toString()
layr2 = “l2” + i.toString();
layr3 = “l3” + i.toString();
layr4 = “l4” + i.toString();
layr5 = “l5” + i.toString();
layr6 = “l6” + i.toString();
layr7 = “l7” + i.toString();
layr8 = “l8” + i.toString();
layr9 = “l9” + i.toString();
layr10 = “l10” + i.toString();
var lft = (i * 100).toString() + “px”;
var lft2 = (i * 100 + 15).toString() + “px”;
var lft3 = (i * 100 + 25).toString() + “px”;
var lft4 = (i * 100 + 17).toString() + “px”;
var lft5 = (i * 100).toString() + “px”;
var lft6 = (i * 100 + 15).toString() + “px”;
var lft7 = (i * 100 + 25).toString() + “px”;
var lft8 = (i * 100 + 15).toString() + “px”;
var lft9 = (i * 100).toString() + “px”;
var lft10 = (i * 100 + 15).toString() + “px”;
document.getElementById(“frame”).innerHTML=document.getElementById(“frame”).innerHTML + ‘<div id=’ + layr + ‘ onclick=\’hide()\’></div>’;
document.getElementById(layr).style.left=lft;
document.getElementById(“frame”).innerHTML=document.getElementById(“frame”).innerHTML + ‘<div id=’ + layr2 + ‘></div>’;
document.getElementById(layr2).style.left=lft2;
document.getElementById(“frame”).innerHTML=document.getElementById(“frame”).innerHTML + ‘<div id=’ + layr3 + ‘></div>’;
document.getElementById(layr3).style.left=lft3;
document.getElementById(“frame”).innerHTML=document.getElementById(“frame”).innerHTML + ‘<div id=’ + layr4 + ‘></div>’;
document.getElementById(layr4).style.left=lft4;
document.getElementById(“frame”).innerHTML=document.getElementById(“frame”).innerHTML + ‘<div id=’ + layr5 + ‘></div>’;
document.getElementById(layr5).style.left=lft5;
document.getElementById(“frame”).innerHTML=document.getElementById(“frame”).innerHTML + ‘<div id=’ + layr6 + ‘></div>’;
document.getElementById(layr6).style.left=lft6;
document.getElementById(“frame”).innerHTML=document.getElementById(“frame”).innerHTML + ‘<div id=’ + layr7 + ‘></div>’;
document.getElementById(layr7).style.left=lft7;
document.getElementById(“frame”).innerHTML=document.getElementById(“frame”).innerHTML + ‘<div id=’ + layr8 + ‘></div>’;
document.getElementById(layr8).style.left=lft8;
document.getElementById(“frame”).innerHTML=document.getElementById(“frame”).innerHTML + ‘<div id=’ + layr9 + ‘></div>’;
document.getElementById(layr9).style.left=lft9;
document.getElementById(“frame”).innerHTML=document.getElementById(“frame”).innerHTML + ‘<div id=’ + layr10 + ‘></div>’;
document.getElementById(layr10).style.left=lft10;
}
document.getElementById(“frame”).innerHTML=document.getElementById(“frame”).innerHTML + ‘<div class=”line1″></div>’;
document.getElementById(“frame”).innerHTML=document.getElementById(“frame”).innerHTML + ‘<div class=”line2″></div>’;
document.getElementById(“frame”).innerHTML=document.getElementById(“frame”).innerHTML + ‘<div class=”line3″></div>’;
document.getElementById(“frame”).innerHTML=document.getElementById(“frame”).innerHTML + ‘<div class=”line4″></div>’;
document.getElementById(“frame”).innerHTML=document.getElementById(“frame”).innerHTML + ‘<div class=”line5″></div>’;
document.getElementById(“frame”).innerHTML=document.getElementById(“frame”).innerHTML + ‘<div class=”line6″></div>’;
document.getElementById(“frame”).innerHTML=document.getElementById(“frame”).innerHTML + ‘<div class=”line7″></div>’;
document.getElementById(“frame”).innerHTML=document.getElementById(“frame”).innerHTML + ‘<div class=”line8″></div>’;
document.getElementById(“frame”).innerHTML=document.getElementById(“frame”).innerHTML + ‘<div class=”line9″></div>’;
}
</script>
</head>
<body onload=’posit();’>
<div id=”frame”></div>

</body>
</html>

To prove the lines are really parallel, click any of the black boxes in the top row and all the boxes will be hidden.

The boxes and the “lines” are all divisions.  Boxes with common properties (size and top) are listed with the common css properties:

#l11,#l12,#l13,#l14,#l15,#l16,#l17,#l18,#l19,#l110{position: absolute; top: 40px; width: 50px; height: 50px; background: black; }

The horizontal position is then set with the function posit():

for (var i = 1; i <= 10; i ++){
layr = “l1” + i.toString()

var lft = (i * 100).toString() + “px”;

document.getElementById(“frame”).innerHTML=document.getElementById(“frame”).innerHTML + ‘<div id=’ + layr + ‘ onclick=\’hide()\’></div>’

document.getElementById(layr).style.left=lft;

A similar function,  hide() is used to remove the boxes so the lines can be seen without the background;

function hide() {

for (var i = 1; i <= 10; i ++){
layr = “l1” + i.toString()
layr2 = “l2” + i.toString();
layr3 = “l3” + i.toString();
layr4 = “l4” + i.toString();
layr5 = “l5” + i.toString();
layr6 = “l6” + i.toString();
layr7 = “l7” + i.toString();
layr8 = “l8” + i.toString();
layr9 = “l9” + i.toString();
layr10 = “l10″ + i.toString();
document.getElementById(layr).style.visibility=”hidden”;
document.getElementById(layr2).style.visibility=”hidden”;
document.getElementById(layr3).style.visibility=”hidden”;
document.getElementById(layr4).style.visibility=”hidden”;
document.getElementById(layr5).style.visibility=”hidden”;
document.getElementById(layr6).style.visibility=”hidden”;
document.getElementById(layr7).style.visibility=”hidden”;
document.getElementById(layr8).style.visibility=”hidden”;
document.getElementById(layr9).style.visibility=”hidden”;
document.getElementById(layr10).style.visibility=”hidden”;
}

jsDraw2D Revisited

In a previous post about jsDraw2D, I mentioned it was a work in progress and that additions might be made. This post discusses rwo changes.
Below is an image displaying the changes.

Click image for larger view

newIF
The original file showed a list of the points for the drawn curve. The new one creates a string that can be copied and pasted in its entirety into a new HTML file.

Here is the new code:

#colr{position: relative; width: 100px;  font:normal normal 700 15px Arial}

<input id = “colr” type=”text”  name=”colr” value=”Hex Color” onclick=’getColor();’/>

I also added a new text input box to create custom fills for closed curves. Entering s hex value and clicking the box chnges its background to the entered color. If the color is satisfactory, grabbing a curve handle and moving it will change the fill of a subsequently created curve. Additionally, entering a hex value and clicking the box will change the fill of an existing curve.

Here is the code for that:

function getColor() {
if(document.getElementById(“colr”).value != “Hex Color”) document.getElementById(“colr”).style.color=”white”
cl = document.getElementById(“colr”).value;
document.getElementById(“colr”).style.backgroundColor = cl;
}

if(document.getElementById(“colr”).value != “Hex Color”) gr.fillClosedCurve(new jsColor(cl),  points);
Below is the code for two closed curves, eqch given a different fill, with point and fill values pasted from the creating HTML file:

<!DOCTYPE html PUBLIC ‘-//W3C//DTD XHTML 1.0 Transitional//EN’ ‘http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd’&gt;
<html xmlns=’http://www.w3.org/1999/xhtml’&gt;
<head profile=’http://gmpg.org/xfn/11′&gt;
<title>Bezier</title>
<style type=’text/css’>
body {margin-left:0;margin-right:0;font:normal normal normal 12px Arial;}
a{ text-decoration: }
:link { color: rgb(0, 0, 255) }
:visited {color :rgb(100, 0,100) }
:hover { }
:active { }
#canvas{position: absolute; width: 40%; height: 50%; left:10%; top: 25%; padding: 10px;}
#canvas2{position: absolute; width: 15%; height: 30%; left:50%; top: 25%; padding: 10px;}
</style>
<script type=”text/JavaScript” src=”jsDraw2D.js”></script>
<script type=”text/JavaScript”>
var str = “”; var str2=””;
var i = 0;
function draw() {
var gr = new jsGraphics(document.getElementById(“canvas”));
var gr2 = new jsGraphics(document.getElementById(“canvas2”));
var points = new Array(new jsPoint(272,43), new jsPoint(434,157), new jsPoint(472,285), new jsPoint(382,371), new jsPoint(183,335), new jsPoint(122,177) );
var points2 = new Array(new jsPoint(45,149), new jsPoint(87,155), new jsPoint(78,114), new jsPoint(105,96), new jsPoint(175,110), new jsPoint(98,206), new jsPoint(159,210), new jsPoint(94,234) );
gr.fillClosedCurve(new jsColor(“#FFEE88”), points);
gr.drawClosedCurve(new jsPen( new jsColor(“black”),3), points);
gr2.fillClosedCurve(new jsColor(“#FF5588”), points2);
gr2.drawClosedCurve(new jsPen( new jsColor(“black”),3), points2);
setInterval(“rot()”, 250);}

function rot() {
i ++;
str = “rotate(” + 6*i + “deg)”;
str2 = “rotate(” + -12*i + “deg)”;
document.getElementById(“canvas”).style.MozTransform=str;
document.getElementById(“canvas”).style.webkitTransform=str;
document.getElementById(“canvas”).style.msTransform=str;
document.getElementById(“canvas2”).style.MozTransform=str2;
document.getElementById(“canvas2”).style.webkitTransform=str2;
document.getElementById(“canvas2”).style.msTransform=str2;
}

</script>

</head>
<body>
<div id=’canvas’ onclick=’draw();’></div>
<div id=’canvas2′ onclick=’draw();’></div>
</body></html>

For good measure, I animated the two curves, each curve having a different rate and direction of rotation.

Click image for larger view

capture2

An Analog HTML Clock

This is a widget that can be placed on a webpage. It uses no images, but is composed from the css Transform, javascript and svg code.
Here is how the clock appears:
Click image for larger view

HTMLClock

Below is the code:

<!DOCTYPE html PUBLIC ‘-//W3C//DTD XHTML 1.0 Transitional//EN’ ‘http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd’&gt; <html xmlns=’http://www.w3.org/1999/xhtml’&gt; <head profile=’http://gmpg.org/xfn/11′&gt; <title>Clock</title>
<style type=’text/css’>
body {margin-left:0;margin-right:0;font:normal normal normal 12px Arial; white-space: pre-wrap}
a{ text-decoration: } :link { color: rgb(0, 0, 255) } :visited {color :rgb(100, 0,100) } :hover { } :active { } #hour{position:absolute;width:8px;height:168px;left:298px;top:90px;background-color:#0000FF;border-width:0;font:normal normal normal 12px Arial; -moz-transform-origin: 4px 148px; -moz-transform: rotate(0deg); -webkit-transform-origin: 4px 148px; -webkit-transform: rotate(0deg); -ms-transform-origin: 4px 148px; -ms-transform: rotate(0deg); } #minute{position:absolute;width:6px;height:188px;left:299px;top:70px;background-color:#00FF00;border-width:0;font:normal normal normal 12px Arial; -moz-transform-origin: 3px 168px; -moz-transform: rotate(0deg); -webkit-transform-origin: 3px 168px; -webkit-transform: rotate(0deg); -ms-transform-origin: 3px 168px; -ms-transform: rotate(0deg); } #second{position:absolute;width:2px;height:208px;left:300px;top:50px;background-color:#FF0000;border-width:0;font:normal normal normal 12px Arial; -moz-transform-origin: 1px 188px; -moz-transform: rotate(0deg); -webkit-transform-origin: 1px 188px; -webkit-transform: rotate(0deg); -ms-transform-origin: 1px 188px; -ms-transform: rotate(0deg); } #block{position:absolute;width:8px;height:8px;left:297px;top:234px;background-color:#FF0000;border-width:0;font:normal normal normal 12px Arial; -moz-transform-origin: 4px 4px; -moz-transform: rotate(0deg); -webkit-transform-origin: 4px 4px; -webkit-transform: rotate(0deg); -ms-transform-origin: 4px 4px; -ms-transform: rotate(0deg); } </style>
<script type=’text/javascript’>
var cnt1 = 0; var cnt2 = 0; var cnt3 = 0; var str; var date = new Date();
function rotate() {
var s = parseInt(date.getSeconds());
cnt1 = s * 6;
str = “rotate(” + cnt1 + “deg)”; document.getElementById(“second”).style.MozTransform=str; document.getElementById(“second”).style.webkitTransform=str; document.getElementById(“second”).style.msTransform=str;
var m = parseInt(date.getMinutes());
cnt2 = m * 6;
str2 = “rotate(” + cnt2 + “deg)”; document.getElementById(“minute”).style.MozTransform=str2; document.getElementById(“minute”).style.webkitTransform=str2; document.getElementById(“minute”).style.msTransform=str2;
var h = parseInt(date.getHours());
h = h > 12 ? h-12: h;
cnt3 = h * 30;
str3 = “rotate(” + cnt3 + “deg)”; document.getElementById(“hour”).style.MozTransform=str3; document.getElementById(“hour”).style.webkitTransform=str3; document.getElementById(“hour”).style.msTransform=str3; setInterval(“move1()”, 1000); }
function move1() {
var e3 = document.getElementById(“minute”);
var e4 = document.getElementById(“hour”);
cnt1 +=6;
if (cnt1 == 360) {
cnt1 = 0;
cnt2 += 6;
if (cnt2 == 360) {
cnt2 == 0;
cnt3 += 30;
str3 = “rotate(” + cnt3 + “deg)”;
e4.style.MozTransform=str3;
e4.style.webkitTransform=str3;
e4.style.msTransform=str3; }
str2 = “rotate(” + cnt2 + “deg)”;
e3.style.MozTransform=str2;
e3.style.webkitTransform=str2;
e3.style.msTransform=str2; }
var e = document.getElementById(“second”);
var e2 = document.getElementById(“block”);
str = “rotate(” + cnt1 + “deg)”;
e.style.MozTransform=str;
e.style.webkitTransform=str;
e.style.msTransform=str;
e2.style.MozTransform=str;
e2.style.webkitTransform=str;
e2.style.msTransform=str; }
</script>
</head>
<body onload=’rotate();’>
<svg xmlns=”http://www.w3.org/2000/svg&#8221; version=”1.1″ width=”600″ height= “600”>
<g transform=”translate(302,214)”>
<g>
<circle r=”208″ fill=”#FAFAFF” stroke-width=”4″ stroke=”gray” />
<circle r=”200″ fill=”none” stroke-width=”15″ stroke=”black” stroke-dasharray=”4,101″ transform=”rotate(-1.5)” />
<circle r=”203″ fill=”none” stroke-width=”9″ stroke=”black” stroke-dasharray=”2,19.3″ transform=”rotate(-.873)” />
</g>
</g>
</svg>
<div id=’hour’></div>
<div id=’minute’></div>
<div id=’second’></div>
<div id=’block’></div>
</body>
</html>

 

The face is made from svg code:

<svg xmlns=”http://www.w3.org/2000/svg&#8221; version=”1.1″ width=”600″ height= “600”>
<g transform=”translate(302,214)”>
<g> <circle r=”208″ fill=”#FAFAFF” stroke-width=”4″ stroke=”gray” /> <circle r=”200″ fill=”none” stroke-width=”15″ stroke=”black” stroke-dasharray=”4,101″ transform=”rotate(-1.5)” />
<circle r=”203″ fill=”none” stroke-width=”9″ stroke=”black” stroke-dasharray=”2,19.3″ transform=”rotate(-.873)” />
</g>
</g>
</svg>

The minute tick marks are made from two circles with no fill and dasharray strokes, which makes the strokes perpendicular to the circumference.

<circle r=”200″ fill=”none” stroke-width=”15″ stroke=”black” stroke-dasharray=”4,101″ transform=”rotate(-1.5)” />
<circle r=”203″ fill=”none” stroke-width=”9″ stroke=”black” stroke-dasharray=”2,19.3″ transform=”rotate(-.873)” />

The hand elements are made from css layers:

#hour{position:absolute;width:8px;height:168px;left:298px;top:90px;background-color:#0000FF;border-width:0;font:normal normal normal 12px Arial; -moz-transform-origin: 4px 148px; -moz-transform: rotate(0deg); -webkit-transform-origin: 4px 148px; -webkit-transform: rotate(0deg); -ms-transform-origin: 4px 148px; -ms-transform: rotate(0deg); } #minute{position:absolute;width:6px;height:188px;left:299px;top:70px;background-color:#00FF00;border-width:0;font:normal normal normal 12px Arial; -moz-transform-origin: 3px 168px; -moz-transform: rotate(0deg); -webkit-transform-origin: 3px 168px; -webkit-transform: rotate(0deg); -ms-transform-origin: 3px 168px; -ms-transform: rotate(0deg); } #second{position:absolute;width:2px;height:208px;left:300px;top:50px;background-color:#FF0000;border-width:0;font:normal normal normal 12px Arial; -moz-transform-origin: 1px 188px; -moz-transform: rotate(0deg); -webkit-transform-origin: 1px 188px; -webkit-transform: rotate(0deg); -ms-transform-origin: 1px 188px; -ms-transform: rotate(0deg); } #block{position:absolute;width:8px;height:8px;left:297px;top:234px;background-color:#FF0000;border-width:0;font:normal normal normal 12px Arial; -moz-transform-origin: 4px 4px; -moz-transform: rotate(0deg); -webkit-transform-origin: 4px 4px; -webkit-transform: rotate(0deg); -ms-transform-origin: 4px 4px; -ms-transform: rotate(0deg); }

On loading, the function rotate() is called, which initiates the rotation and calls the move1 function at one second intervals:

function rotate() {
var s = parseInt(date.getSeconds());
cnt1 = s * 6;
str = “rotate(” + cnt1 + “deg)”;
document.getElementById(“second”).style.MozTransform=str; document.getElementById(“second”).style.webkitTransform=str; document.getElementById(“second”).style.msTransform=str;
var m = parseInt(date.getMinutes());
cnt2 = m * 6; str2 = “rotate(” + cnt2 + “deg)”; document.getElementById(“minute”).style.MozTransform=str2; document.getElementById(“minute”).style.webkitTransform=str2; document.getElementById(“minute”).style.msTransform=str2;
var h = parseInt(date.getHours());
h = h > 12 ? h-12: h;
cnt3 = h * 30;
str3 = “rotate(” + cnt3 + “deg)”;
document.getElementById(“hour”).style.MozTransform=str3; document.getElementById(“hour”).style.webkitTransform=str3; document.getElementById(“hour”).style.msTransform=str3; setInterval(“move1()”, 1000); }

The current second, minute and hour are obtained from the date() function:

var s = parseInt(date.getSeconds());
cnt1 = s * 6;
var m = parseInt(date.getMinutes());
cnt2 = m * 6;

The hour is adjusted for a 12 hour clock.

var h = parseInt(date.getHours());
h = h > 12 ? h-12: h;
cnt3 = h * 30;

move1() performs the further rotation.

cnt1 is the second count, cnt2 is the minute count and cnt3 is the hour count. Since a circle has 360 degrees, cnt 1 is increased by 6 each second. Every time cnt1 reaches 360, it is set back to 0 and cnt2 is increased by 6:

if (cnt1 == 360) { cnt1 = 0; cnt2 += 6;

Every time cnt2 reaches 360, it is set to 0 and cnt3 is increased by 30, for a 12 hour clock.

if (cnt2 == 360) { cnt2 == 0; cnt3 += 30;

Strings are then obtained for the rotations.

str = “rotate(” + cnt1 + “deg)”;
str2 = “rotate(” + cnt2 + “deg)”;
str3 = “rotate(” + cnt3 + “deg)”;

The id for each element is then obtained and the css style value transform applied to the strings. For example, with the minutes hand:

var e3 = document.getElementById(“minute”);
str2 = “rotate(” + cnt2 + “deg)”;
str2 = “rotate(” + cnt2 + “deg)”; e3.style.MozTransform=str2; e3.style.webkitTransform=str2;
e3.style.msTransform=str2;

The transform values are browser specific, so included are Moz for Firefox, webkit for Chrome and Safari and ms for IE.