Archive for the ‘Web development’ Category

IE Hack: CSS drop shadow

Thursday, May 6th, 2010

Easy-to-apply, dynamic, auto-expanding drop shadows have always been a bit of a pain to apply across all the major browsers. We fairly recently got the box-shadow attribute, which can be applied with -moz-box-shadow and -webkit-box-shadow on gecko and webkit browsers. But it leaves the IE family out in the cold.

The easiest solution to the is the IE-proprietary filter attribute. It does not producte quite as nice shadows as the box-shadow attribute, but for simple just-a-few-pixels drop shadows it does the trick. One noticeable drawback is that IE for some reason disables anti-aliasing on elements that has this attribute. But I can live with that in most cases.

This box has a shadow
.shadow {
	zoom:1; /* This enables hasLayout, which is required for older IE browsers */
	filter: progid:DXImageTransform.Microsoft.Shadow(color='#b0b0b0', Direction=135, Strength=3);
	-moz-box-shadow:2px 2px 2px #b0b0b0;
	-webkit-box-shadow:2px 2px 2px #b0b0b0;
	box-shadow:2px 2px 2px #b0b0b0;
}

This should look fairly similar in all major browsers, including IE 6+

IE Hack: inline-block

Tuesday, May 4th, 2010

I just decided that it would be a good idea to collect solutions to common IE css issues here on my blog. Sure, these are all over the web now a days, but hey, another place can’t hurt right? :)
I’m going to start posting them under the IE hacks category whenever I come across one.

This time it’s about the inline-block display property (introduced in CSS 2.1), which can be very useful in certain scenarios. The problem is that it is not supported IE <= 7 for elements that are block level by default.

Without further ado, here's the most simple solution I could find. Just append these two lines at the end of the CSS block where the inline-block style is set:

zoom: 1;
*display: inline;

Basically it triggers hasLayout for the target element, which is "kinda like magical fairy dust you can sprinkle on rendering issues and make them disappear".

Source: http://blog.mozilla.com/webdev/2009/02/20/cross-browser-inline-block/

SamHaXe + Snow Leopard

Sunday, November 29th, 2009

Ex spies and big cats don’t always get along well. The main problem you will face when trying to compile SamHaXe on OS X 10.6 is that the Neko version you got from installing HaXe (Which I will assume you have installed) is a 32 bit one. SamHaXe will not be able to link against libneko.dylib when you compile, because your target architecture is 64-bit in Snow Leopard.

After some fiddling around and some kick-ass help from the SamHaXe mailing list I finally managed to get SamHaXe up and running on Snow Leopard. In a nutshell, the solution is to compile a 64-bit Neko before you compile SamHaXe.

