...

View Full Version : Trouble with Prototypes - Extending an Image Object to Make a Snowflake



EchoLynx
12-31-2010, 11:27 PM
In the spirit of the season, I wanted to make it snow on my website. So I began digging. Eventually I ended up with a script that moved an image element down the page in a snowflake-like manner. The problem with it was it was dependant on an img element for every flake - simply no poor programming when using an Object Oriented programming language.

So I decided I wanted to extend (in Java-speak; most of my programming background is in Java) the in-built Image object. The new object's src variable will lead to an image of the type of flake it is. (I want to be able to have more variance in images than a simple dot.) The new object will have a function that will allow it to move. A separate, unrelated function will control when each flakes move.

I did some more research and read about prototyping on JavaScript Kit and here (http://mckoss.com/jscript/object.htm), but I still cant seem to get this to work. JS Lint says it's bug-free, but Firefox says "move()" is an invalid function. I am presuming the problem lies in my inability to fully grasp how to extend objects in JavaScript.


<html>
<head>
<script type="text/javascript">
Image.prototype.dFlake=dotFlake;
function dotFlake(xLocation,yLocation){
this.src = "simpleDotFlake.png";
this.x = xLocation;
this.y = yLocation;
}
dotFlake.prototype.move = fall;
function fall(){ // ^^ Belongs to dotFlake class.
this.style.position="absolute";
this.style.top = this.y;
this.style.left = this.x;

this.y= this.y + 1; // Falling is constant.
if (Math.random() > 0.5){ // Random direction, though.
this.x = this.x + 1;
} else{
this.x = this.x - 1;
}
}
function snow(flakes){ // Allows addition of different flakes later.
for (i in flakes){
i.move();
}
timer = setTimeout("snow()",1);
}
function startSnow(){
basicFlakes = new Array(new dotFlake(0,0));
snow(basicFlakes);
}
</script>
</head>
<body onload="startSnow()">
<h1>This is test text.</h1>
<img id="basicFlake" src="./simpleDotFlake.png" width="10" height="10" />
</body>
</html>

Any and all input is much appreciated.

Thank you!

oesxyl
01-01-2011, 01:54 AM
In the spirit of the season, I wanted to make it snow on my website. So I began digging. Eventually I ended up with a script that moved an image element down the page in a snowflake-like manner. The problem with it was it was dependant on an img element for every flake - simply no poor programming when using an Object Oriented programming language.

So I decided I wanted to extend (in Java-speak; most of my programming background is in Java) the in-built Image object. The new object's src variable will lead to an image of the type of flake it is. (I want to be able to have more variance in images than a simple dot.) The new object will have a function that will allow it to move. A separate, unrelated function will control when each flakes move.

I did some more research and read about prototyping on JavaScript Kit and here (http://mckoss.com/jscript/object.htm), but I still cant seem to get this to work. JS Lint says it's bug-free, but Firefox says "move()" is an invalid function. I am presuming the problem lies in my inability to fully grasp how to extend objects in JavaScript.


<html>
<head>
<script type="text/javascript">
Image.prototype.dFlake=dotFlake;
function dotFlake(xLocation,yLocation){
this.src = "simpleDotFlake.png";
this.x = xLocation;
this.y = yLocation;
}
dotFlake.prototype.move = fall;
function fall(){ // ^^ Belongs to dotFlake class.
this.style.position="absolute";
this.style.top = this.y;
this.style.left = this.x;

this.y= this.y + 1; // Falling is constant.
if (Math.random() > 0.5){ // Random direction, though.
this.x = this.x + 1;
} else{
this.x = this.x - 1;
}
}
function snow(flakes){ // Allows addition of different flakes later.
for (i in flakes){
i.move();
}
timer = setTimeout("snow()",1);
}
function startSnow(){
basicFlakes = new Array(new dotFlake(0,0));
snow(basicFlakes);
}
</script>
</head>
<body onload="startSnow()">
<h1>This is test text.</h1>
<img id="basicFlake" src="./simpleDotFlake.png" width="10" height="10" />
</body>
</html>

Any and all input is much appreciated.

Thank you!

try this( not tested):


function dotFlake(xLocation,yLocation){
this.src = "simpleDotFlake.png";
this.x = xLocation;
this.y = yLocation;
}

dotFlake.prototype = {
fall:function(){ // ^^ Belongs to dotFlake class.
this.style.position="absolute";
this.style.top = this.y;
this.style.left = this.x;

this.y= this.y + 1; // Falling is constant.
if (Math.random() > 0.5){ // Random direction, though.
this.x = this.x + 1;
} else{
this.x = this.x - 1;
}
}
};

function snow(flakes){ // Allows addition of different flakes later.
for (i in flakes){
i.fall();
}
timer = setTimeout("snow()",1);
};

startSnow:function(){
basicFlakes = new Array(new dotFlake(0,0));
snow(basicFlakes);
};



wait i think i messed up the code, not all are methods of dotFlakes.

i think i fixed now

best regards

oesxyl
01-01-2011, 04:24 AM
this works for me in ffox 3.0.6:

flake.js:


/* -*- c++ -*- */
function dotFlake(xLoc,yLoc){
this.init(xLoc,yLoc);
this.x = xLoc;
this.y = yLoc;
this.move(0,0);
};

dotFlake.prototype = {
init:function(x,y){
this.obj = document.getElementById('basicFlake');
},

move:function(dx,dy){
this.x += dx;
this.y += dy;
this.obj.style.cssText = 'position: absolute; top: ' + this.x + 'px; left: ' + this.y + 'px;';
}
};

var flake;

function snow(){
var dx = Math.random()*100 -50, dy = Math.random()*100 -50;
flake.move(dx,dy);
};

window.onload = function(ev){
flake = new dotFlake(100,100);
setInterval(snow,1000);
};


index.html:


<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript" src="flakes.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<meta name="description" content="" />
<meta name="keywords" content="" />
</head>
<body>
<h1>This is test text.</h1>
<img id="basicFlake" src="./simpleDotFlake.png" style="width:10;height:10;" />
</body>
</html>


best regards

EchoLynx
01-01-2011, 01:42 PM
You sure go the extra mile to help a guy out! Thanks!

Unfortunately, I the only one I could get to work was the second one, and it doesn't solve my problem of having to write in an <img /> with a unique id for each flake (or at least I don't think it does...).

That is why I was interested in extending the Image object. That way, every dotFlake object would have an image associated with it as the parent is the Image object - no need to get and image by ID.

I think you tried to do this in the first one, but followed caught the train of thought I had originally, the one that led me to the discovery of the <img /> limitation.



<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="template.php_files/style.html">
<title>EchoLynx.com</title>

<script type="text/javascript">
var x = 100;
var y = 0;
var timer;

function startSnow(){
if (document.body.clientHeight<y){ //Thanks! http://www.softcomplex.com/docs/get_window_size_and_scrollbar_position.html
clearTimeout(timer);
document.getElementById("basicFlake").visible = "collapse";
} else {
timer = setTimeout("startSnow()",1);
}
document.getElementById("basicFlake").style.position="absolute";
document.getElementById("basicFlake").style.top = y;
document.getElementById("basicFlake").style.left = x;
y++; // Falling is constant.
if (Math.random() >.5){ // Random direction, though.
x++;
} else{
x--;
}
}
function stopSnow(){
document.getElementById("basicFlake").style.visible="hidden";
}
</script>
</head>
<body onload="startSnow()">
<h1>This is test text.</h1>
<a href="stopSnow()">Stop Snow</a>
<img id="basicFlake" src="./simpleDotFlake.png" width="10" height="10" />
</body>
</html>

oesxyl
01-01-2011, 05:48 PM
You sure go the extra mile to help a guy out! Thanks!

Unfortunately, I the only one I could get to work was the second one, and it doesn't solve my problem of having to write in an <img /> with a unique id for each flake (or at least I don't think it does...).
yes, you are right, first didn't work, that's why i post the second one, :)
i understand why you try to avoid using the id but imo is not such a big problem because you have many ways to get one or more objects from a page. Of course for this we need to write the proper code.
the idea behind my second post was not to make it work as you want, only to work and use prototype, i assume you want to do your own experiments with this.


