Loading images before starting the webapp

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

Loading images before starting the webapp

Clément Bera
Hello,
I try to move an html 5 game made with the html canvas tag from
javascript to Smalltalk with Amber. I found a way to do most things I
had in my previous code in javascript but Image management.

Basically, I used to load all the images at the begining of the game,
so the user can play freely in real time once everything is loaded.
The code looked like :
var image;
image = new Image();
image.src = "images/ground.png";
image.onload = function(){ if (allImageLoaded) startGame();}

I tried to do this with Amber, but I had some issues. I didn't find a
way to do new Image() so I used :
|image|
image := <new Image()>.
image src: images/ground.png".

But I can't find a way to use the onload function. I could use another
Image Class made by myself, but I need to display the image through
canvas : context2d drawImage: image x: 50 y: 50.

Can you tell me if you know a way to use the onload function ? Is
there another way to instantiate image than <new Image()> ?

Thank you very much for your help
Reply | Threaded
Open this post in threaded view
|

Re: Loading images before starting the webapp

sebastianconcept
you can use "ready" in the header of your page:

  <script type="text/javascript">
amber.load({
files: ['blah.js',
'blah.js'],
prefix: '',
ready: function() {smalltalk.YourMainPresenter._open()}}); 
    </script> 

the ready callback is executed when all is loaded and you can make YourMainPresenter to load all those images when opens




Em sábado, 26 de maio de 2012 10h27min53s UTC-3, Clément Bera escreveu:
Hello,
I try to move an html 5 game made with the html canvas tag from
javascript to Smalltalk with Amber. I found a way to do most things I
had in my previous code in javascript but Image management.

Basically, I used to load all the images at the begining of the game,
so the user can play freely in real time once everything is loaded.
The code looked like :
var image;
image = new Image();
image.src = "images/ground.png";
image.onload = function(){ if (allImageLoaded) startGame();}

I tried to do this with Amber, but I had some issues. I didn't find a
way to do new Image() so I used :
|image|
image := <new Image()>.
image src: images/ground.png".

But I can't find a way to use the onload function. I could use another
Image Class made by myself, but I need to display the image through
canvas : context2d drawImage: image x: 50 y: 50.

Can you tell me if you know a way to use the onload function ? Is
there another way to instantiate image than <new Image()> ?

Thank you very much for your help
Reply | Threaded
Open this post in threaded view
|

Re: Loading images before starting the webapp

Clément Bera
Hello,

I did the way you said, but there is still the issue. In
smalltalk.YourMainPresenter._open(), I have the code :

var img:= <new Image()>.
img src: 'images/ground.png'.
self drawImage: img onCanvas: aCanvas.

whereas I should have something :
var img:= <new Image()>.
img src: 'images/ground.png'.
img ready:[self drawImage: img onCanvas: aCanvas].

Because drawImage (javascript function) does not work if the image is
not loaded yet. But ready does not work.

Perhaps you meant I have to include loading images in amber.load, so
that "ready" from amber.load could permit to launch my game I'll have
a look.

thanks,

On 27 mai, 00:19, Sebastian Sastre <[hidden email]> wrote:

> you can use "ready" in the header of your page:
>
>   <script type="text/javascript">
> amber.load({
> files: ['blah.js',
> 'blah.js'],
> prefix: '',
> ready: function() {smalltalk.YourMainPresenter._open()}});
>     </script>
>
> the ready callback is executed when all is loaded and you can make
> YourMainPresenter to load all those images when opens
>
> Em sábado, 26 de maio de 2012 10h27min53s UTC-3, Clément Bera escreveu:
>
>
>
>
>
>
>
>
>
> > Hello,
> > I try to move an html 5 game made with the html canvas tag from
> > javascript to Smalltalk with Amber. I found a way to do most things I
> > had in my previous code in javascript but Image management.
>
> > Basically, I used to load all the images at the begining of the game,
> > so the user can play freely in real time once everything is loaded.
> > The code looked like :
> > var image;
> > image = new Image();
> > image.src = "images/ground.png";
> > image.onload = function(){ if (allImageLoaded) startGame();}
>
> > I tried to do this with Amber, but I had some issues. I didn't find a
> > way to do new Image() so I used :
> > |image|
> > image := <new Image()>.
> > image src: images/ground.png".
>
> > But I can't find a way to use the onload function. I could use another
> > Image Class made by myself, but I need to display the image through
> > canvas : context2d drawImage: image x: 50 y: 50.
>
> > Can you tell me if you know a way to use the onload function ? Is
> > there another way to instantiate image than <new Image()> ?
>
> > Thank you very much for your help
Reply | Threaded
Open this post in threaded view
|