Here’s how how to do it:

  1. First install MacPorts. It will make it a lot easier to get the right dependencies.
  2. Then install PCRE and ImageMagick:
    $ sudo port install ImageMagick pcre

    This will take ages, so go get a good book or something. :)

  3. Neko will need to link against Hans Boehms garbage collector, so you will need to compile and install that before getting on with Neko. Go and get version 7.1 from the downloads section at http://www.hpl.hp.com/personal/Hans_Boehm/gc/.
    If you configure and compile it right away you will get an error due to Apples aggressive deprecation policy, so you will have to get your hands dirty with some preprocessor code here.
    Open mach_dep.c and find these lines:

    #if !defined(HAVE_PUSH_REGS) && defined(UNIX_LIKE)
    # include <ucontext.h>
    #endif

    Change them to this:

    #if !defined(HAVE_PUSH_REGS) && defined(UNIX_LIKE) && !defined(DARWIN)
    # include <ucontext.h>
    #elif defined(DARWIN)
    # include <sys/ucontext.h>
    #endif

    Now you can do the usual

    $ ./configure
    $ make
    $ make install
  4. Ok, now you’re all set for compiling a 64-bit Neko. Version 1.8.1 that is the current official version has a bug in it that prevents using modules on Snow Leopard, so you will have to get the CVS version. There’s instructions on the Neko downloads page: http://nekovm.org/download.
    Unfortunately, there’s a new OS X bug in the CVS version that you will have to work around manually for now (Hopefully this is fixed soon though). Here’s how:

    • Create a file called “clock_gettime_stub.c” in [neko-source-dir]/libs/std. Copy the contents from http://le-depotoir.googlecode.com/svn/trunk/misc/clock_gettime_stub.c into that file.
      [Edit: It appears that this file doesn't get compiled. So all you need is the change to neko.h below. This will allow Neko to compile, but I suspect it will crash at run time if something accesses the sys_thread_cpu_time() function. I will leave this be as long as it works for me though.]
    • Open [neko-source-dir]/vm/neko.h and put the following lines right above C_FUNCTION_END at the bottom of the file:
      #ifdef NEKO_MAC
       typedef enum {
           CLOCK_REALTIME,
           CLOCK_MONOTONIC,
           CLOCK_PROCESS_CPUTIME_ID,
           CLOCK_THREAD_CPUTIME_ID
       } clockid_t;
       EXTERN int clock_gettime(clockid_t clk_id, struct timespec *tp);
       #endif
      

      [Edit: This has been fixed on CVS now, so this step should no longer be needed]

    Now you can compile Neko like this:

    $ make MACOSX=1

    You will be asked three times about headers for mod_neko, mod_tora and mysql. I decided to simply skip these as I won’t need them.

  5. Now you have a 64-bit binary version of neko in the [neko-source-dir]/bin directory. To install it to your system, make a backup copy of /usr/lib/neko and then copy the contents of [neko-source-dir]/bin into it and replace what ever is in there.
  6. Now you should be able to compile SamHaXe. Follow these steps:
    • Create ant.config and put these lines in it. The paths should be correct for a default installation of MacPorts.
       haxe.path=/usr/bin
       haxe.stdpath=/usr/lib/haxe/std
       imagemagick.path=/opt/local/bin
       imagemagick.include.path=/opt/local/include/ImageMagick
       imagemagick.library.path=/opt/local/lib
       imagemagick.library.name=MagickWand
       neko.path=/usr/lib/neko/
       neko.include.path=/usr/lib/neko/include
       neko.library.path=${neko.path}
       freetype.path=/opt/local/bin
       freetype.include.path=/opt/local/include/
       freetype.library.path=/opt/local/lib
    • Open build.xml and change image-imagemagick.dylib to libimage-imagemagick.dylib on line 238 and font.dylib to libfont.dylib on line 317
    • Now type ‘ant’ in the terminal to compile.
  7. That’s it! If all went like it should you now have a fully working SamHaXe in the [samhaxe-source-dir]/bin directory.

A problem you might encounter is that haxelib won’t work with the 64-bit neko, since haxelib is 32-bit by default. To fix this, you can compile a new haxelib from /usr/lib/haxe/std/tools/haxelib/. Simply cd to that directory and do “haxe haxelib.hxml”. Then copy the new binary over the old /usr/bin/haxelib.

BitmapData and paletteMap

Tuesday, November 10th, 2009

I just happened to stumble across a feature of flash’s BitmapData class that I hadn’t noticed before: paletteMap()

With paletteMap() you can switch the color values of the pixels in a BitmapData using mapping arrays. The function will basicly take the red, green or blue value of a pixel (0-255), and then replace it with the value found at the corresponding index in the mapping array. Doing this is a lot faster than using the setPixel method.

To try this out, I applied it to the fractal code I used in an earlier post. In this particular case I can assign an index value to each pixel, instead of a color, and then simply use a single array for the palette mapping.

So first I set an index value for each pixel in the bitmap data, and the palette data (The palette data will retain the original values, and I will use it to map against when I set the values for my bitmap).

bitmapData.setPixel(ix, iy, iteration);
paletteData.setPixel(ix, iy, iteration);

And now, my render loop only need to do 128 steps, one for each index. this is much quicker than looping through all 320×240 pixels.

for(i in 0...128) {
    r = i + colorModifier;
    g = i + colorModifier + r;
    b = i + colorModifier + g;
    rgbArray[i] = (r<<16 | g<<8 | b);
}
...
bitmapData.paletteMap(paletteData, bitmapData.rect, new Point(0,0), rgbArray, rgbArray, rgbArray);

The performance gain is pretty awesome. The setPixel version ran at about 50-60 fps on my machine at 320x240.This paletteMap version runs at 1000+ fps! (Takes less than 1 ms to render). Nice.

Get Adobe Flash player

And here's a version running at 1024x768 with 512 iterations.

Also, as a curious side note, I happend to notice that "flash.Lib.current.stage.stageHeight" is not a good thing to use in a loop (duh) :) Replacing it with an inlined static variable reduced fractal generation time with several hundred ms.

The full haXe source is available here if you want it.

MooTools form validation

Friday, October 30th, 2009

I was digging around in some old backup files of mine, and I happened to stumble across a form validation script I made for MooTools a while back. And I thought, hey, this is actually pretty neat. So I figured I should write up a simple test form for it and post it on my blog. In case anyone is intreseted in yet another form validator for MooTools :)

Basic usage is very simple. All that is needed in the example below is:

new FormHandler({form:'MyForm', identical:['f7', 'f8']});

Some of the features include;

  • Uses class names to specify which fields to validate
  • Email and number validation
  • Matching fields validation (Useful for password re-type fields)
  • Callbacks for onValid and onInvalid

Requires MooTools core 1.2.1 or later.

Here’s an example: (in an iframe)

Code can be downloaded here.