|
by Naveen
14. March 2012 13:28
In my previous post New TextMode proprty values for TextBox in ASP.Net, I
talked about some new values introduced for input HTML element's type in ASP.Net 4.5 server control In this
post I will discuss how to take advantage of these new attribute values to allow your browser to validate
and control user's input without you having to write extra client side code.
See it in action
To see these attributes in action below, you will need to use Chrome browser.
<input type="number" min="1.5" max="50.5" step="1.25" />
<input type=number>
In this post I will focus behavior of text box when type attribute value is set to
number. As the value of this attribute suggests, by setting this value you indicate to the
browser that this text box will only accept numeric type data. This means that you can only enter any valid
floating numbers in the text box. If you will enter text that does not represent a numeric value, the browser
will erase that input from text box. For example if you enter x.y in the text box, the moment
the text box looses focus, the text will be gone. There are more attributes that compliment type
value set to number.
<input "min=" />
By setting attribute min to a valid numeric number you indicate the minumum value the text
box will accept. Currently Chrome does allow to enter value that is out of MIN range. It will bring it back to
MIN value when you try to use numeric updown control to manipulate it,
<input "max=" />
By setting attribute max to a valid numeric number you indicate the maximum value the text
box will accept. Currently Chrome does allow to enter value that is out of MAX range. It will bring it back to
MAX value when you try to use numeric updown control to manipulate it,
<input "step=" />
This attribute defines the step increment for updown control. If you do not set the value for this attribute,
then default value is 1. And it also turns the control into accepting only integer values if min
attribute is not set to a floating point number. So it is important to set min attribute if you want to deal with
floating point numbers. The value of step attribute should be a valid floating point number.
Pros and Cons
The discussion will not be complete without going over some of the pros and cons of using these new attributes.
Pros
When you allow browser to provide first line of validation, then you pretty much reduce the over head
of writing javascript code around it. That means page size if reduced as well as page performance is
improved as well.
Cons
One thing that lack with using browser's attributes is that there is not way to let user know that he or she
is violating some constraint. With ASP.Net validators or some custom implementation you are able to show
informative error message. But I did not find browser triggering any event or displaying some default
message if input does not satisfy some constraint set by attributes.
Despite some limitations, I think it will be worth setting up appropriate attribute values to let browser
do its magic and then add your own light weight validator on top of it.
by Naveen
13. July 2011 07:09
These days I am working very heavily on conversion of existing web applications to use new HTML5 and CSS specifications. So I installed add-on in Visual Studio 2010 to use HTML5 intellisense. Now when I started to create new pages and type HTML tags, I could see new attributes and elements in the intellsense drop down list etc. One of the things that stood out on most of the pages was that all the TABLE elements had greenunderlines for attributes like cellpadding, cellspacing etc. When I hover on those errors, I get the following message.
Validation (HTML5): Attribute 'cellpadding' is not a valid attribute of element 'table'
How to set cellpadding, cellspacing and border for table using CSS
Since a lot of existing web applications have the page structure created using TABLE elements, you will need a solution to get rid of
these obsolete attributes and make your pages CSS compliant. Here what you are going to do.
Set border
Define a style for your table in your CSS file or style section in header of your page. And add border style to it. To control how border is drawn around cells, you will need to add border-collapse style as well. Here is an example of it.
.tablewithspacing
{
border: 1px solid #193144;
border-collapse:separate;
}
.tablewithspacing td
{
border:1px solid #193144;
padding:2px;
vertical-align:top;
}
There are two possible values for border-collapse style.
 | collapse: This value will make border lines collapse or draw on top of each other. You
can see from the image here how border lines are drawn. |
 |