That is why I was interested in extending the Image object. That way, every dotFlake object would have an image associated with it as the parent is the Image object - no need to get and image by ID.

I think you tried to do this in the first one, but followed caught the train of thought I had originally, the one that led me to the discovery of the <img /> limitation.



<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="template.php_files/style.html">
<title>EchoLynx.com</title>

<script type="text/javascript">
var x = 100;
var y = 0;
var timer;

function startSnow(){
if (document.body.clientHeight<y){ //Thanks! http://www.softcomplex.com/docs/get_window_size_and_scrollbar_position.html
clearTimeout(timer);
document.getElementById("basicFlake").visible = "collapse";
} else {
timer = setTimeout("startSnow()",1);
}
document.getElementById("basicFlake").style.position="absolute";
document.getElementById("basicFlake").style.top = y;
document.getElementById("basicFlake").style.left = x;
y++; // Falling is constant.
if (Math.random() >.5){ // Random direction, though.
x++;
} else{
x--;
}
}
function stopSnow(){
document.getElementById("basicFlake").style.visible="hidden";
}
</script>
</head>
<body onload="startSnow()">
<h1>This is test text.</h1>
<a href="stopSnow()">Stop Snow</a>
<img id="basicFlake" src="./simpleDotFlake.png" width="10" height="10" />
</body>
</html>
i guess you want to make js code as much as you can independent of the content of html, is this correct?
take a look at this DOM Reference (http://www.javascriptkit.com/domref/index.shtml)

best regards and happy new year.

EchoLynx
01-01-2011, 08:15 PM
Aha! I could use the cloneNode method in a loop to copy the image element's node as many times as I need!

Muchas gracias, seņor! I will try that...

That is what you meant, right? There isn't another, better way that you I am missing, is there?

PS- You guessed correctly- I am the kind of person who would much rather receive a nudge in the right direction instead of a complete answer. :D

oesxyl
01-01-2011, 08:49 PM
Aha! I could use the cloneNode method in a loop to copy the image element's node as many times as I need!
yes, but you could try to explore another ways like creating new flakes objects and appending to a given container, a div in the html page. see createElement, appendChild, removeChild for example.


Muchas gracias, seņor! I will try that...
you are welcome, :)


That is what you meant, right? There isn't another, better way that you I am missing, is there?
yes to first question, no to second, and usualy it's hard and incorrect to say that something is better then something else, rather are different ways to do same thing.
what is better you can decide based on code, speed, cross-browsers, easy to use and in the end personal preferences.


PS- You guessed correctly- I am the kind of person who would much rather receive a nudge in the right direction instead of a complete answer. :D
i like to explore my self different things no matter how hard it is so it's easy to guess when somebody else have same preferences, :)

best regards



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum