Android Tutorial [B4X] [XUI] Drawing with B4XCanvas

Status
Not open for further replies.

Erel

Administrator
Staff member
Licensed User
B4XCanvas is the cross platform version of Canvas.

Steps to using B4XCanvas:

1. Initialize and pass the target view. In most cases it will be a Panel (or Pane). It must be a Pane in B4J.
2. Make the drawings.
3. Call Invalidate to commit the drawings.
4. If the target view is resized then you should call B4XCanvas.Resize. This is more relevant in B4J and B4i as the activity is recreated in B4A when the screen size changes.
5. B4XCanvas.CreateBitmap returns the drawings bitmap.
6. Call B4XCanvas.Release if the canvas is no longer required.

Example of a bouncing smiley:



B4X:
Sub Process_Globals
   Private Timer1 As Timer
End Sub

Sub Globals
   Private xui As XUI
   Private smiley As B4XBitmap
   Private deg, vx = 10dip, vy = 10dip As Double
   Private SmileyRect As B4XRect
   Private size As Double = 40dip
   Private Panel1 As B4XView
   Private cvs As B4XCanvas

End Sub

Sub Activity_Create(FirstTime As Boolean)
   Activity.LoadLayout("1")
   Create
End Sub

'*** code is identical from here ***
Sub Resize 'ignore
   cvs.Resize(Panel1.Width, Panel1.Height)
   cvs.ClearRect(cvs.TargetRect)
   cvs.Invalidate
End Sub

Sub Create
   smiley = xui.LoadBitmapResize(File.DirAssets, "smiley.png", size, size, False)
   If xui.IsB4J Then
     vx = 7dip
     vy = 7dip
   Else
     vx = 10dip
     vy = 10dip
   End If
   Timer1.Initialize("Timer1", 10)
   Timer1.Enabled = True
   SmileyRect.Initialize(10dip, 10dip, 10dip + size, 10dip + size)
   cvs.Initialize(Panel1)
End Sub

Sub Timer1_Tick
   cvs.ClearRect(cvs.TargetRect)
   If SmileyRect.Right > cvs.TargetRect.Width Then
     vx = -Abs(vx)
   Else If SmileyRect.Left < 0 Then
     vx = Abs(vx)
   End If
   If SmileyRect.Bottom > cvs.TargetRect.Height Then
     vy = -Abs(vy)
   Else If SmileyRect.Top < 0 Then
     vy = Abs(vy)
   End If
   SmileyRect.Left = SmileyRect.Left + vx
   SmileyRect.Top = SmileyRect.Top + vy
   SmileyRect.Width = size
   SmileyRect.Height = size
   deg = deg + 1
   cvs.DrawBitmapRotated(smiley, SmileyRect, deg)
   cvs.Invalidate
End Sub
Another example: [B4X] [XUI] Create a round image
 

Attachments

Last edited:

trisium

Member
Licensed User
At the moment I am still trying to understand the differences between pane, panel, canvas etc.
One question would be: B4XCanvas has no Visible property - why? And what could a workaround look like?
Thanks for any help!!
 

klaus

Expert
Licensed User
In B4X XUI, a Canvas must be linked to a Panel (B4A, B4i) or a Pane (B4J) with the B4XCanvas1.Initialize method.
You may need to call B4XCanvas1.Invalidate to make the drawing active.
This is different from B4A and B4i where you need to Invalidate the Panel.
You may have a look at the B4X Graphics and B4X XUI booklets.
 

Erel

Administrator
Staff member
Licensed User
In B4X XUI, a Canvas must be linked to a Panel (B4A, B4i) or a Pane (B4J) with the B4XCanvas1.Initialize method.
You may need to call B4XCanvas1.Invalidate to make the drawing active.
This is different from B4A and B4i where you need to Invalidate the Panel.
Note that these differences can be ignored.
1. You should use B4XView with XUI.CreatePanel or a Pane(l) created with the designer.
2. You should call B4XCanvas.Invalidate when you are done drawing.
 
Last edited:

saeed10051

Active Member
Licensed User
Hi All
thanks for the reply
however i am missing one point here, the examples given here refer to drawing something programatically and displaying it on the canvas. I want to draw by dragging my figer on the screen. how to capture that event. When i see the code by Erel in B4J (as given in my origianl question) he has used the mouse drag to draw something, how to capture that event while working with B4A , as here we do not have a mouse we just drag our finger on the screen.
 

klaus

Expert
Licensed User
You should use a Panel and it's Touch event.
There you get the X and Y coordinates in Action_DOWN, Action_MOVE and Action_UP.
With these events you can do what ever you want.
You can use either an Android Canvas or a B4XView with a B4XVanvas.
 

saeed10051

Active Member
Licensed User
Thanks Klaus,
this one is really working as i wanted it to be, i have made a small change in the following code to show the drawing as small circles. Now the only thing left is how to clear the , panel after drawing. I have experimented with various method in panel but it is not refreshing the panel, so that another drawing can be done

Select Action
Case pnlGraph.TOUCH_ACTION_DOWN
x0 = X
y0 = Y
Case pnlGraph.TOUCH_ACTION_MOVE
x1 = X
y1 = y
cvsGraph.DrawCircle(x1, y1, 15dip, xui.Color_ARGB(Rnd(1,255),Rnd(1,255),Rnd(1,255),Rnd(1,255)), True, 0)
cvsGraph.Invalidate
x0 = x1
y0 = y1
Case pnlGraph.TOUCH_ACTION_Up
End Select
 

klaus

Expert
Licensed User
There is no need to post in both threads.

Use
cvsGraph.ClearRect(cvsGraph.TargetRect)
Sets the background to transparent.

Or
cvsGraph.DrawRect(cvsGraph.TargetRect, xui.Color_White, True, 1)
Sets the given background color.
 

saeed10051

Active Member
Licensed User
Thanks Klaus
the cvsGraph.DrawRect(cvsGraph.TargetRect, xui.Color_White, True, 1)
is working fine
Posting on both the threads was by mistake.
 
Status
Not open for further replies.
Top