Re: Loading images before starting the webapp

Clément Bera
Ok I found a way to do what I want.

Basically it work this way.
image := <new Image()>.
image src: 'specter.jpg'.
< self.onload = self._onLoadFunction() >.

and onLoadFunction is another class method in smalltalk.

It works but I don't like it. If you have other ideas...

On 27 mai, 09:20, Clément Bera <[hidden email]> wrote:

> Hello,
>
> I did the way you said, but there is still the issue. In
> smalltalk.YourMainPresenter._open(), I have the code :
>
> var img:= <new Image()>.
> img src: 'images/ground.png'.
> self drawImage: img onCanvas: aCanvas.
>
> whereas I should have something :
> var img:= <new Image()>.
> img src: 'images/ground.png'.
> img ready:[self drawImage: img onCanvas: aCanvas].
>
> Because drawImage (javascript function) does not work if the image is
> not loaded yet. But ready does not work.
>
> Perhaps you meant I have to include loading images in amber.load, so
> that "ready" from amber.load could permit to launch my game I'll have
> a look.
>
> thanks,
>
> On 27 mai, 00:19, Sebastian Sastre <[hidden email]> wrote:
>
>
>
>
>
>
>
> > you can use "ready" in the header of your page:
>
> >   <script type="text/javascript">
> > amber.load({
> > files: ['blah.js',
> > 'blah.js'],
> > prefix: '',
> > ready: function() {smalltalk.YourMainPresenter._open()}});
> >     </script>
>
> > the ready callback is executed when all is loaded and you can make
> > YourMainPresenter to load all those images when opens
>
> > Em sábado, 26 de maio de 2012 10h27min53s UTC-3, Clément Bera escreveu:
>
> > > Hello,
> > > I try to move an html 5 game made with the html canvas tag from
> > > javascript to Smalltalk with Amber. I found a way to do most things I
> > > had in my previous code in javascript but Image management.
>
> > > Basically, I used to load all the images at the begining of the game,
> > > so the user can play freely in real time once everything is loaded.
> > > The code looked like :
> > > var image;
> > > image = new Image();
> > > image.src = "images/ground.png";
> > > image.onload = function(){ if (allImageLoaded) startGame();}
>
> > > I tried to do this with Amber, but I had some issues. I didn't find a
> > > way to do new Image() so I used :
> > > |image|
> > > image := <new Image()>.
> > > image src: images/ground.png".
>
> > > But I can't find a way to use the onload function. I could use another
> > > Image Class made by myself, but I need to display the image through
> > > canvas : context2d drawImage: image x: 50 y: 50.
>
> > > Can you tell me if you know a way to use the onload function ? Is
> > > there another way to instantiate image than <new Image()> ?
>
> > > Thank you very much for your help
Reply | Threaded
Open this post in threaded view
|

Re: Loading images before starting the webapp

Balázs Kósi
Hi!

image is a JSObjectProxy, you can set properties of a js object with #at:put:.

image := <new Image()>.
image class. " JSObjectProxy "
image at: 'onload' put: [ console log: 'loaded' ].
img at: 'src' put: 'image.png'

