Is it possible to create canvas larger than screen size?

ozgureffe

Member
Licensed User
Longtime User
Hi,
Is it possible to create canvas larger than screen size?

I am trying to create a scrollable canvas with larger size than the screen size? But when i scroll it some strange things happen...
 

Attachments

  • ScrollableCanvas.zip
    13.9 KB · Views: 357

Erel

B4X founder
Staff member
Licensed User
Longtime User
It is recommended to also post the code if it is not too long.
B4X:
Sub Globals
    Dim notePanel As Panel
    Dim Phone As Phone
    Dim btn_resizeAndSlidePanel As Button
    Dim Timer1 As Timer
    Dim btn_reset As Button
    Dim r As Int
    Dim Bitmap1 As Bitmap
    Dim argb() As Int
    Dim Canvas1 As Canvas
    Dim btn_save As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)
       Timer1.Initialize("Timer1", 10)
    Phone.SetScreenOrientation(0)
    Activity.LoadLayout("Main")
    notePanel.Width = 100%x
    Activity.LoadLayout("main")
    Canvas1.Initialize(notePanel) 'Initialize the canvas (drawer) and makes it draw on the activity (form).
    Bitmap1.Initialize3(Canvas1.Bitmap)
End Sub

Sub Activity_Touch(Action As Int, tx As Float, ty As Float)
    Canvas1.DrawCircle(tx, ty, 5dip, Colors.ARGB(50,255,255,255), True, 1dip)
    Canvas1.DrawCircle(tx, ty, 4dip, Colors.ARGB(50,255,255,255), True, 1dip)
    Canvas1.DrawCircle(tx, ty, 3dip, Colors.ARGB(50,255,255,255), True, 1dip)
    Canvas1.DrawCircle(tx, ty, 2dip, Colors.ARGB(50,255,255,255), True, 1dip)
    Canvas1.DrawCircle(tx, ty, 1dip, Colors.ARGB(50,255,255,255), True, 1dip)
    Activity.Invalidate3(tx - 7dip, ty - 7dip, tx + 7dip, ty + 7dip)
End Sub

Sub btn_resizeAndSlidePanel_Click
    notePanel.Width = notePanel.Width + 100%x
    Timer1.Enabled = True
    r = 0
End Sub

Sub btn_reset_Click
    notePanel.Width = 100%x
    notePanel.Left = 0
    Timer1.Enabled = False
End Sub

Sub Timer1_Tick
    notePanel.Left = notePanel.Left - 10%x
    r = r + 1
    If r>7 Then Timer1.Enabled = False
End Sub

Sub btn_save_Click
    Dim Out As OutputStream
    Bitmap1.Initialize3(Canvas1.Bitmap)
    Out = File.OpenOutput(File.DirRootExternal, "Test.png", False)
    Bitmap1.WriteToStream(out, 100, "PNG")
    Out.Close
End Sub

- It should be possible to use a canvas with a bitmap larger than the screen size. You shouldn't however change the panel width after creating the canvas.
- You should invalidate the panel not the activity as you are drawing on the panel.
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
Here you are, with a Panel even 3 times the screen size.
You need to set the Panel with to the width you want.
I added the drawing of a line between the points, your request in this thread How to draw on screen with finger.

B4X:
Sub Globals
  Dim notePanel As Panel
  Dim Phone As Phone
  Dim btn_SlidePanelLeft, btn_SlidePanelRight As Button
  Dim Timer1 As Timer
  Dim btn_reset As Button
  Dim r As Int
  Dim Bitmap1 As Bitmap
  Dim argb() As Int
  Dim Canvas1 As Canvas
  Dim btn_save As Button
 
  Dim x1, y1, x2, y2 As Float
  Dim MoveStep As Float
'  Dim LineColor As Int   : LineColor = Colors.ARGB(50,255,255,255)
  Dim LineColor As Int   : LineColor = Colors.RGB(128,128,128)
  Dim ImageWidth As Float  : ImageWidth = 300%x
  Dim MinLeftValue As Float
End Sub
 
Sub Activity_Create(FirstTime As Boolean)
  Timer1.Initialize("Timer1", 10)
  Phone.SetScreenOrientation(0)
  Activity.LoadLayout("Main")
  notePanel.Width = ImageWidth
  MinLeftValue = ImageWidth -Activity.Width
  notePanel.Left = 0
  Canvas1.Initialize(notePanel) 'Initialize the canvas (drawer) and makes it draw on the activity (form).
  Bitmap1.Initialize3(Canvas1.Bitmap)
End Sub
 
Sub Activity_Touch(Action As Int, tx As Float, ty As Float)
  Select Action
  Case Activity.ACTION_DOWN
    x1 = tx - notePanel.Left
    y1 = ty
    Canvas1.DrawCircle(x1, y1, 5dip, LineColor, True, 1dip)
    notePanel.Invalidate3(x1 - 7dip, y1 - 7dip, x1 + 7dip, y1 + 7dip)
 Case Activity.ACTION_MOVE
    x2 = tx - notePanel.Left
    y2 = ty
    Canvas1.DrawLine(x1, y1, x2, y2, LineColor, 10dip)
    Canvas1.DrawCircle(x2, y2, 5dip, LineColor, True, 1dip)
    notePanel.Invalidate3(Min(x1, x2) - 7dip, Min(y1, y2) - 7dip, Max(x1, x2) + 7dip ,Max(y1, y2) + 7dip)
    x1 = x2
    y1 = y2
  Case Activity.ACTION_UP
  End Select
