Tuesday, August 19, 2014

Drawing Line Using Javascript


Updated on 27th of August: Please use the 2nd version of my drawLine() function (scroll to the bottom of this page) if possible. The first version has a lots of flaws which may not draw the line correctly in certain situation.



With HTML5 coming hot and jQuery to be well received by web developers, Javascript is now a frozen cake from the fridge. Especially when it comes to drawing shapes on browsers, Javascript will be receiving less and less focus especially when HTML5 flocks into web applications someday.

Although Javascript is becoming less and less important, I still post my way of drawing lines on browsers using Javascript due to the fact that Javascript is still a good educational language for beginners to start with. The readability of jQuery is too low and may turn some newcomers away. That is why I still insist on posting Javascript goodies here. Hope this last piece of cake does not end up in the dumpster.

Note: The anti-alias version can be found here.

Here we go (the codes):


<html>

<script>

var spanTag,red,green,blue; // declare these as global
var colorChannel; // to save resources

function mkDot(x,y,color) {

  colorChannel = color.match(/\#(\w\w)(\w\w)(\w\w)/); // match out RGB
  red = parseInt(colorChannel[1],16);
  green = parseInt(colorChannel[2],16);
  blue = parseInt(colorChannel[3],16);

  spanTag = document.createElement("span");
  spanTag.innerHTML = '<img src="dummy1x1.png" height=1 width=1>';// You need a 1x1 dummy transparent PNG image as foreground
  spanTag.style.position = "absolute";
  spanTag.style.zIndex = 1; // In case you have other elements on the same page
  spanTag.style.left = x + "px";
  spanTag.style.top = y + "px";

  red = red>=16?red.toString(16):"0"+red.toString(16); // convert to HEX
  green = green>=16?green.toString(16):"0"+green.toString(16);
  blue = blue>=16?blue.toString(16):"0"+blue.toString(16);
  spanTag.style.backgroundColor = "#"+red+green+blue; // set background color

  document.body.appendChild(spanTag);
}

function drawLine(x1,y1,x2,y2,color) {
  var i,j,x,y,m,d,done=0;
  x=Math.abs(x1);
  y=Math.abs(y1);
  m=(y2-y1)/(x2-x1);
  d=x1>x2?"-":"+";
  c=y1-(m*x); // trigonometry

  while (!done) {
   mkDot(x,y,color);
   if (x==x2) { done = 1; }
   if (d=="-") { x--; }
   else { x++; }
   y = parseInt(m*x) + c; // trigonometry
  }
}

window.onload = function() { // only can call after the body loaded
  drawLine(10,40,1000,320,"#3388cc");
};

</script>

<body>
...
</body>

</html>


In case you need the dummy1x1.png, here it is https://drive.google.com/file/d/0B2RFpjH4zL5bTm9TdVo3UFUzRTg/edit?usp=sharing.





My second version (without discontinued steep line problem):



<script>

function drawLine3(x1,y1,x2,y2,color) {

 var x,y,i,m,steep,d,done=0;
 x1=Math.abs(x1);x2=Math.abs(x2);y1=Math.abs(y1);y2=Math.abs(y2);
// make sure no negative points

 if (x1>x2) { // swap xy if 1st point is on the right
  i=x1;x1=x2;x2=i;
  i=y1;y1=y2;y2=i;
 }
 d = y1>y2?1:0; // d = downward
 x=x1;
 y=y1;
 m=(y2-y1)/(x2-x1);
 c=y1-(m*x);
 steep=Math.abs(m)>1?1:0; // if steep, draw more y pixels, else more x pixels

 while (!done) {
  mkDot(x,y,color);
  if (steep) {
   if (y==y2||x==x2) { done = 1; }
   d?y--:y++;
   x = parseInt((y - c)/m);
  }
  else {
   if (x==x2) { done = 1; }
   x++;
   y = parseInt(m*x) + c;
  }
 }
}

</script>



I've just used this improved version to draw this! (Of course with a lots of other codes such as JSON parsers/generator... sent from mySQL chart data) Isn't it cool?



Read More »

Friday, August 15, 2014

Javascript to Prevent Selecting Texts on Tabled Buttons


It is now a common phenomenon that HTML tables are made buttons to replace conventional image-based buttons. The benefits of tabled buttons are quick loading, good button quality when zoomed on tablets and easy to change color. There is also no need to perform pre-loading.

This new popular method of displaying buttons can sometimes perform awkwardly if the text selection is not turned off on the tabled button. The following shows my javascript of disabling the text selection on a table.


<table>
<tr>

<td width=100 bgcolor=yellow id=box1 onclick="func1()" onmouseover="over(this)" onmouseout="out(this)" align=center>Box 1</td>
<td width=100 bgcolor=yellow id=box2 onclick="func2()" onmouseover="over(this)" onmouseout="out(this)" align=center>Box 2</td>

</tr>
</table>

<script>

document.getElementById('box1').onselectstart = function() {return false;};

function func1() {
 alert('Box 1');
}

function func2() {
 alert('Box 2');
}

function over(elem) {
 elem.style.backgroundColor = "#ccddff";
 elem.style.cursor = "pointer";
}

function out(elem) {
 elem.style.backgroundColor = "yellow";
 elem.style.cursor = "default";
}


</script>


The screen capture of this HTML being run on browser:



Note that if your mouse is trying to select on "Box 1", it won't work. But it works for "Box 2", as the selection feature is not disabled by the Javascript.
Read More »

Thursday, August 14, 2014

How to Quickly Identify Missing/Extra HTML Tag

When your HTML gets more and more complicated and packed, a slight mistake in the tagging will render you helpless. It could take a long time to find just a missing or extra tag. My way of solving this problem is to use Notepad++! It's free but it is only available on Windows.


It's easy. You just need to click on the tag and look for missing PURPLE! Once you click on any of the HTML tag, the corresponding closing/opening tag will be highlighted in purple. If you click on a tag and nothing happens, that means Notepad++ is unable to find a corresponding tag for it. You've found the problematic tag! There are still chances that the highlighted tag in purple is wrong. That means you need to also double check the highlighted tag to see whether they are coded the way you really intended.

The screen capture shows the tag highlighted in purple after you click on it. There you have it and happy debugging!

Read More »

Thursday, August 7, 2014

Javascript to Measure Vertical Scrollbar Width


I used the following codes to measure the vertical scrollbar (overflowY) width so that I can place a dummy blank DIV onto the real scrollbar to prevent someone from scrolling by dragging the scroller on the right scrollbar.


<script>

var dummyDiv = document.createElement("div"); // Create a dummy DIV
dummyDiv.style.overflow = "scroll"; // force it to have a scrollbar
dummyDiv.style.width = "50px"; // required for IE, can be other values
document.body.appendChild(dummyDiv); // add to DOM
var scrollbarWidth = dummyDiv.offsetWidth - dummyDiv.clientWidth; document.body.removeChild(dummyDiv); // remove dummy from DOM

alert("The scrollbar width is "+scrollbarWidth);

// If I'm not mistaken, for non IE browsers,
// except the Mac Safari (scrollbars are of 0 width) and touch devices
// such as iPad and tablets, the width is required to increase by 1



</script>


There is a very rare chance that you might need this as most developers nowadays are using JQUERY to take care of the scrolling actions. In case you are a Javascript guy, this is good to know.

Read More »

Monday, July 28, 2014

My Javascript Way to Check the Validity of an Email Address Input



Before sending an email address input from a submitted form to the server to verify, it is better to perform a simple check on the email address format for any possible typo. This will save some server bandwidth as Javascript is capable of catching some obvious email format errors.

The following Javascript codes/function are used:


<script>

function emailError() {

 if (document.userForm.em.value.match(/(\w+\@\w+\.\w+)/) == null) {
  return true;
 }

 return false;
}

if (emailError()) { alert('Invalid Email Format!'); }

</script>


Assume the name of your HTML form is 'userForm' and em is the name of the email input. The emailError() function is making use of the Javascript .match() function to match the pattern of \w+\@\w+\.\w+. If there is a mismatch, an error (true) will be returned to signify an email format error. Please also note that this function will also treat ab.cd@efghijk.xyz as valid although the code can only match the cd@efghijk.xyz. Since the match content is not important, the ab. before the cd will be ignored without affecting the result of the emailError() function.

Read More »

Sunday, July 27, 2014

Javascript to Disable Mouse Scroll for All Browsers including IE


I use these codes to temporarily disable the mouse scroll when I display a pop-up DIV. Although this is not quite necessary but it looks more professional to have mouse scroll locked when the pop-up appears. However the side scroll bar is still working with these following codes. You can still use the mouse to drag the page upward or downward.

The following javascript codes/functions are used: (to lock mouse scroll only that uses the center wheel of a mouse)


<script>

var ff = (navigator.userAgent.indexOf("Firefox") != -1);

if (ff) {
  mousewheelevent = "DOMMouseScroll";
}
else {
  mousewheelevent = "mousewheel";
}

function lockScroll() {
 if (document.attachEvent) {
   document.attachEvent("on"+mousewheelevent, catchWheel);
 }
 else if (document.addEventListener) {
   document.addEventListener(mousewheelevent, catchWheel, false);
 }
// you can also hide the scrollbar by using the following simple javascript command:
// document.body.style.overflowY="hidden";

}

function unlockScroll() {
 if (document.detachEvent) {
   document.detachEvent("on"+mousewheelevent, catchWheel);
 }
 else if (document.removeEventListener) {
   document.removeEventListener(mousewheelevent, catchWheel, false);
 }
// you can also recover the scrollbar by using the following simple javascript command:
// document.body.style.overflowY="scroll";

}


function catchWheel(e){

 if (e.preventDefault) {
  e.preventDefault();
 }
 else {
  e.returnValue = false;
 }
}


lockScroll(); // to lock scroll
unlockScroll(); // to unlock scroll


</script>


Read More »

Saturday, July 26, 2014

Javascript Way to Check Loaded Image


I use this to display images only after they are loaded into the browser's memory. I need Javascript codes to tell me if the image is ready to be displayed or processed. For example, there is a huge image that I need to display but the size is too big. I display a loading icon before I reveal the image so that it looks more like a contemporary (jQuery equipped) web page. I use the following Javascript codes.


<script>

var loaded_img = new Array();
var image_list = new Array("1.jpg","2.jpg","3.jpg","4.jpg","5.jpg"); // the list of potential images that you want to check later
var img1loaded = false;

function installOnloadAlarm() {

 var i;
 for (i=0; i<image_list.length; i++) { // iterate all images

  var img = new Image(); // create an image object

  img.onload = function() { // set up onload actions
   var match_result = this.src.match(/\/(\w+\.\w+)$/); // match filename after the last '/'
   loaded_img.push(match_result[1]); // push match result into loaded_img array
  };

  img.src = "image/"+image_list[i]+".jpg"; // by setting the source, the browser will start loading (assume images are in 'image' directory)
 }
}

function checkLoadedImg(imgFilename) {
 var i;
 for (i=0; i<loaded_img.length; i++) {
  if (imgFilename == loaded_img[i]) {
   return true;
  }
 }
 return false;
}

function afterLoaded() {
 if (img1loaded) {
  clearInterval(timer1);
  clearInterval(timer2);
  .
  .
  .
  do your post loading job
  .
  .
  .
 }
}

installOnloadAlarm();
var timer1 = setInterval(function(){img1loaded = checkLoadedImg('1.jpg');},200); // need to set timer to check as the result won't be available instantly (this example checks only '1.jpg')
var timer2 = setInterval(function(){afterLoaded();},200);


</script>


The timers are necessary as the results won't be available after installing the onload conditions. This is just a brief example of a complete image file checking system whether the image is loaded into browser.

Read More »

Wednesday, July 23, 2014

IE4-7 Jagged Text Problem After Applying Filter and the Solution


IE4 until IE7 is notorious to have this anti-alias being turned off after applying a filter to a text (with the position property is set to absolute) such as the opacity filter used for fade in and fade out. For example, the following HTML codes will show the jagged text (without anti-alias) after even applying an empty filter in IE7:

<span id="test" style="position:absolute;top:10px;left:10px;">Remove Filter</span>

<script>
document.getElementById('test').filter = "";
</script>


In order to tell IE4-7 to turn the anti-alias back on, the filter has to go by removing it from the DOM.

<span id="test" style="position:absolute;top:10px;left:10px;">Remove Filter</span>

<script>
document.getElementById('test').filter = "";
document.getElementById('test').style.removeAttribute("filter");
</script>


There you go. The removeAttribute() has to be used to clear the element of any filter. Setting the filter to none still make IE4-7 think that the filter feature will still be needed and you just disable it temporarily.

Read More »