separate: This value will make border lines draw with padding in between. As you can see image how each cell has individual border rectangle drawn. |
If you want to draw border only around the table and not for individual cells then do not set border style for td element.
Set cellpadding
As you can see from the same CSS style, I have set padding style for td element for my table. This will ensure that I have cellpadding of 2px around the cells.
e4bd92d5-c38d-4277-8945-ff23c386a070|0|.0
Views: 2466
Tags: HTML5
CSS | HTML
by Naveen
30. June 2011 16:56
In previous posts,
How to apply transformation and
HTML5 animation, I discussed some basic concepts involved in rendering of graphics is HTML5 and do
some animation. In this post, I am going to show how those concepts can be applied to create a Gauge
chart. The demo implementation of chart also shows how real time change in values can be displayed on the
gauge.
How to create HTML5 Chart?
Following javascript code shows how this gauge chart is rendered. The code shown bold
highlights key concepts used in drawing of gauge chart on canvas.
NetFour.GaugeChart.prototype.draw = function (value, gchart) {
var radius = 75;
var chartObject = gchart || this;
var drawingCtx = chartObject.chart.graphics.drawingCtx;
chartObject.chart.graphics.saveContext();
chartObject.chart.graphics.clearCanvas();
drawingCtx.fillStyle = "rgba(75,175,225,.75)";
drawingCtx.globalAlpha = .9;
drawingCtx.arc(chartObject.chart.canvas.center.x,
chartObject.chart.canvas.height - 20, radius,
Math.PI, Math.PI * 2, false);
drawingCtx.fill();
drawingCtx.translate(chartObject.chart.canvas.center.x,
chartObject.chart.canvas.height - 20);
// Draw tickers.
var rotAngle = 0;
for (var i = 0; i <= 10; i++) {
rotAngle = i == 0 ? 0 : -(180 / 10);
drawingCtx.beginPath();
chartObject.chart.graphics.applyRotation(rotAngle);
drawingCtx.moveTo(radius - 2, 0);
drawingCtx.lineTo(radius + 2, 0);
drawingCtx.stroke();
drawingCtx.closePath();
}
chartObject.chart.graphics.setIdentityTransform();
// Translate to tail of needle.
drawingCtx.translate(chartObject.chart.canvas.center.x,
chartObject.chart.canvas.height - 20);
// Calculate angle.
var angle = value || 0;
if (angle < 0) { angle = 0; }
if (angle > 100) { angle = 100; }
var roundedAngle = Math.round(angle);
drawingCtx.font = "20px sans-serif";
if (angle < 40) {
drawingCtx.fillStyle = "rgba(0,0,255,.75)";
}
else if (angle > 70) {
drawingCtx.fillStyle = "rgba(255,255,0,.75)";
}
else {
drawingCtx.fillStyle = "rgba(255,0,0,.75)";
}
var textWidth = drawingCtx.measureText(roundedAngle).width;
drawingCtx.fillText(roundedAngle, -textWidth / 2, -40);
var angle = 35 - (180 / 100) * angle;
chartObject.chart.graphics.applyRotation(angle);
drawingCtx.drawImage(chartObject.needleImage, -10, -22);
chartObject.chart.graphics.restoreContext();
};
Lets look at some explanation of this code. Rendering starts by drawing a semi-circle
representing base of the scale using arc function. Next translation
matrix is applied to move the origin to center of the semi-circle. By moving the origin
it becomes very easy to calculate positions of tickers and needle. Next all tickers are
drawn along the perimeter of semi-circle. You can see that I used rotation
matrix before drawing ticker lines. This way the ticker line is always along x-axis because
axis were rotated along the angle where ticker needed to be drawn. Now the only
part left is drawing the needle.
To draw needle I copied an image of gauge needle from internet and then used drawImage
function. Very important part of drawing needle image was applying rotation along the angle
to display value represented on the scale. You may be wondering about following line of code.
var angle = 35 - (180 / 100) * angle;
The reason for an offset of 35 degrees is that original image of needle has needle pointed to right
at 35 degree. Therefore offset had to be added to draw original image along x-axis.
Following code shows how page initializes this HTML5 chart and then runs a timer at 500ms
interval to vary the value to be displayed on gauge chart.
var myGChart = null;
var valueTimer = 0;
$(document).ready(function () {
myGChart = new NetFour.GaugeChart('gaugeChartCanvas');
myGChart.needleLoadCallBack = drawTheChart;
myGChart.loadNeedle('meter_needle.png');
});
function drawTheChart() {
clearInterval(valueTimer);
var rndValue = Math.random();
myGChart.draw(rndValue*100);
valueTimer = setInterval(drawTheChart, 500);
}
HTML5 Chart Demo
You can see this gauge chart in action at following location.
HTML5 Gauge Chart Demo
6912c344-6cf2-452f-ab17-ba212c541b2f|0|.0
Views: 3036
Tags: HTML5
HTML
by Naveen
27. June 2011 19:40
In the previous post HTML5 Canvas - How to apply transformation,
I talked about fundamentals of HTML5 canvas transformation. I focused the discussion on two function, translate and
rotate. But graphics transformations is not just limited to translation and rotation. There is lot more to transformation. Lets look at
transformation functions in canvas api one more time.
- context.scale(x, y)
- context.rotate(angle)
- context.translate(x, y)
- context.transform
- context.setTransform(a, b, c, d, e, f)
transform and setTransform functions provide finer control on transformation. But before you use these
functions, it is very important that you understand what kind of transformation 6 parameters a,b,c,d,e and f apply. These
6 parameters are part of the transformation matrix below.
a c e
b d f
0 0 1
Transformation Matrix Components
| Identity Matrix (No transformation) |
|
a: Scale along x-axis |
|
b: Skew along y-axis |
|
c: Skew along x-axis |
|
d: Scale along y-axis |
|
e: Translate along x-axis |
|
f: Translate along y-axis |
|
As you can see that my manipulating these individual matrix components you can create some very powerful
graphics and animation effects.
thisDemo.graphics.drawingCtx.transform(thisDemo.a, thisDemo.b, thisDemo.c, thisDemo.d, thisDemo.e, thisDemo.f);
See it in action
I have implemented a demo application that allows you to play with these 6 parameters to see the effect
on transformation.
HTML5 Transformation Demo
In subsequent posts, I will discuss more on transformations to show some cool animations.
be8da8bc-2c07-4415-b42b-4780b48895d2|0|.0
Views: 2250
Tags: HTML5
HTML
by Naveen
18. June 2011 08:54
I was experimenting with some HTML5 canvas features to create some animation with lines. I ran into some very
interesting effect of rendering on canvas. Let me first describe what I was trying to do and what I ended up with.
- Create a canvas element on page with white background.
- Draw a straight line of thinckness T from point (x1,y1) to point (x2,y2) with red color.
- Draw a straight line of thinckness T from point (x1,y1) to point (x2,y2) with white color.
If you look at description, the end result should be that there is no line visible to user because white line will
be drawn over the red line. But the result was not what I expected. I ended up with following view (two parallel red lines).
My first reaction was that it may be some bug in IE. Then I tried on all browsers and I saw same behaviour. So definitely
not a bug. Then I looked at image and I noticed that color is not sharp red that I had set in first step, it was
little lighter shade of red. Next thought came to mind that may be it has something to do with opacity. After
looking at HTML5 specification, I noticed that default value of opacity is 1. So that is not the
case. If it was case of opacity then whole line will be visible with a lighter shade.
Next thought was to try some different value of line thinckness so I could see the behaviour closely in bigger
width. I noticed that when I had line width as an ODD number, I was left with two parallel lines. And when the
line width was an EVEN number, the result was as expected that is no line visible to user. This now
started to make sense that it has to do with how rendering of lines is done in graphics engine. It was back to
Computer Graphics 101. And then I dug up some documentation on HTML5 canvas rendering and found the answer to this
puzzle.
Let me first show you the code that I was using for my experiment.
function drawLines(canvasId) {
var canvasElem = $('#' + canvasId);
if (null != canvasElem) {
var width = canvasElem.width();
var height = canvasElem.height();
if (canvasElem[0].getContext) {
var drawCtx = canvasElem[0].getContext('2d');
if (null != drawCtx) {
drawCtx.lineWidth = 15;
drawCtx.beginPath();
drawCtx.strokeStyle = "#f00";
drawCtx.moveTo(0, 50);
drawCtx.lineTo(200, 50);
drawCtx.stroke();
drawCtx.closePath();
drawCtx.beginPath();
drawCtx.strokeStyle = "#fff";
drawCtx.moveTo(0, 50);
drawCtx.lineTo(200, 50);
drawCtx.stroke();
drawCtx.closePath();
}
}
}
}
Effect of line width in Canvas drawing
You can set width of line in canvas using lineWidth property on drawing context as shown
in bold in code above. By setting a value of line width (e.g. 15), you are telling the rendering engine as follows:
Draw a line from point (x1,y1) with a pencil of width 15. The center of the pencil should be places at
(x1,y1) when drawing the line.
What this means is that your line width will be divided by 2 and each half will be placed on top and above and center
line. This means if I have line width of 15, the line will have thickness of 7.5 at top and below the center (x1,y1).
Well now we have a problem that pixels can't be split into half or fractions. To overcome this, canvas
rendering engine compensates by padding extra 0.5 thickness with a lighter color. So at the end you end up with
a line which is 16 units wide and not 15. When I put white line on top of red line, there is no color lighter
than white so canvas rendering engine decided not to compensate with extra 0.5 at top and bottom. So I ended up
with two parallel lines at a distance of width of original line width that I intnded to use. Following image shows
the effect of compensation with a lighter shade of red.
Compensate for odd width
If you have to draw line with odd number width, then you will have to offset the center of your line by 0.5 up or
down. That way rendering will happen at boundary of pixel and not in middle. And you will always have a sharp
line with no residue at end edges.
de648581-4c80-4845-a738-2835a74e6861|2|5.0
Views: 2143
Tags:
HTML
by Naveen
12. June 2011 05:54
In this post I will be putting together some introductory notes on one of cool features of HTML5, CANVAS.
Canvas opens up whole new dimension in some interesting presentations in web application without use
of third party add on like Flash, Silverlight or some server side controls to generate images (e.g. charts).
This post will some basic use of 2D api to draw some basic shapes in Canvas element on your web page.
Canvas Element
You have to start by adding a canvas element on the page where you want to render graphics. Following
snippet shows element on my demo page.
<canvas id="drawingCanvas" width="400px" height="300px"></canvas>
Check Browser Support For 2D API
Since HTML5 specification is not supported by all browsers, you want to make sure that your browser has support for
it. To support drawing api (e.g. 2D), canvas has to implement getContext fuction. So
we will check for it.
var canvasElem = $('#' + elemId);
if (null != canvasElem) {
// There is support for canvas api
}
Check For 2D Drawing API Support
Next step is to check what kind of drawing you can perform on your canvas element. In HTML5 specification terms, you
have to check what kind of context is supported. You have to call getContext method with a string
parameter for type of rendering you want to perform. For example to draw 2D graphics, you will set that parameter
value as '2d'. You should check return value from that function to make sure that context
is actually supported. HTML5 specification states that if a given context is not supported then getContext
function will return null.
var canvasElem = $('#' + elemId);
if (null != canvasElem) {
if (canvasElem[0].getContext) {
var drawCtx = canvasElem[0].getContext('2d');
if (null != drawCtx) {
// We can use 2d api
}
}
}
Draw Some Basic Shapes
Here are some example on drawing some basic shapes.
How to draw filled rectangle
You will use fillRect function to draw a filled rectangle. This function takes 4 parameters as shown
in function signature below.
fillRect(x, y, width, height)
Next question you have in mind is how do you specify color to use for filling. This is done by using fillStyle
function. Basic use of this function is to set color value to this property. Following code snippet shows how to draw
four filled rectangles with 2 colors as shown in the screenshot.
// Draw 4 rectanlges
drawCtx.fillStyle = "#4e3";
drawCtx.fillRect(0, 0, 100, 75);
drawCtx.fillRect(100, 75, 100, 75);
drawCtx.fillStyle = "#e13";
drawCtx.fillRect(100, 0, 100, 75);
drawCtx.fillRect(0, 75, 100, 75);
How to draw lines
Use will use lineTo function to draw a line. As function name suggests that parameters for this
function specify end point for the line. Now you are wondering how to specify start point for the line. Rendering
API has concept of path. You use moveTo function to move start point of path to that
specified point. And then lineTo function will draw line from moveTo point to lineTo point. Untill
you use beingPath function, subsequent calls to lineTo function calls will use last
point as start point. Following code snippet shows drawing two lines across diagonals.
// Draw lines across diagonals
drawCtx.beginPath();
drawCtx.moveTo(0, 0);
drawCtx.lineTo(200, 150);
drawCtx.stroke();
// now set stroke color to blue.
drawCtx.beginPath();
drawCtx.strokeStyle = "#00f";
drawCtx.moveTo(0, 150);
drawCtx.lineTo(200, 0);
drawCtx.stroke();
How to draw circle
Similar to drawing a line, you will use arcTo function to draw an arc. A circle
is special case of an arc where start angle is 0 and end angle is 360 degree. Following code
snippet shows drawing of a circle in middle of rectangle as shown in screenshot.
// Draw a circle.
drawCtx.beginPath();
drawCtx.lineWidth = 3;
drawCtx.strokeStyle = "#ff0";
drawCtx.arc(100, 75, 50, 0, Math.PI * 2, true);
drawCtx.stroke();
These are just some basic examples of 2D api. In subsequent posts I will show some interesting
usage of various 2D api functions to perform some cool rendering on pages.
by Naveen
9. June 2011 12:07
Some time back I did a project involving Twitter location and posted some notes about use of geo locaton
API at this post,
Convert IP Address To Location and Address. Now that HTML5 is picking up steam and all the latest browsers
are supporting most of HTML5 specification, use of native Geolocation API in HTML5 will be
the way to go as long as your users are using a brwosers that support HTML5. There are some caveats that you
need to be aware of before you use GeoLocation API in HTML5.
Privacy: HTML5 specification for GeoLocation API clearly states that the
A conforming implementation of this specification must provide a mechanism that protects the user's privacy
and this mechanism should ensure that no location information is made available through this API without
the user's express permission. What this means is that when you try to use this API, your browser will
present user interface to user to get permission. Following images show what this UI looks like on different browsers.
IE9
Chrome
FireFox
GeoLcation API Usage
This API is exposed through geolocation property of navigator object. There are
three methods supported by geolocation object.
- getCurrentPosition: As the name suggests, this function is called to current position of
your browser or mobile device.
- watchPosition: As name suggests, this function is used to monitor or watch position change of
your device or browser. This method is very helpful for your mobile device application where your position is going to
change as you are travelling. In case of browsers, the position is based on IP address assigned to your network.
This position may change if you are using broadband card and your provider switches IP address on you. But overall
it is very useful method to monitor the position change and then change the display of UI based on new
location.
- clearWatch: This method works together with watchPosition. It is equivalent to
clearing of timer in JS. watchPosition spawns a thread and hands you an ID related to that watch
thread. By calling clearWatch method, you can clear that thread.
Asynchrnous Calls
Both functions getCurrentPosition and watchPosition are asynchnronous. This means
that you have to provide call back functions to these APIs. These APIs take upto 3 arguments but two are
optional. For the API to work, you have to provide atlease call back for success. If you do not provide
a call back function for success event then the API will throw an error.
Specifying Timeout
When you are dealing with asynchronous calls, it is very important that you have some time out for
request. You do not want to end up in a situation where your request is waiting forever. Depending
on settings of your device or browser, there is always a default timeout for a HTTP request, but
that time out is longer than you really want to wait for. Third parameter for these function is
options. You can set three option parameters for each request and one of them is
timeout. Following are three options exposed by this object.
- enableHighAccuracy
- timeout
- maximumAge
Example Code
Following javascript code snippet shows how I used geolocation API to get current position
of my browser.
function getMyPosition() {
if (navigator.geolocation) {
var geoApiOptions = { timeout: 5000, enableHighAccuracy: true };
var pos = navigator.geolocation.getCurrentPosition
(getGeoLocationSuccess, getGeoLocationFail, geoApiOptions);
}
}
function getGeoLocationSuccess(position) {
$('#latitudeLabel').text(position.coords.latitude);
$('#longitudeLabel').text(position.coords.longitude);
$('#altitudeLabel').text(position.coords.altitude);
$('#accuracyLabel').text(position.coords.accuracy);
$('#altitudeAccuracyLabel').text(position.coords.altitudeAccuracy);
$('#headingLabel').text(position.coords.heading);
$('#speedLabel').text(position.coords.speed);
}
function getGeoLocationFail(positionError) {
alert(positionError);
}
$(document).ready(function () {
getMyPosition();
});
Coordinates In Result
As you can see in example, getGeoLocationSuccess function is callback for request
success. This function is called with one parameter, position. This objects has following
two properties.
coords object contains the properties that identifes the coordinates and other
related attributes for position of the device or browser. This objects has following properties.
- latitude
- longitude
- altitude
- accuracy
- altitudeAccuracy
- heading
- speed
Of these values, latitude, longitude and accuracy will always be returned when call succeeds. Other
properties are optional depending on device or browser's implementation.
Once you have position values, you can use those to do some more interesting things in your applications. I
will discuss some of these usages in subsequent posts!
by Naveen
25. April 2011 05:35
In my previous post,
How to draw circle with CSS, we saw drawing of circle using CSS box-radius style. In this post
I will show another aspect of syntax of box-radius style to draw an ellipse. An oval shape is
ellipse which has major-axis length idfferent from minor-axis. In previous post I only used one value
for box-radius.
box-radius Syntax
box-radius: horizontalRadius / verticalRadius
For simplicity sake I have only used one value. As you can see there are two components of
border-radius to control radius along horizontal and vertical direction. If you do not specify
vertical radius value, browser will use horizontal radius value for vertical radius as well.
Draw Ellipse
Based on the above information about syntax, to draw ellipse we need to specify different values for
horizontal and vertical radius. Here is what you will need to draw ellipse.
- DIV that has height different than width. Depending on shape of ellipse you want, height may be
more or less than width.
- horizontalRadius value of border-radius will be half of width of DIV
- verticalRadius value of border-radius will be half of height of DIV
Here is an example of style example I used to draw an ellipse using CSS.
 |