img src: 'image.png' works, because the src property is already defined,
and it goes through the JSObjectProxy >> doesNotUnderstand:.
Take a look at that method.

If you set src first and onload second, you may miss the event, if the image
loads before you can set the onload handler.

Amber resolves Image to a js object, it would be nice if we could just write:
image := Image new
It would probably make some sense to bring BlockClosure's #new, #newValue:
and friends over to JSObjectProxy. What do you think?

cheers, Balázs
Reply | Threaded
Open this post in threaded view
|

Re: Loading images before starting the webapp

Clément Bera
Thank you very much for your help Balazs, that was exactly what I was
looking for. You also fixed my other bugs on other JSObject, I can now
move my game from javascript to Amber.

I tried to add something like #new to JSObjectProxy, but it didn't
work. Perhaps it's not possible as it is a proxy, not the object
itself.
I tried :
onImage
        |image|
        image := <new Image()>.
        ^self new
                jsObject: image;
                yourself
But it doesn't work (it compiles, error in javascript console from
firefox).

Thanks a lot anyway,

On 27 mai, 10:51, Balázs Kósi <[hidden email]> wrote:

> Hi!
>
> image is a JSObjectProxy, you can set properties of a js object with
> #at:put:.
>
> image := <new Image()>.
> image class. " JSObjectProxy "
> image at: 'onload' put: [ console log: 'loaded' ].
> img at: 'src' put: 'image.png'
>
> img src: 'image.png' works, because the src property is already defined,
> and it goes through the JSObjectProxy >> doesNotUnderstand:.
> Take a look at that method.
>
> If you set src first and onload second, you may miss the event, if the image
> loads before you can set the onload handler.
>
> Amber resolves Image to a js object, it would be nice if we could just
> write:
> image := Image new
> It would probably make some sense to bring BlockClosure's #new, #newValue:
> and friends over to JSObjectProxy. What do you think?
>
> cheers, Balázs
Reply | Threaded
Open this post in threaded view
|

Re: Loading images before starting the webapp

Balázs Kósi
I tried to add something like #new to JSObjectProxy, but it didn't
work. Perhaps it's not possible as it is a proxy, not the object
itself.
 
Probably that was your problem exactly. Although it's possible to solve it,
because you can access the original object. Try adding the following method to
JSObjectProxy.

new
    <return new self['@jsObject']()>

and then you can evaluate:

Image new
    at: 'onload' put: [ :evt | 'body' asJQuery prepend: evt target ];
    at: 'src' put: 'http://amber-lang.net/images/amber.png'
Reply | Threaded
Open this post in threaded view
|

Re: Loading images before starting the webapp

Nicolas Petton
In reply to this post by Clément Bera
Clément Bera <[hidden email]> writes:

Hi!

The Image constructor is a bit special. With normal constructor
functions, you could just have done "Foo new" and it would have worked.

Here, if you want to have the ImageConstructor as a Smalltalk class, you
need to map the constructor to an Amber class:

smalltalk.mapClassName('Image', 'MyPackage', Image, smalltalk.Object);
smalltalk.init(smalltalk.Image);

you can add accessors to img properties:

Image >> src
      ^ self basicAt: 'src'

Image >> src: aString
      self basicAt: 'src' put: aString

then you can do:

img := Image new.
img src: aString

HTH,
Nico


See boot.js for other wrapped JS constructors.

> Hello,
> I try to move an html 5 game made with the html canvas tag from
> javascript to Smalltalk with Amber. I found a way to do most things I
> had in my previous code in javascript but Image management.
>
> Basically, I used to load all the images at the begining of the game,
> so the user can play freely in real time once everything is loaded.
> The code looked like :
> var image;
> image = new Image();
> image.src = "images/ground.png";
> image.onload = function(){ if (allImageLoaded) startGame();}
>
> I tried to do this with Amber, but I had some issues. I didn't find a
> way to do new Image() so I used :
> |image|
> image := <new Image()>.
> image src: images/ground.png".
>
> But I can't find a way to use the onload function. I could use another
> Image Class made by myself, but I need to display the image through
> canvas : context2d drawImage: image x: 50 y: 50.
>
> Can you tell me if you know a way to use the onload function ? Is
> there another way to instantiate image than <new Image()> ?
>
> Thank you very much for your help

