Blog

Archive of August 2009

CSS Resizable "Background" Image Technique

Resize this page. The background will remain the same width as the window. The technique uses an actual image tag and its own fixed position div wrapper to pull off the effect. This will probably make semantic-web nazis' heads explode, but at least it doesn't use tables. The image will remain at the top of the page however, so having the image end in a single color at the bottom, matched by a similar color for the body background would probably finish this off quite nicely. If you need the image to center, use the tables technique linked above. Here's the basic CSS to pull this off in IE7, IE8, Firefox, Safari, Opera and Chrome:

HTML {
height:100%;
width:100%;
}
BODY {
min-height:100%;
width:100%;
margin:0;
padding:0;
}

#bg {
position:fixed;
top:0;
left:0;
width:100%;
height:100%;
overflow:hidden;
}
#bgimg {
width:100%;
}

And this is all the HTML you need to add to the top of the page (above any "wrapper" div you may be using):

<div id="bg">
<img id="bgimg" src="[URL_TO_YOUR_IMAGE]"
alt="background image" width="0" />
</div>

To find out how to make this work in IE6, look at the source code of The Demo page

Tags: , ,
2009.08.21 11:14 PM | Permalink 0 Comments

Fun with static methods in Flash AS3 : controlling instances

Every once and a while there are times, especially when creating a public API, when you want to be able to hide settings and actions from plain view. Here's a fun little trick: using public static methods to control instances of a class. By creating internal interfaces, you can use static methods to control various aspects of a class that wouldn't be accessible through "normal means". Now, the following code is obviously an over simplified example, but it does show the concept. It shows how to access normally inaccessible properties, do extended actions during set up, or even simulate Constructor overloading.

package {

public class TestStatic {

private var _readOnly:boolean = false;

private var _name:String;
private var _color:String;


public function TestStatic(name:String,color:String) {
_name = name;
_color = color;
}

//secondary constructors
public static function BlueTestStatic(name:String):TestStatic {
return new StaticTest(name,'Blue');
}

//access advanced settings
public static function makeReadOnly(instance:TestStatic):void {
instance.readOnly = true;
}

//change 'read only' properties
public static function rename(instance:TestStatic,name:String):void {
instance.name = name;
}


public function get color():String {
return _color;
}

public function set color(value:String):void {
if(!_readOnly) {
_color = value;
}
else {
throw new ReferenceError("this property is read only");
}
}

public function get name():String {
return _name;
}

internal function set name(value:String):void {
if(!_readOnly) {
_name = value;
}
}

internal function set readOnly(value:Boolean):void {
_readOnly = value;
}
}
}


var ts:TestStatic = new TestStatic("Henry","Orange");
trace(tsN.name); //returns "Henry";
TestStatic.rename("Hank");
trace(tsN.name); //returns "Hank";
Tags: , ,
2009.08.19 10:26 PM | Permalink 0 Comments

JavaScript roman numeral converter.

Here's the JavaScript Roman Numeral Conversion functions I alluded to in the last post.

//each numeral, starting with the largest
var numerals = {
"M":1000,
"CM":900,
"D":500,
"CD":400,
"C":100,
"XC":90,
"L":50,
"XL":40,
"X":10,
"IX":9,
"V":5,
"IV":4,
"I":1
};
function RomanToDecimal(roman) {
//the roman numeral value
var _v = roman.toUpperCase();
//this holds the decimal equivalent
var _d = 0;
//if the roman value contains more than the allowed letters return Not a Number
if (!_v.match(/^[MDCLXVI]+$/)) return NaN;
//for each roman numeral
for (_n in numerals) {
//while this numeral is at the front of the passed string
while (_v.match(new RegExp("^"+_n))) {
//add the numeral's decimal value to the decimal equivalent
_d += numerals[_n];
//and pop off the numeral found
_v = _v.substr(_n.length);
}
}
// still letters left. Improper sequencing. return Not a Number
if (_v.length) return NaN;
//otherwise, return the decimal equivalent
else return _d;
}

function DecimalToRoman(num) {
//the decimal equvalent
var _d = parseInt(num);
//this will hold the roman value
var _r = '';
//for each roman numeral
for(var _n in numerals) {
// get the number of times (if any) it divides into the decimal value
var _x =Math.floor(_d/numerals[_n]);
// if it does divide into the decimal value
if (_x) {
// subtract that amount from the decimal value
_d -= (_x*numerals[_n]);
//and add the appropriate number of numerals to the roman value
for(var a=0;a<_x;a++) {
_r += _n;
}
}
// if the decimal value now equals zero, stop building our number
if (!_d) break;
}
return _r;
}
DecimalToRoman(RomanToDecimal("MCCLXXVIIII"));
Tags: ,
2009.08.17 01:07 PM | Permalink 0 Comments