.ellipseDiv
{
height:50px;
width:100px;
border: 2px solid #005;
border-radius:50px / 25px;
background-color:#EE5D20;
}
|
ff5b32e1-44e4-4258-8e05-424b309fac95|0|.0
Views: 2756
Tags: CSS, HTML5
CSS | HTML
by Naveen
25. April 2011 05:14
In this post I will describe how to use border-radius CSS style to draw a circle
in your web page. Most important part of the technique is understanding this new border-radius
style and what it does.
border-radius syntax
border-radius: top-left top-right bottom-right bottom-left
These values represent radius of the oval or ellipse that will be be used to draw rounded corner at specified location
of the box. I will discuss this syntax of border-radius in more details in subsequent post(s). For now
it is sufficient to know that these values are radius of the corner.
Draw circle
A circle is a special case of an oval or ellipse where size of major-axis is equal to minor axis. This means
if I take a square and set the radius of corners to half the length of a side of square, it becomes a circle.
This is exactly how you will draw the circle. The following style is used to draw a circle.
 |
.circleDiv
{
height:100px;
width:100px;
border: 2px solid #005;
border-radius:50px;
background-color:#EE5D20;
}
|
Key points of this technique are:
- DIV height and width are to be same
- box-radius value should be half the size of div
633339b5-9111-4d8a-b5a6-f1dabd1070d8|0|.0
Views: 2073
Tags:
CSS | HTML
by Viper
4. March 2009 06:01
I see this question and related questions posted in a lot of web programming forums. And I always end up answering it the same way. And I still don't know why people try to fight the battle that can't be won. I remember some time back I was asked to look at a site that will not allow user to right click on image save it locally. The user asked me that she want to save it locally to manipulate it. You really did not need any tools to accomplish that. Answer was very simple, goto Temporary Internet Files folder and there you will find these images.
Now you see why it is just not possible to prevent save or copying of any content that is published on internet. If you are still not convinced, then I will tell you what I will do to copy content from your site. May be that will give some food for your thoughts.
- I will look in the temporary internet files folder first and grab the content from there.
- If I can't find content in temporary folders, I will write two lines of code to send a HTTP GET request to your page using HttpWebRequest (in .Net) or other means in other languages to get response stream from the page, convert it to text and save it. You are sending HTML response back from your page so how hard it is to save it as HTML file and then view it.
- And if want to parse data out of your pages, then I will use tool like HTMLParser.Net to get all the content from your page and do whatever i want to do with it.
There are some steps you can take to make it difficult for regular user to copy the content
- Disable right clicking on the page by trapping right mouse click event using javascript.
- From landing page of your application, open the main page of the application in a new browser window and remove all menu bars, tool bars etc. Well, it is going to be very annoying for the user.
- From server side, set caching headers appropriately to let browser know that content is not be cached. That will make the browser to get fresh content from the site all the time. That means slow user experience.
- User document.write to write the whole HTML in memory. This will make it difficult for the BOTs to parse the pages. But then you will also loose visibility in search engines as well.
But as I said you can't hide content of your pages from the user. I have given you all the options and down side of doing it as well. So pick your battle wisely.
aa1cad4d-b31f-4cb6-94cb-af01e38b4200|0|.0
Views: 5851
Tags: web, html
HTML | Web
|
|