I’ve looked around the net for some JavaScript slider widgets, and I’ve noticed that many of them were part of a framework (YUI, script.aculo.us), not well written or not even free. So I’ve decided to write my own (not saying that using the sliders from a framework are evil, but including a whole framework just for one or two sliders isn’t that great). I finished a rather good one, but then I had an idea, which I spent quite some time on figuring out. I’ve ended up with a slider which actually (mis)uses a scrollbar. It’s a very lightweight widget, the compressed code is less than 1kb! Click on the picture to see some examples of it.

new ScrollSlider('id');
ScrollSlider
ScrollSlider works in all popular browsers

ScrollSlider only supports Integers, but it could be extended to use Floats or even using certain steps on the slider. I just didn’t want to do it :P

It works the following way: The div-container, which represents the slider, has a child (another div), which overflows over it’s parent. Basically, the child can not be seen (by setting the style-attribute to certain values - this took me a bit to make sure that IE, Firefox, Opera and Safari are happy…), but the scrollbar appears. The child’s width decides, how “thin the handle is” / how many values can be accessed. The current value is calculated with the parent-div’s scrollLeft variable (and vice versa, the setValue method also uses this variable).

The syntax is as follows:

new ScrollSlider (slider, args, noInitScroll)

  • slider is either the ID of a div-element or a reference to one
  • args is an Object, which can contain the following elements:
    • min: the smallest value (default: 0)
    • max: the largest value (default: 100)
    • value: the current value (default: 0)
    • size: the size (width) of the scrollbar (default: 150)
    • scroll: the function fired when scrolled (default: function(){} [empty function])
      Note that the argument passed to this function is the current value. However, all properties can be accessed via this, e.g. this.max or this.value
  • noInitScroll is an optional Boolean; if set to true, the scroll-function will not be triggered on initialising

Example:
new ScrollSlider('slider', {
  min:    -42,
  max:    250,
  value:  100,
  scroll: function (val) {
    document.getElementById(’check’).innerHTML = val;
  }
});

This would update $('check') everytime the ScrollSlider was changed. Since no value for size is handed over, the default is used.

Arguments can also be changed lateron, just by passing them (as a object) to the sliders’s change method. It also has the method getValue and setValue (pass an Integer).

ScrollSlider is released under GPL v3. View examples or download.

Opera added the setPixel and getPixel methods to their ‘opera-2dgame’ Canvas Context, but CanvasRenderingContext2D lacks them. My workaround seems to be the optimal solution:

getContext('2d').setPixel = function (/*Integers*/x, y, /*String*/color) {
  if (color) {
    var oldStyle = this.fillStyle;
    this.fillStyle = color;
    this.fillRect(x, y, 1, 1);
    this.fillStyle = oldStyle;
  } else {
    this.fillRect(x, y, 1, 1); 
  }
}

getContext('2d').getPixel = function (/*Integers*/ x, y) {
  function zero (num) {
    return (num.length === 1) ? ‘0′ + num : num;
  }
  var d = this.getImageData(x, y, 1, 1).data;
  if (d[3] === 255) {
    return ‘#’ + zero(d[0].toString(16)) + zero(d[1].toString(16)) + zero(d[2].toString(16));
  } else {
    return ‘rgba(’ + d[0] + ‘,’ + d[1] + ‘,’ + d[2] + ‘,’ + d[3] + ‘)’;
  }
}

 

A practical implementation could look like this:

window.kwExtendCanvas = function (/*CanvasRenderingContext2D*/ ctx) {

  if (!ctx.setPixel) {
    ctx.setPixel = function (/*Integers*/ x, y, /*String*/ color) {
      if (color) {
        var oldStyle = this.fillStyle;
        this.fillStyle = color;
        this.fillRect(x, y, 1, 1);
        this.fillStyle = oldStyle;
      } else {
        this.fillRect(x, y, 1, 1); 
      }
    }
  }

  if (!ctx.getPixel) {
    if (ctx.getImageData) {

      ctx.getPixel = function (/*Integers*/ x, y) {
        function zero (num) {
          return (num.length === 1) ? ‘0′ + num : num;
        };
        var d = this.getImageData(x, y, 1, 1).data;
        if (d[3] === 255) {
          return ‘#’ + zero(d[0].toString(16)) + zero(d[1].toString(16)) + zero(d[2].toString(16));
        } else {
          return ‘rgba(’ + d[0] +’,’+ d[1] +’,’+ d[2] +’,’+ d[3] + ‘)’;
        }
      };

    } else {
      ctx.getPixel = function () { };
    }
  }

};

var canvasElements = document.getElementsByTagName('canvas');
for (var elCount = elCanvas.length - 1; elCount >= 0; elCount–) {
  kwExtendCanvas(canvasElements[elCount].getContext(’2d’));
}

 

If a canvas element is created after the above for loop, then can still be extended just by passing its ‘2d’ context to kwExtendCanvas.

getPixel just draws a filled rectangle and should work on all browsers supporting fillRect. getPixel on the other hand uses getImageData, which is not widely supported (yet). Safari (Windows beta) and IE7 using ExplorerCanvas don’t seem to support my getPixel method - didn’t check any other browsers.

kwJsAgent is a software agent simulator written in JavaScript. Every agent moves in a two-dimensional “box” and is programmed by calling the Agent Constructor for every single agent. In the current version (kwJsAgent 0.1)

  • red agents follow black agents
  • green agents follow either black or red agents
  • blue agents follow green agents

