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 |
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, |
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 |
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 |
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 |
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 |
I tried to add something like #new to JSObjectProxy, but it didn't 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' |
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 |
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: |
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:
|
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 |
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 |
Free forum by Nabble | Edit this page |