RealBasic: Canvas tutorial lesson 2

As a base, we’re using our project form lesson 1. We are going to add a background to the ABCanvas and some nice effects on our comic covers.

For the effects, we’re going to build some masks. One for the shadow and one for the glow. One big advantage of using masks is that we can re-use them for all the objects we have. This way, it does not matter if we change the comic cover, they will all have a shadow and a glow.

You can use your favorite paint program to make these, but I’ll use The Paint Shop Pro 6.02. It’s a dinosaur among the painting programs, but it is very simple to use.

As you can see, our shadow mask is about 5 pixels widther and heigher than the cover. We’ll need to take this into acount when we’ll draw the new cover.

The more black a pixel is, the less transparent it will be when we draw it as a mask. So rgb(255, 255, 255) is completely transparent and rgb(0,0,0) is completely solid.

For our glow we want to see the cover fully solid and a white transparent ‘light’ above it.

Let’s start with the code:

We are going to need some new properties to the ABCanvas to hold our new effects:

ComicMask as picture
ComicGlow as picture
Background as picture

In the CleanUp() function we’ll add them also:

Background = nil
ComicMask = nil
ComicGlow = nil

We need to make some changes to our Init() function so we can add our background and our masks. As for the background, make sure you pick a picture that has a high contrast with your objects. This way, your covers will ‘jump’ out of the screen if we apply the effect. I picked a nice green one because my covers are anything but green.

Sub ABCanvas Init(tmpBackGround as picture, tmpComicMask as picture, tmpComicGlow as picture)
  
  me.Background = NewPicture(width,height, 32)
  me.Background.Graphics.DrawPicture tmpBackGround,0,0, width, height, 0,0, tmpBackGround.Width, tmpBackGround.Height
  
  pBuffer = NewPicture(width, height, 32)
  gBuffer = pBuffer.Graphics
  
  ' our shadow
  ComicMask = NewPicture(tmpComicMask.Width, tmpComicMask.Height, 32)
  ComicMask.Graphics.DrawPicture tmpComicMask,0,0
  
  ' our glow
  ComicGlow = NewPicture(tmpComicGlow.Width, tmpComicGlow.Height, 32)
  ComicGlow.Graphics.DrawPicture tmpComicGlow,0,0
End Sub

We must also change our DrawMe() function so that it draws the background on the canvas before we draw the objects. Again, here we prepare our function to be able to redraw only a part of the screen. We’ll need this in a later lesson when w’ll going to drag and drop the albums.

Sub DrawMe(x as integer, y as integer, w as integer, h as integer)
    #pragma disableBackgroundTasks
  
  Dim i,maxi As Integer
  Dim tmpElem As ABElement
  Dim picleft, pictop As Integer
  
  ' Redraw background...
  gBuffer.DrawPicture Background,x,y,w,h, x,y,w,h
  
  ' Redraw the elements which are within the given bounds.
  maxi = UBound(MyElements)
  for i = 0 to maxi
    tmpElem = MyElements(i)
    if tmpElem.Visible then
      picleft = tmpElem.x-tmpElem.w/2
      pictop = tmpElem.y-tmpElem.h/2
      if picleft+tmpElem.w > x and picleft < x+w and pictop+tmpElem.h > y and pictop < y+h then
        gBuffer.DrawPicture tmpElem.pBuffer, picleft, pictop
      end if
      
    end if
  next
  
  ' the actual drawing to the canvas
  self.Graphics.DrawPicture pBuffer,x,y,w,h,x,y,w,h
End Sub

Ok, preparations on the ABCanvas are done. Let’s do some fun things to the ABElement now!