kwJsAgent

Of course, everything can be expanded and extended. Theoretically, the agents can behave in any possible way, it just has to be coded!

While we’re at it ;)

Math._round = Math.round;

Math.round = function (/*Float*/ number, /*Integer*/ digits) {
  if (digits) {
    digits = this.pow(10, digits);
    return this._round(number * digits) / digits;
  }
  return this._round(number);
};

Examples:

Math.round(Math.PI);
// returns 3
Math.round(Math.PI, 5);
// returns 3.14159
Math.round(Math.PI, 3);
// returns 3.142
Math.round(Math.PI * 100000, 3);
// returns 314159.265
Math.round(Math.PI * 100000, -2);
// returns 314200

This is kind of a combination of my last post and another post of mine:

Math._random = Math.random;

Math.random = function (/*Integers*/ max, min) {
  if (max) {
    min = (!min) ? 0 : min;
    return this.floor(this._random() * (max - min + 1) + min);
  }
  return this._random();
}

If find this very unobtrusive, becuase Math::random still works perfectly well if no arguments are passed. Examples:

Math.random();
// returns random float between 0 (inclusive) and 1 (exclusive)
Math.random(42);
// returns random integer between 0 and 42 (both inclusive)
Math.random(37, 13);
// returns random integer between 13 and 37 (both inclusive)

I’ve just had the following idea for JavaScripts that repeatadly call functions using setTimeout. This can cause a high system load, which is why I wrote the following piece of code:

kwSetTimeout = {
  factor: 1,
  lastTime: new Date().getTime(),
  adjust: function () {
    var newTime = new Date().getTime();
    var diff = newTime - kwSetTimeout.lastTime - 10;
    kwSetTimeout.factor = (diff > 0) ? (1 + diff / 100) : 1;
    kwSetTimeout.lastTime = newTime;
    _setTimeout(kwSetTimeout.adjust, 10);
  }
};

_setTimeout = setTimeout;
window.setTimeout = function (/*Function*/ fn, /*Integer*/ timeout) {
  return _setTimeout(fn, timeout * kwSetTimeout.factor);
};

_setTimeout(kwSetTimeout.adjust, 10);

 

The replaced setTimeout method should increase with the system load. The only way I could think of to check this is by checking the elapsed time of a setTimeout call. kwSetTimeout::adjust keeps calling itself every 10ms and every time more than 10ms passed, it increases will increase the timeouts of setTimeout calls. The original function can be accessed via _setTimeout.

Now I’m not sure whether this actually works. The few tests I’ve done were rather disappointing, but oh well, it was just an idea.

Just for fun, I reduced the code size to 256 bytes:

kwST={f:1,l:new Date().getTime(),a:function(){var n=new Date().getTime(),d=n-kwST.l-10;kwST.f=(d>0)?(1+d/100):1;kwST.l=n;_setTimeout(kwST.a,10)}};_setTimeout=setTimeout;window.setTimeout=function(f,t){return _setTimeout(f,t*kwST.f)};_setTimeout(kwST.a,10);

Perhaps this is something that everybody knows already, but I just figured this out ;)

var myObject = {
  myArray: [],
  myFunction: function (/*Array*/ args) {
    args.each(function (s) {
      this.myArray.push(s.strip());
    }.bind(this));
  }
};

Thanks to Prototype’s bind, the “this” keyword now correctly points to myObject.
Just for the sake of completeness:

myObject.myFunction(['   foo ', ' bar ', 'baz  ']);
alert(myObject.myArray.join));
// alerts “foo,bar,baz”

By accident, I landed on this site, telling me how to write a “correct” random number generator. Well, it’s goes like this:

function intRand(max) {
  return Math.ceil(Math.random() * 1000) % max + 1;
}

Now this might be easy to understand - but it’s only useful if max is <= 1000. If it’s greater, then you will only get numbers between 1 (!) and 1000. It’s also a statistical mess… Good thing this is in the archives, because it’s horrible!

I also found this interesting solution (which I also changed just a little for better reading):

function intRand(max) {
  return Math.floor(new Date().getSeconds() / 59 * max);
}

Obviously, the problem is, that when max is >= 60, it doesn’t output the complete range between 0 and max. Needless to say that the number you get only changes once a second. Nevertheless, it doesn’t use random, which is why I optimized it a little just for fun:

function intRand(max) {
  return Math.floor(new Date().getMilliseconds() / 1000 * max);
}

Again, this is bad, why not use Math.random correctly? This is my killer function ;)

function intRand(max, min) {
  max = (!max) ? 1 : max;
  min = (!min) ? 0 : min;
  return Math.floor(Math.random() * (max - min + 1) + min);
}

or the one-liner:

function intRand(max, min) {
  return Math.floor(Math.random() * (((!max) ? 1 : max) - ((!min) ? 0 : min) + 1) + ((!min) ? 0 : min));
}

min and max are optional. I decided to use max as the first argument because (at least for me) it’s very likely to pass a min of 0.

So, there you go ;)

kwFretboard is a very simple program I wrote in Delphi. It should help you learn the notes on a (bass) guitar fretboard.

kwFretboard

Download (Mirror)
- Source also available

Hello, world! Every blog has to start with its first post, no matter how bad or how good it is. Now the reasons I set up this blog are the following:

  • to share my thoughts and ideas about Web (2.0) etc.
  • to improve my English and writing skills
  • because it’s fun :)

I will probably not be able to post that often, but I will do my best!

Cheers, Kevinin