--
Nicolas Petton
http://nicolas-petton.fr
Reply | Threaded
Open this post in threaded view
|

Re: Loading images before starting the webapp

Andrew McQuiggin

It's useful to know how to deal with this special case, Nico.

I'm interested to know what makes it different, and are there others that are also special cases?

Thanks,

        Andrew

On May 28, 2012 7:48 AM, <[hidden email]> wrote:
Clément Bera <[hidden email]> writes:

Hi!

The Image constructor is a bit special. With normal constructor
functions, you could just have done "Foo new" and it would have worked.

Here, if you want to have the ImageConstructor as a Smalltalk class, you
need to map the constructor to an Amber class:

smalltalk.mapClassName('Image', 'MyPackage', Image, smalltalk.Object);
smalltalk.init(smalltalk.Image);

you can add accessors to img properties:

Image >> src
     ^ self basicAt: 'src'

Image >> src: aString
     self basicAt: 'src' put: aString

then you can do:

img := Image new.
img src: aString

HTH,
Nico


See boot.js for other wrapped JS constructors.

> Hello,
> I try to move an html 5 game made with the html canvas tag from
> javascript to Smalltalk with Amber. I found a way to do most things I
> had in my previous code in javascript but Image management.
>
> Basically, I used to load all the images at the begining of the game,
> so the user can play freely in real time once everything is loaded.
> The code looked like :
> var image;
> image = new Image();
> image.src = "images/ground.png";
> image.onload = function(){ if (allImageLoaded) startGame();}
>
> I tried to do this with Amber, but I had some issues. I didn't find a
> way to do new Image() so I used :
> |image|
> image := <new Image()>.
> image src: images/ground.png".
>
> But I can't find a way to use the onload function. I could use another
> Image Class made by myself, but I need to display the image through
> canvas : context2d drawImage: image x: 50 y: 50.
>
> Can you tell me if you know a way to use the onload function ? Is
> there another way to instantiate image than <new Image()> ?
>
> Thank you very much for your help

--
Nicolas Petton
http://nicolas-petton.fr
Reply | Threaded
Open this post in threaded view
|

Re: Loading images before starting the webapp

Andrew McQuiggin

I just spotted your reference to boot.js for the other wrapped JS constructors...

On May 28, 2012 7:56 AM, "Andrew McQuiggin" <[hidden email]> wrote:

It's useful to know how to deal with this special case, Nico.

I'm interested to know what makes it different, and are there others that are also special cases?

Thanks,

        Andrew

On May 28, 2012 7:48 AM, <[hidden email]> wrote:
Clément Bera <[hidden email]> writes:

Hi!

The Image constructor is a bit special. With normal constructor
functions, you could just have done "Foo new" and it would have worked.

Here, if you want to have the ImageConstructor as a Smalltalk class, you
need to map the constructor to an Amber class:

smalltalk.mapClassName('Image', 'MyPackage', Image, smalltalk.Object);
smalltalk.init(smalltalk.Image);

you can add accessors to img properties:

Image >> src
     ^ self basicAt: 'src'

Image >> src: aString
     self basicAt: 'src' put: aString

then you can do:

img := Image new.
img src: aString

HTH,
Nico


See boot.js for other wrapped JS constructors.

> Hello,
> I try to move an html 5 game made with the html canvas tag from
> javascript to Smalltalk with Amber. I found a way to do most things I
> had in my previous code in javascript but Image management.
>
> Basically, I used to load all the images at the begining of the game,
> so the user can play freely in real time once everything is loaded.
> The code looked like :
> var image;
> image = new Image();
> image.src = "images/ground.png";
> image.onload = function(){ if (allImageLoaded) startGame();}
>
> I tried to do this with Amber, but I had some issues. I didn't find a
> way to do new Image() so I used :
> |image|
> image := <new Image()>.
> image src: images/ground.png".
>
> But I can't find a way to use the onload function. I could use another
> Image Class made by myself, but I need to display the image through
> canvas : context2d drawImage: image x: 50 y: 50.
>
> Can you tell me if you know a way to use the onload function ? Is
> there another way to instantiate image than <new Image()> ?
>
> Thank you very much for your help

--
Nicolas Petton
http://nicolas-petton.fr
Reply | Threaded
Open this post in threaded view
|

Re: Loading images before starting the webapp

Nicolas Petton
In reply to this post by Andrew McQuiggin
Andrew McQuiggin <[hidden email]> writes:

> It's useful to know how to deal with this special case, Nico.
>
> I'm interested to know what makes it different, and are there others
> that are also special cases?

Amber maps one to one with the JS equivalent whenever it makes sense.
So functions in JavaScript are BlockClosure instances in Amber.

If you have a JS function Foo, you can do in Amber

Foo new

And it will call the function with the "new" operator.

Now Image() is not a normal JS function, so it doesn't work.

Also, for more complex wrapping, using Smalltalk classes makes
sense. For example, Number() is wrapped to Number in Smalltalk,
etc.

Nico

>
> Thanks,
>
>         Andrew
>
> On May 28, 2012 7:48 AM, <[hidden email]> wrote:
>
>     Clément Bera <[hidden email]> writes:
>    
>     Hi!
>    
>     The Image constructor is a bit special. With normal constructor
>     functions, you could just have done "Foo new" and it would have
>     worked.
>    
>     Here, if you want to have the ImageConstructor as a Smalltalk
>     class, you
>     need to map the constructor to an Amber class:
>    
>     smalltalk.mapClassName('Image', 'MyPackage', Image,
>     smalltalk.Object);
>     smalltalk.init(smalltalk.Image);
>    
>     you can add accessors to img properties:
>    
>     Image >> src
>          ^ self basicAt: 'src'
>    
>     Image >> src: aString
>          self basicAt: 'src' put: aString
>    
>     then you can do:
>    
>     img := Image new.
>     img src: aString
>    
>     HTH,
>     Nico
>    
>    
>     See boot.js for other wrapped JS constructors.
>    
>     > Hello,
>     > I try to move an html 5 game made with the html canvas tag from
>     > javascript to Smalltalk with Amber. I found a way to do most
>     things I
>     > had in my previous code in javascript but Image management.
>     >
>     > Basically, I used to load all the images at the begining of the
>     game,
>     > so the user can play freely in real time once everything is
>     loaded.
>     > The code looked like :
>     > var image;
>     > image = new Image();
>     > image.src = "images/ground.png";
>     > image.onload = function(){ if (allImageLoaded) startGame();}
>     >
>     > I tried to do this with Amber, but I had some issues. I didn't
>     find a
>     > way to do new Image() so I used :
>     > |image|
>     > image := <new Image()>.
>     > image src: images/ground.png".
>     >
>     > But I can't find a way to use the onload function. I could use
>     another
>     > Image Class made by myself, but I need to display the image
>     through
>     > canvas : context2d drawImage: image x: 50 y: 50.
>     >
>     > Can you tell me if you know a way to use the onload function ?
>     Is
>     > there another way to instantiate image than <new Image()> ?
>     >
>     > Thank you very much for your help
>    
>     --
>     Nicolas Petton
>     http://nicolas-petton.fr
>    

--
Nicolas Petton
http://nicolas-petton.fr
Reply | Threaded
Open this post in threaded view
|

Re: Loading images before starting the webapp

Clément Bera
I tried to do the way Nico said :
smalltalk.wrapClassName('Image', 'MyPackage', Image,
smalltalk.Object); "Note it is wrapClassName not mapClassName"
smalltalk.init(smalltalk.Image);

but I still can't use accessor, when I write :
Image >> onload
      ^ self basicAt: 'onload'
Image >> onload: aBlock
      self basicAt: 'onload' put: aBlock

The debugger tells me : [object HTMLImageElement] does not understand
#onload:

In Nico's example, he used :
img := Image new.
img src: aString

and it works, but not because of accessors to img properties, but
because it goes through the JSObjectProxy >> doesNotUnderstand:.

Anyway, I'm going to use :
img := <new Image()>.
and then use it as a JSObjectProxy. It is just written in 1 method of
class, so it's OK. I just wanted to know if using <new Image()> was
the proper way to instantiate the Image.

Thanks a lot everyone anyway.

On 28 mai, 09:30, [hidden email] wrote:

> Andrew McQuiggin <[hidden email]> writes:
> > It's useful to know how to deal with this special case, Nico.
>
> > I'm interested to know what makes it different, and are there others
> > that are also special cases?
>
> Amber maps one to one with the JS equivalent whenever it makes sense.
> So functions in JavaScript are BlockClosure instances in Amber.
>
> If you have a JS function Foo, you can do in Amber
>
> Foo new
>
> And it will call the function with the "new" operator.
>
> Now Image() is not a normal JS function, so it doesn't work.
>
> Also, for more complex wrapping, using Smalltalk classes makes
> sense. For example, Number() is wrapped to Number in Smalltalk,
> etc.
>
> Nico
>
>
>
>
>
>
>
>
>
>
>
> > Thanks,
>
> >         Andrew
>
> > On May 28, 2012 7:48 AM, <[hidden email]> wrote:
>
> >     Clément Bera <[hidden email]> writes:
>
> >     Hi!
>
> >     The Image constructor is a bit special. With normal constructor
> >     functions, you could just have done "Foo new" and it would have
> >     worked.
>
> >     Here, if you want to have the ImageConstructor as a Smalltalk
> >     class, you
> >     need to map the constructor to an Amber class:
>
> >     smalltalk.mapClassName('Image', 'MyPackage', Image,
> >     smalltalk.Object);
> >     smalltalk.init(smalltalk.Image);
>
> >     you can add accessors to img properties:
>
> >     Image >> src
> >          ^ self basicAt: 'src'
>
> >     Image >> src: aString
> >          self basicAt: 'src' put: aString
>
> >     then you can do:
>
> >     img := Image new.
> >     img src: aString
>
> >     HTH,
> >     Nico
>
> >     See boot.js for other wrapped JS constructors.
>
> >     > Hello,
> >     > I try to move an html 5 game made with the html canvas tag from
> >     > javascript to Smalltalk with Amber. I found a way to do most
> >     things I
> >     > had in my previous code in javascript but Image management.
>
> >     > Basically, I used to load all the images at the begining of the
> >     game,
> >     > so the user can play freely in real time once everything is
> >     loaded.
> >     > The code looked like :
> >     > var image;
> >     > image = new Image();
> >     > image.src = "images/ground.png";
> >     > image.onload = function(){ if (allImageLoaded) startGame();}
>
> >     > I tried to do this with Amber, but I had some issues. I didn't
> >     find a
> >     > way to do new Image() so I used :
> >     > |image|
> >     > image := <new Image()>.
> >     > image src: images/ground.png".
>
> >     > But I can't find a way to use the onload function. I could use
> >     another
> >     > Image Class made by myself, but I need to display the image
> >     through
> >     > canvas : context2d drawImage: image x: 50 y: 50.
>
> >     > Can you tell me if you know a way to use the onload function ?
> >     Is
> >     > there another way to instantiate image than <new Image()> ?
>
> >     > Thank you very much for your help
>
> >     --
> >     Nicolas Petton
> >    http://nicolas-petton.fr
>
> --
> Nicolas Pettonhttp://nicolas-petton.fr