Just like ordinary Delphi, Javascript has it’s own canvas object. As you can imagine the canvas of the browser is quite different from the good old Delphi TCanvas, but not so alien that it doesn’t have it’s similarities. But you will need to brush up on the documentation from Apple in order to use it.
But HTML5 also have something else up it’s sleeve, namely that you can create off-screen bitmaps (wrapped in the TW3ImageData class from w3graphics.pas). The difference between a Delphi bitmap and a HTML5 bitmap is 3 fold:
- The bitmap is obtained from the canvas, not the other way around (Delphi’s TBimap has a canvas property)
- Off-screen bitmaps do not have a canvas, they are in reality DIBS (device independent bitmaps)
- Off-screen bitmaps are 32bit exclusively (RGBA, 8888 format).
This is actually good news because it means we can create games and multimedia dealing with pixel data rather than the (excuse me) somewhat cumbersome canvas object. Most javascript developers actually avoid this part because they are used to “high level” coding only – but coders coming from the Delphi community have been knocking out low level graphics libraries for ages. So if you have ever played around with DIBS (device independent bitmaps) in Delphi – you should feel right at home.
Here is a quick example of how to plot some pixels off-screen, and copy the results onto the screen (note: this is a game project):
[sourcecode language=”delphi”]
unit Project8;
interface
uses w3system, w3components, w3application,
w3game, w3gameapp, w3graphics, w3components;
type
TApplication=class(TW3CustomGameApplication)
private
{ Private methods }
FBuffer: TW3ImageData;
protected
{ protected methods }
procedure ApplicationStarting;override;
procedure ApplicationClosing;override;
Procedure PaintView(Canvas:TW3Canvas);override;
end;
Implementation
//############################################################################
// TApplication
//############################################################################
procedure TApplication.ApplicationStarting;
Begin
inherited;
//Initialize refresh interval, set this to 1 for optimal speed
GameView.Delay:=20;
(* Create a our "offscreen bitmap" *)
FBuffer:=GameView.Canvas.CreateImageData(32,32);
//Start the redraw-cycle with framecounter active
//Note: the framecounter impacts rendering speed. Disable
//the framerate for maximum speed (false)
GameView.StartSession(true);
End;
procedure TApplication.ApplicationClosing;
Begin
GameView.EndSession;
inherited;
End;
// Note: In a real live game you would try to cache as much
// info as you can. Typical tricks are:
// 1: Only get the width/height when resized
// 2: Pre-calculate strings, especially RGB/RGBA values
// 3: Only redraw what has changed, avoid a full repaint
// The code below is just to get you started
procedure TApplication.PaintView(Canvas:TW3Canvas);
Begin
// Clear background
canvas.fillstyle:=’rgb(0,0,99)’;
canvas.fillrectF(0,0,gameview.width,gameview.height);
// Draw our framerate on the screen
canvas.font:=’10pt verdana’;
canvas.FillStyle:=’rgb(255,255,255)’;
canvas.FillTextF(‘FPS:’ + IntToStr(GameView.FrameRate),10,20,MAXINT);
// plot some pixels
if FBuffer<>NIL then
Begin
FBuffer.setPixelC(0,2,clGreen);
FBuffer.setPixelC(1,2,clGreen);
FBuffer.setPixelC(2,2,clGreen);
FBuffer.setPixelC(0,4,clRed);
FBuffer.setPixelC(1,4,clRed);
FBuffer.setPixelC(2,4,clRed);
// paste graphics to display
Canvas.putImageData(FBuffer,20,20);
end;
End;
end.
[/sourcecode]
The result may not look so impressive right now, but it’s the foundation for what will become a very impressive browser based graphics system:
In the future we are going to add a lot more functionality to the TW3ImageData class. Things like line, ellipse, fillrect, circle and flood-fill is already prototyped. But if you feel like playing around with pixels – this is a good start.
Open the file w3graphics.pas and have a look at the methods and properties of TW3ImageData for more information. Also check out this excellent canvas tutorial by Mark Pilgrim.