Jun 18, 2009

Solving the wmode keyboard bug in Firefox (AS3)

The Firefox team has embarrasingly been saying (for years) that they are working on solving their problems with keyboard focus on embedded flash objects with wmode set to either 'transparent' or 'opaque'.

See details:
http://forum.sephiroth.it/showthread.php?t=9232
http://timconfessions.blogspot.com/2008/04/firefox-wmodetransparent-bug.html
http://lists.macosforge.org/pipermail/webkit-unassigned/2008-September/084474.html

The list goes on and hopes are low. There has been some dirty quickfixes circulating but I grew tired and wrote a more robust solution for AS3.

Embed the following in your class, assign it to your inputField and... enjoy.

Download Flex Project Archive

 0)? input.text.substring(input.selectionEndIndex, input.text.length) : "";

     // Enter the codes to change here
     // Below is Swedish keyboard
     switch (event.text)
     {
      case "2" : event.text = "@"; break;
      case "3" : event.text = "£"; break;
      case "4" : event.text = "$"; break;
      case "5" : event.text = "€"; break;
      case "6" : event.text = "6"; break;
      case "7" : event.text = "{"; break;
      case "8" : event.text = "["; break;
      case "9" : event.text = "]"; break;
      case "0" : event.text = "}"; break;
      case "+" : event.text = "\\"; break;
      case "<" : event.text = "|"; break;
      default : break;                     
     }

     input.text = startText + event.text + endText;
     input.setSelection(input.selectionBeginIndex + 1, input.selectionBeginIndex + 1);
    }
    catch (error:Error)
    {
     trace(error.getStackTrace());
    }
   }
  }
 }
}

Jun 8, 2009

Doing perspective in Adobe Flash the old way

This has been a problem for ages:



http://pixelfumes.blogspot.com/2006/01/flash-why-do-you-mock-me-bitmap.html

As a solution to this, some smart developer came up with a quick fix, and people seem to stick to it.

http://pixelfumes.blogspot.com/2006/01/perspective-distort-example.html

This solution maps a lot of triangles to a quad and uses bitmapFill to project the image onto the surface. As you can see it has some limitations, the borders become teared and the final results look so so.

I'm currently working on a wallpaper application for a company that sells.. well guess.

Since there's always version-limitations as to what you can expect from the visitors, we decided that flashplayer 9 was the target version for this application, but this version suffers from the aforementioned problems so we had to fix it somehow.



After looking at the results of the 'perspective distort script' I concluded that there was something awkwardly wrong with this way of drawing images. The code places the triangles in a linearly interpolated fashion which screws up any chance of actually drawing something close to a correct perspective.

(If you're into this kind of stuff, You've probably seen this bit of code before)
public function setTransform( x0:Number , y0:Number , x1:Number , y1:Number , x2:Number , y2:Number , x3:Number , y3:Number ):void
{
var w:Number = texture.width;
var h:Number = texture.height;

var dx30:Number = x3 - x0;
var dy30:Number = y3 - y0;
var dx21:Number = x2 - x1;
var dy21:Number = y2 - y1;

var l:Number = poly.length;

while( --l > -1 )
{
var point:Object = poly[ l ];

var gx:Number = (( point.x - _xMin ) / w);
var gy:Number = ( point.y - _yMin ) / h;

var bx:Number = x0 + gy * ( dx30 );
var by:Number = y0 + gy * ( dy30 );

point.sx = bx + gx * ( ( x1 + gy * ( dx21 ) ) - bx );
point.sy = by + gx * ( ( y1 + gy * ( dy21 ) ) - by );
}
render();
}
After some thinking I came up with a somewhat simple quick-fix to a wall specific problem. With a bit of tinkering you'll easily be able to add vertical correction too, if that floats your boat. Anyway... enjoy.
public function setTransform( x0:Number , y0:Number , x1:Number , y1:Number , x2:Number , y2:Number , x3:Number , y3:Number ):void
{
var w:Number = texture.width;
var h:Number = texture.height;

var dx30:Number = x3 - x0;
var dy30:Number = y3 - y0;
var dx21:Number = x2 - x1;
var dy21:Number = y2 - y1;

var l:Number = poly.length;

// Calculate the facing angle of the quad.
var dangle:Number = ((Math.atan2(dy30 - dy21, x2 - x0) * (180/Math.PI)) / 90);

while( --l > -1 )
{
var point:Object = poly[ l ];

var gx:Number = (( point.x - _xMin ) / w);
var gy:Number = ( point.y - _yMin ) / h;

// Quadraticly shift the triangles x-ward into the perspective depending on the facing angle
var gxshift:Number = (gx * (1 - Math.abs(dangle))) + (Math.pow(gx, 2) * Math.abs(dangle));

if (dangle > 0) gxb = 1 - gxb;

var bx:Number = x0 + gy * ( dx30 );
var by:Number = y0 + gy * ( dy30 );

// Apply the new coordinates
point.sx = bx + gxshift * ( ( x1 + gy * ( dx21 ) ) - bx );
point.sy = by + gxshift * ( ( y1 + gy * ( dy21 ) ) - by );
}
render();
}
During this project I also came across some creative ways to apply subtle sharpening to images in flash. Post a comment or something if you're interested.