End Sub
 
Sub btn_SlidePanel_Click
  Dim Send As Button
 
  Send = Sender
  If Send.Tag = "-" Then
    MoveStep = 10%x
  Else
    MoveStep = -10%x
  End If
  Timer1.Enabled = True
  r = 0
End Sub
 
Sub btn_reset_Click
  notePanel.Left = 0
  Timer1.Enabled = False
End Sub
 
Sub Timer1_Tick
  notePanel.Left = notePanel.Left + MoveStep
 
  If notePanel.Left < - MinLeftValue Then
    notePanel.Left = - MinLeftValue
  End If
  If notePanel.Left > 0 Then
    notePanel.Left = 0
  End If
 
  r = r + 1
  If r>4 Then Timer1.Enabled = False
End Sub
 
Sub btn_save_Click
  Dim Out As OutputStream
  Bitmap1.Initialize3(Canvas1.Bitmap)
  Out = File.OpenOutput(File.DirRootExternal, "Test.png", False)
  Bitmap1.WriteToStream(out, 100, "PNG")
  Out.Close
End Sub
Best regards.
 

Attachments

  • ScrollableCanvas1.zip
    14.2 KB · Views: 464
Upvote 0

ozgureffe

Member
Licensed User
Longtime User
Thank you, thank you, thank you so much magician!
Now it is working like a charm :)
 
Upvote 0

varayut

Member
Licensed User
Longtime User
Canvas is the object that draws. So a canvas cannot be scrolled. You can use ScrollView and draw on its inner panel to have a scrollable drawing layer.

I 'd tried to put panel in scrollview like this but no result
B4X:
Sub Globals
Dim scroll1 As ScrollView
Dim panel1 As Panel
Dim canvas1 As Canvas
Dim xc, yc, x1, y1, x2, y2, r1, r2, h, w As Float
End Sub

Sub Activity_Create(FirstTime As Boolean)

If FirstTime Then

x1 = 0.5%x
y1 = 100%y - 55dip
y2 = 100%y - 102dip
w = 20%x
h = 50dip

scroll1.Initialize(100dip)
panel1.Initialize("panel1")
textbox.Initialize("text1")
panel1.Color = Colors.LightGray

Activity.AddView(scroll1, 0, 0, 100%x, 75%y)
Activity.AddView(panel1, 0, 0, 100%x, 75%y)

canvas1.Initialize(panel1)
panel1.Initialize(scroll1)
Scroll1.Panel.Height = 200dip
Scroll1.Panel.Width = 200dip
Scroll1.Panel.AddView(panel1, 5dip, 5dip * 200dip, Scroll1.Width - 10dip, 190dip)

Activity.AddView(btn1, x1, y2, w, h)
Activity.AddView(btn2, x1, y1, w, h)
Activity.AddView(textbox,0,80%x,50%x,40dip)


End If
End Sub

Sub Activity_Resume
  Drawing
End Sub

Sub Activity_Pause (UserClosed As Boolean)
  Drawing
End Sub

Sub Drawing
Activity.Invalidate
canvas1.DrawColor(Colors.White)

x1 = 100dip
y1 = 10dip
x2 = 150dip
y2 = 20dip
canvas1.DrawLine(x1, y1, x2, y2, Colors.Red, 0)

xc = 90dip
yc = 130dip
r1 = 70dip
canvas1.DrawCircle(xc, yc, r1, Colors.Green, False, 2dip)
canvas1.DrawText("Hello", x1, y1, Typeface.DEFAULT, 16, Colors.Red, "RIGHT")

Sub panel1_Touch (Action As Int, X As Float, Y As Float)

End Sub
Sub scroll1_Touch (Action As Int, X As Float, Y As Float)

End Sub
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
You should not set the inner panel width and height. See this example: ScrollView example

There are several problems in your code.
You should only use FirstTime to initialize non-UI variables. Otherwise your layout will not be loaded after the user rotates the screen or after the user comes back to your application.


The following code creates a scrollview and adds a panel which you can draw on:
B4X:
Sub Globals
   Dim sv As ScrollView
   Dim canvas1 As Canvas
   Dim panel1 As Panel
End Sub

Sub Activity_Create(FirstTime As Boolean)
   sv.Initialize(1000dip)
   Activity.AddView(sv, 10dip, 10dip, 300dip, 300dip)
   panel1.Initialize("")
   sv.Panel.AddView(panel1, 0, 0, sv.Width, 1000dip)
   canvas1.Initialize(panel1)
   canvas1.DrawColor(Colors.Yellow)
End Sub
 
Upvote 0
Top