New topic: Canvas.Mousedrag too slow?
<http://forums.realsoftware.com/viewtopic.php?t=46558> Page 1 of 1 [ 9 posts ] Previous topic | Next topic Author Message alexvs Post subject: Canvas.Mousedrag too slow?Posted: Mon Jan 14, 2013 11:52 am Joined: Fri Feb 12, 2010 1:32 pm Posts: 219 Location: Switzerland Hey there To try something for another project I quickly came up with a canvas that mimiks a chalkboard. In the mousedown/-drag events I record the mouse position, call the canvas to refresh and return true. In the respective paint event I then draw the recorded points. Basically everything works fine except that it's to slow. Instead of a line it paints single points when moving the mouse at normal speed. Only when moving slowly, a line is being drawn (see example screenshot below). My guess is that the mousedrag event is called too infrequently - or what might be the issue in your opinion? Thanks, Alex Last edited by alexvs on Mon Jan 14, 2013 12:03 pm, edited 1 time in total. Top DaveS Post subject: Re: Canvas toh slow?Posted: Mon Jan 14, 2013 12:02 pm Joined: Sun Aug 05, 2007 10:46 am Posts: 4412 Location: San Diego, CA A lot has to do with exactly how you are implementing this.... I have a drawing program that works just fine...... except when you move the mouse at super-speed. but for normal to quick drawing activities it produces a nice line. It has to do with how are you keeping track of the mouse points? are you calling REFRESH or INVALIDATE? And no matter what... your best bet is to connect the dots..... because it will be near impossible to catch a single pixel movement, store the data and redraw the screen . Of course you can get really fancy, and apply a Bezier function to your points and get a mathematically smoothed line as well. _________________ Dave Sisemore MacPro, OSX Lion 10.7.4 RB2012r1 Note : I am not interested in any solutions that involve custom Plug-ins of any kind Top alexvs Post subject: Re: Canvas toh slow?Posted: Mon Jan 14, 2013 12:11 pm Joined: Fri Feb 12, 2010 1:32 pm Posts: 219 Location: Switzerland Thanks for your reply, Dave. DaveS wrote:It has to do with how are you keeping track of the mouse points? are you calling REFRESH or INVALIDATE? I went for invalidate, however I also tried refresh with no difference. For keeping track of the dots I have a very simple class ("stroke") that has an array with the dots (of type Realbasic.Point), since I want to be able to keep track of the single strokes the user does. In the mousedown event I create an instance of that class, add the first point, call invalidate and return true: Function MouseDown(X As Integer, Y As Integer) As Boolean dim s as new stroke s.StrokeColor = ForegroundColor s.LineThickness = LineThinkness s.AddPoint(x,y) History.append s me.invalidate return true End Function In the mousedrag event I pick up the latest instance in the array and add the point handed over by the event and do the same again: Sub MouseDrag(X As Integer, Y As Integer) dim s as stroke s = history(history.Ubound) s.AddPoint(x,y) me.Invalidate End Sub In the paint event, I then loop through the points and draw them: Sub Paint(g As Graphics, areas() As REALbasic.Rect) //paint Background g.ForeColor = me.BackgroundColor g.FillRect 0,0,me.Width,me.Height //paint the points in the history array for i as integer = 0 to history.Ubound dim s as stroke = history(i) g.ForeColor = s.StrokeColor for j as integer = 0 to s.PointCount-1 dim p as realbasic.point = s.Point(j) g.FillOval p.X,p.y,s.LineThickness,s.LineThickness next next End Sub Some methods and properties refer to the Stroke and or my custom Canvas class. DaveS wrote: And no matter what... your best bet is to connect the dots..... because it will be near impossible to catch a single pixel movement, store the data and redraw the screen . Of course you can get really fancy, and apply a Bezier function to your points and get a mathematically smoothed line as well. Well, in the screenshot attached above, I moved the mouse quite slowly. Moving it at normal speed results in even bigger gaps. I do consider connecting the dots, however I think the dots need to be closer to each other first. Otherwise the results won't be very satisfying. How are you doing this in your paint app? Thanks, Alex Edit: The "Stroke" class: Class Stroke Stroke.AddPoint: Sub AddPoint(x as integer, y as integer) points.append new REALbasic.Point(x, y) End Sub Stroke.LastPoint: Function LastPoint() As REALbasic.Point return Points(Points.Ubound) End Function Stroke.Point: Function Point(index as integer) As REALbasic.Point return Points(index) End Function Stroke.PointCount: Function PointCount() As integer return Points.Ubound+1 End Function Properties: LineThickness As Integer = 5 Points() As REALbasic.Point StrokeColor As Color = &cFFFFFF End Class Top doofus Post subject: Re: Canvas toh slow?Posted: Mon Jan 14, 2013 1:19 pm Joined: Thu Sep 10, 2009 2:50 am Posts: 335 Location: Santa Cruz, CA, USA alexvs wrote:I went for invalidate, however I also tried refresh with no difference. me.invalidate In the paint event, I then loop through the points and draw them: You're redrawing the entire canvas every time, instead only repaint the necessary region using invalidate(x,y,w,h) or refreshRect. You should only be drawing the latest dot. I think this may need a buffer picture or the backdrop may work. Top kermit Post subject: Re: Canvas.Mousedrag too slow?Posted: Mon Jan 14, 2013 2:04 pm Joined: Mon May 30, 2011 12:56 am Posts: 590 consider adding a Group2D object to the visible graphic. Instead of adding points to your list, .append curve shapes (probably just straight lines) to the group. (These lines start at previousx,previousy and end at x,y ) The group will redraw itself automatically when the picture is refreshed. You dont need to iterate through the points array every time, and you dont need to explicitly draw the dots. Using lines means you get no gaps, but feel free to add dots instead if you like Top timhare Post subject: Re: Canvas.Mousedrag too slow?Posted: Mon Jan 14, 2013 6:04 pm Joined: Fri Jan 06, 2006 3:21 pm Posts: 11982 Location: Portland, OR USA Use a buffer picture. Your Paint event is doing way too much work and slowing you down. Top npalardy Post subject: Re: Canvas.Mousedrag too slow?Posted: Mon Jan 14, 2013 6:21 pm Real Software Engineer Joined: Sat Dec 24, 2005 8:18 pm Posts: 7674 Location: Canada, Alberta, Near Red Deer alexvs wrote:Hey there To try something for another project I quickly came up with a canvas that mimiks a chalkboard. In the mousedown/-drag events I record the mouse position, call the canvas to refresh and return true. In the respective paint event I then draw the recorded points. Basically everything works fine except that it's to slow. Instead of a line it paints single points when moving the mouse at normal speed. Only when moving slowly, a line is being drawn (see example screenshot below). My guess is that the mousedrag event is called too infrequently - or what might be the issue in your opinion? Thanks, Alex 1) just have the code update some internal class that represents the item being drawn as long as the mouse stays down (so just have "line" class that has a start & end points & update the end point based on the current position) 2) invalidate instead of refresh 3) in the pain redraw the line based on the start & end points _________________ My web site Great White Software RBLibrary.com REALbasic learning Top alexvs Post subject: Re: Canvas toh slow?Posted: Tue Jan 15, 2013 5:19 am Joined: Fri Feb 12, 2010 1:32 pm Posts: 219 Location: Switzerland Guys, you're awesome. I'm overwhelmed by the number of replies and the support I get in these forums. Let me go through your answers post by post: doofus wrote:You're redrawing the entire canvas every time, instead only repaint the necessary region using invalidate(x,y,w,h) or refreshRect. You should only be drawing the latest dot. I think this may need a buffer picture or the backdrop may work. timhare wrote:Use a buffer picture. Your Paint event is doing way too much work and slowing you down. I added a buffer and things got waaay better, though still gaps exist. I also went for invalidate(x,y,w,h), which makes sense. However, in the paint event, the areas() parameter always seems to be empty, thus requiring repainting of the whole graphics. How comes? I'd rather just repaint what needs to be repainted. npalardy wrote:1) just have the code update some internal class that represents the item being drawn as long as the mouse stays down (so just have "line" class that has a start & end points & update the end point based on the current position) 2) invalidate instead of refresh 3) in the pain redraw the line based on the start & end points 1) But with lines - I'd get straight lines only, nothing like shown in my screenshot. Maybe I do misunderstand you? 2) Already doing 3) see 1) kermit wrote:consider adding a Group2D object to the visible graphic. Instead of adding points to your list, .append curve shapes (probably just straight lines) to the group. (These lines start at previousx,previousy and end at x,y ) The group will redraw itself automatically when the picture is refreshed. You dont need to iterate through the points array every time, and you dont need to explicitly draw the dots. Using lines means you get no gaps, but feel free to add dots instead if you like That seems like an interesting approach, will give it a try! Alex Top alexvs Post subject: Re: Canvas.Mousedrag too slow?Posted: Tue Jan 15, 2013 5:43 am Joined: Fri Feb 12, 2010 1:32 pm Posts: 219 Location: Switzerland Painting a line between the dots made it pretty perfect. The only thing I don't like so far (I'm an esthete...) is that I don't get rounded corners at the start and the end of a stroke which I initially planned by using the oval shape for the points. But that's peanuts Top Display posts from previous: All posts1 day7 days2 weeks1 month3 months6 months1 year Sort by AuthorPost timeSubject AscendingDescending Page 1 of 1 [ 9 posts ] -- Over 1500 classes with 29000 functions in one REALbasic plug-in collection. The Monkeybread Software Realbasic Plugin v9.3. http://www.monkeybreadsoftware.de/realbasic/plugins.shtml [email protected]