Difference between using Object as associative array in Flash AS3 and JavaScript

As I was porting a Roman number converter (I will post it shortly) I had written in JavaScript to AS3 and ran into an interesting "quirk" of the AS3 Object class. I doesn't keep the keys in the same order that they were declared. The code used an Object literal as an associative array; holding each roman "digit" along with it's decimal equivalent in descending order by value. I'd then use a for ... in loop to cycle through the object. In JavaScript I'd get the values in the same order they had been generated. AS3 seems to be a little more cavalier. The following code in Javascript:

var o = {
"name1":1,
"name2":1,
"name3":1,
"name4":1,
"name5":1
};
var a=0;
for (var n in o) {
document.write(" o " + a + ":"+n);
a++;
}

produces this result in all major browsers (Firefox 3.5, IE 8, Safari 4, Opera 9.54, Chrome 2):
o 0:name1 o 1:name2
o 2:name3
o 3:name4
o 4:name5

However, using the following code in the Flash IDE

var o:Object = {
"name1":1,
"name2":1,
"name3":1,
"name4":1,
"name5":1
};
var a:uint = 0
for (var n:String in o) {
trace(" o " + a + ":"+n);
a++;
}

resulted in the following trace result:
o 0:name4
o 1:name5
o 2:name1
o 3:name2
o 4:name3

Oddly, it seemed to produce the exact same order each time I ran it. I tried it with a Dictionary, to see if the made a difference, but results were similar. I tried different values, to try and find a reason for the ordering -- to no avail. If someone knows why it's consistently picks the same random order, I'd love to know.

Tags: , , ,
2009.08.16 11:25 PM | Permalink 0 Comments

Flash AS3 Showdown: Object vs. Dictionary

I decided to see what the difference was between using a Dictionary and an Object to store simple name:value pairs, where name was always a String. Fired up the Flash IDE and typed out the following code:

import flash.sampler.getSize;
import flash.utils.Dictionary;
var a:uint;
var s:Date;
var find:Array = new Array()
var val:*;

trace('creating 20000 entries');
s = new Date();
var d:Dictionary = new Dictionary();
for (a = 0;a<20000;a++) {
d[String('name'+a)] = a;
}
trace('Dictionary creation: '
+ (new Date().valueOf() - s.valueOf()) + 'ms'
+ ', size: ' + getSize(d) + ' bytes');
s = new Date();
var o:Object = {};
for (a = 0;a<20000;a++) {
o[String('name'+a)] = a;
}
trace('Object creation: '
+ (new Date().valueOf() - s.valueOf()) + 'ms'
+ ', size: ' + getSize(o) + ' bytes');

for (a = 1;a <1000;a++) {
find.push(20000/a);
}
trace('reading 1000 keys');

s = new Date();
for (a = 0;a<1000;a++) {
val = d['name' + find[a]];
}
trace('Dictionary read: '
+ (new Date().valueOf() - s.valueOf()) + 'ms');

s = new Date();
for (a = 0;a<1000;a++) {
val = o['name' + find[a]];
}
trace('Object read: '
+ (new Date().valueOf() - s.valueOf()) + 'ms');


trace('search for 1000 values');
s = new Date();
for (a = 0;a<1000;a++) {
for each(val in d) {
if (val == find[a]) break;
}
}
trace('Dictionary search: '
+ (new Date().valueOf() - s.valueOf()) + 'ms');

s = new Date();
for (a = 0;a<1000;a++) {
for each(val in o) {
if (val == find[a]) break;
}
}
trace('Object search: '
+ (new Date().valueOf() - s.valueOf()) + 'ms');

Which produced the following trace results:

creating 20000 entries
Dictionary creation: 47ms, size: 160032 bytes
Object creation: 47ms, size: 160024 bytes

So, same speed, and Object is a tiny bit smaller. In multiple runs this was almost always the same value - often enough to be a reliable value.

reading 1000 keys
Dictionary read: 16ms
Object read: 16ms

Again, for direct key reads, the two are same speed. In multiple runs this was always the same value.

search for 1000 values
Dictionary search: 2047ms
Object search: 2219ms

Now here, Object falls down bit. The interesting thing is that, despite having the same values created for the search each time, the search ms were all over the map. Each time I fired this, I got a different value. I'm assuming this much churn was causing the garbage collector to kick in sporadically. That said, the difference between the values would vary from 100 to 400 ms. The one constant though, was that Object searches were almost always slower than Dictionary searches, and the instances where Object was faster were few and far between. However, the time was always just over 2000ms for each. So, the average speed per search was still aprox. 2-2.5ms per search for both Object and Dictionary.

Conclusion: unless you really need to use an strict type checking for your keys, then there's no discernible difference between the two, except that using Object saves you an import.

Tags: , ,
2009.08.14 11:14 PM | Permalink 0 Comments