We change the Init(à function so that the width and height of the cover can also hold the shadow:

Sub Init(tmpID as integer, tmpX as integer, tmpY as integer, tmpImage as picture, tmpVisible as boolean)
  me.ID = tmpID
  me.x = tmpX
  me.y = tmpY
  me.Visible = tmpVisible
  me.w = tmpImage.Width
  me.h = tmpImage.Height
  
  Image = NewPicture(w,h, 32)
  image.Graphics.DrawPicture tmpImage,0,0
  
  if MyABCanvas.ComicMask <> nil then
    ' if we have a shadow, we must take the width and height of the mask
    me.w = MyABCanvas.ComicMask.Width
    me.h = MyABCanvas.ComicMask.Height
  end if
  
  pBuffer = NewPicture(w,h, 32)
  gBuffer = pBuffer.Graphics
  
  DrawMe
End Sub

In the DrawMe() function of the ABElement is where the exciting stuff happens. Remember from our previous lesson we do not redraw the picture every time we refresh the canvas. This gives us some more space to do some more time consuming stuff like making shadows and glows.

The trick to do shadows is by combining a mask with a black layer. As for the glow we’ll need to use a white layer, but it’s just a little bit more complicated. We can’t do it directly, we’ll need to make a temporary picture to hold the white transparent layer. Let’s dive into the code:

Sub DrawMe()
  if Image <> nil then
    ' initalize me with my initial Picture + make a new picture so the mask is reset.  As we do this only when the element changes, it's no big drawback
    pBuffer = NewPicture(w,h, 32)
    gBuffer = pBuffer.Graphics
    ' no need to draw the image here anymore, we'll do it later in the glow
    ' gBuffer.DrawPicture image,0,0
    
    ' here we will be able to add whatever drawing code we want
    if MyABCanvas.ComicMask <> nil then
      ' for our shadow, we have to add first a black layer
      gBuffer.ForeColor = &c000000
      gBuffer.FillRect 0,0, w,h
      
      pBuffer.Mask.Graphics.DrawPicture MyABCanvas.ComicMask,0,0
    end if
    if MyABCanvas.ComicGlow <> nil then
      ' for our glow, it's a litte bit more compilicated. The order and Width/Height is very important!
      
      ' we do need a temporary picture
      dim tmpBuildPic as Picture
      
      ' get the width and height of the comic, here it is the same as our ComicGlow and make a new tmpBuildPic
      dim tmpGW as Integer = MyABCanvas.ComicGlow.Width
      dim tmpGH as integer = MyABCanvas.ComicGlow.Height
      tmpBuildPic = newpicture(tmpGW,tmpGH,32)
      
      ' draw our glow on the mask of our tmpBuildPic
      tmpBuildPic.mask.Graphics.DrawPicture MyABCanvas.ComicGlow,0,0
      ' draw our comic cover on the graphics of our tmpBuildPic
      tmpBuildPic.Graphics.DrawPicture Image,0,0
      
      ' prepare our final picture by putting a white layer on top of it
      ' if we don't do this, it will not be a glow but a shadow
      gbuffer.ForeColor = &cFFFFFF
      gbuffer.FillRect 0,0, tmpGW, tmpGH
      
      ' draw our temporary build glow picture on top of it
      gbuffer.DrawPicture tmpBuildPic,0,0
      
    end if
  end if
End Sub

Ready! Now all to do in the program is change our LoadMe() function to use the shadow and glow masks:

  Dim tmpPic2 as Picture
  
  f= GetFolderItem("ComicMask.png")
  tmpPic = f.OpenAsPicture
  f= GetFolderItem("ComicGlow.png")
  tmpPic2 = f.OpenAsPicture
  
  f = GetFolderItem("Background.png")
  ' the new init function
  ABCanvas1.Init(f.OpenAsPicture, tmpPic, tmpPic2)

Let’s run our new program. It should look something like this:

Waw, that look a lot better! So this concludes this lesson. We learned how to make shadows and glows on objects very easy by simply drawing masks. No complicated calcualtions that consume a lot of time but by using this simple trick with masks.

In our next lesson we’ll going to learn how to make this canvas interactive so we can drag and drop our comic covers around with the mouse or touchscreen.

The code for this tutorial can be download from http://www.gorgeousapps.com/Tut2.zip

If you have any questions, don’t hesitate to leave a comment to this lesson. After all, we’re here to learn.

Have fun coding!

Click here to Donation if you like my work

Advertisements

About Alwaysbusy

My name is Alain Bailleul and I'm the Senior Software Architect/Engineer at One-Two. I like to experiment with new technologies, Computer Vision and A.I. My projects are programmed in B4X , Xojo, C#, java, HTML, CSS and JavaScript. View all posts by Alwaysbusy

3 responses to “RealBasic: Canvas tutorial lesson 2

  • andrea antonioni

    Excuse me for my bad english … Good tutorials … very interesting … i don’t know REALBASIC very well, I create windows software for recognize movement and forms… with realbasic you have good velocity for this? Now i use similar product mix project vbnet/(realbasic/purebasic) and i search better solution for this product…
    kinect Example is possible compile to LINUX – WIN – MAC? the driver is only windows o no?
    Thank you very much

  • Alwaysbusy

    Hi Andrea,

    If you try to follow the tutorials on the blog you will see that Realbasic can indeed provide the speed you need. Start from the first tutorial and work your way up, because some important things about speed are mentioned in the early lessons. I’ve created 12Work at OneTwo that is a pure canvas and does some heavy graphics stuff. It performs very well, even at full HD on some older computers (seach for 12work on this blog to see what I mean).

    As for the Kinect: yes this is windows only because I’ll use a Windows driver.

    Good luck with your projects!

    Alwaysbusy

  • chuckthetekkie

    I’m not entirely sure what I am doing wrong but I can’t get the Background Image or element pictures to show for some reason. I got it to work in another part of my project but not where I currently working.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: