canvas - Android translate MotionEvent coordinates when drawing -


hello try make drawing after user zooms view , have issue. ive got zoomview (custom view) contains subview imageview image (custom view), zoomview working good, im able zoom/pan/drag , imageview (custom) responds gesture, when try draw on imageview after zoomed/dragged/panned zoomview drawn on touch gets little messed.

enter image description here

first top line drawn when zoomview not zoomed, line looks good. second line drawn when zoomview @ middle zoom. third drawn @ full zoom.

the issue when zoomed , touching finger, line draws faster normal, , cant line, add other line in case (second line: line going top , , third line: line going bottom) while try draw line.

im asking help: how can translate touch point zoomview when zoomed imageview touch points draw canvas.

here classes:

public class ownzoom extends framelayout {  /**  * zooming view listener interface.  *   * @author karooolek  *   */ public interface ownzoomlistener {      void onzoomstarted(float zoom, float zoomx, float zoomy);      void onzooming(float zoom, float zoomx, float zoomy);      void onzoomended(float zoom, float zoomx, float zoomy); } boolean modedown=false; // zooming float zoom = 1.0f; float maxzoom = 2.0f; float smoothzoom = 1.0f; float zoomx, zoomy; float smoothzoomx, smoothzoomy; private boolean scrolling; // nopmd karooolek on 29.06.11 11:45  // minimap variables private boolean showminimap = false; private int minimapcolor = color.black; private int minimapheight = -1; private string minimapcaption; private float minimapcaptionsize = 10.0f; private int minimapcaptioncolor = color.white;  // touching variables private long lasttaptime; private float touchstartx, touchstarty; private float touchlastx, touchlasty; private float startd; private boolean pinching; private float lastd; private float lastdx1, lastdy1; private float lastdx2, lastdy2;  // drawing private final matrix m = new matrix(); private final paint p = new paint();  // listener ownzoomlistener listener;  private bitmap ch;      public void setzommmode(boolean zoomed){         this.modedown=zoomed;     } public ownzoom(final context context) {     super(context); }  public float getzoom() {     return zoom; }  public float getmaxzoom() {     return maxzoom; }  public void setmaxzoom(final float maxzoom) {     if (maxzoom < 1.0f) {         return;     }      this.maxzoom = maxzoom; }  public void setminimapenabled(final boolean showminimap) {     this.showminimap = showminimap; }  public boolean isminimapenabled() {     return showminimap; }  public void setminimapheight(final int minimapheight) {     if (minimapheight < 0) {         return;     }     this.minimapheight = minimapheight; }  public int getminimapheight() {     return minimapheight; }  public void setminimapcolor(final int color) {     minimapcolor = color; }  public int getminimapcolor() {     return minimapcolor; }  public string getminimapcaption() {     return minimapcaption; }  public void setminimapcaption(final string minimapcaption) {     this.minimapcaption = minimapcaption; }  public float getminimapcaptionsize() {     return minimapcaptionsize; }  public void setminimapcaptionsize(final float size) {     minimapcaptionsize = size; }  public int getminimapcaptioncolor() {     return minimapcaptioncolor; }  public void setminimapcaptioncolor(final int color) {     minimapcaptioncolor = color; }  public void zoomto(final float zoom, final float x, final float y) {     this.zoom = math.min(zoom, maxzoom);     zoomx = x;     zoomy = y;     smoothzoomto(this.zoom, x, y); }  public void smoothzoomto(final float zoom, final float x, final float y) {     smoothzoom = clamp(1.0f, zoom, maxzoom);     smoothzoomx = x;     smoothzoomy = y;     if (listener != null) {         listener.onzoomstarted(smoothzoom, x, y);     } }  public ownzoomlistener getlistener() {     return listener; }  public void setlistner(final ownzoomlistener listener) {     this.listener = listener; }  public float getzoomfocusx() {     return zoomx * zoom; }  public float getzoomfocusy() {     return zoomy * zoom; }  @override public boolean dispatchtouchevent(final motionevent ev) {     // single touch     if (ev.getpointercount() == 1) {         processsingletouchevent(ev);     }      // // double touch     if (ev.getpointercount() == 2) {         processdoubletouchevent(ev);     }      // redraw     getrootview().invalidate();     invalidate();      return true; }  private void processsingletouchevent(final motionevent ev) {     //if(!modedown){     final float x = ev.getx();     final float y = ev.gety();      final float w = minimapheight * (float) getwidth() / getheight();     final float h = minimapheight;     final boolean touchingminimap = x >= 10.0f && x <= 10.0f + w && y >= 10.0f && y <= 10.0f + h;      if (showminimap && smoothzoom > 1.0f && touchingminimap) {         processsingletouchonminimap(ev);     } else {         processsingletouchoutsideminimap(ev);     }     //}else if(modedown){     //  log.i("moded own ", "is false");    // } }  private void processsingletouchonminimap(final motionevent ev) {     final float x = ev.getx();     final float y = ev.gety();      final float w = minimapheight * (float) getwidth() / getheight();     final float h = minimapheight;     final float zx = (x - 10.0f) / w * getwidth();     final float zy = (y - 10.0f) / h * getheight();     smoothzoomto(smoothzoom, zx, zy); }  private void processsingletouchoutsideminimap(final motionevent ev) {     final float x = ev.getx();     final float y = ev.gety();     float lx = x - touchstartx;     float ly = y - touchstarty;     final float l = (float) math.hypot(lx, ly);     float dx = x - touchlastx;     float dy = y - touchlasty;     touchlastx = x;     touchlasty = y;      switch (ev.getaction()) {     case motionevent.action_down:         touchstartx = x;         touchstarty = y;         touchlastx = x;         touchlasty = y;         dx = 0;         dy = 0;         lx = 0;         ly = 0;         scrolling = false;         break;      case motionevent.action_move:         if(modedown){         if (scrolling || (smoothzoom > 1.0f && l > 30.0f)) {             if (!scrolling) {                 scrolling = true;                 ev.setaction(motionevent.action_cancel);                 super.dispatchtouchevent(ev);             }             smoothzoomx -= dx / zoom;             smoothzoomy -= dy / zoom;             return;         }         }else if(!modedown){             ev.setaction(motionevent.action_move);             super.dispatchtouchevent(ev);             return;         }           break;      case motionevent.action_outside:     case motionevent.action_up:          // tap         if (l < 30.0f) {             // check double tap             if (system.currenttimemillis() - lasttaptime < 500) {                 if (smoothzoom == 1.0f) {                     smoothzoomto(maxzoom, x, y);                 } else {                     smoothzoomto(1.0f, getwidth() / 2.0f, getheight() / 2.0f);                 }                 lasttaptime = 0;                 ev.setaction(motionevent.action_cancel);                 super.dispatchtouchevent(ev);                 return;             }              lasttaptime = system.currenttimemillis();              performclick();         }         break;      default:         break;     }      ev.setlocation(zoomx + (x - 0.5f * getwidth()) / zoom, zoomy + (y - 0.5f * getheight()) / zoom);      ev.getx();     ev.gety();      super.dispatchtouchevent(ev); }  private void processdoubletouchevent(final motionevent ev) {     final float x1 = ev.getx(0);     final float dx1 = x1 - lastdx1;     lastdx1 = x1;     final float y1 = ev.gety(0);     final float dy1 = y1 - lastdy1;     lastdy1 = y1;     final float x2 = ev.getx(1);     final float dx2 = x2 - lastdx2;     lastdx2 = x2;     final float y2 = ev.gety(1);     final float dy2 = y2 - lastdy2;     lastdy2 = y2;      // pointers distance     final float d = (float) math.hypot(x2 - x1, y2 - y1);     final float dd = d - lastd;     lastd = d;     final float ld = math.abs(d - startd);      math.atan2(y2 - y1, x2 - x1);     switch (ev.getaction()) {     case motionevent.action_down:         startd = d;         pinching = false;         break;      case motionevent.action_move:         if (pinching || ld > 30.0f) {             pinching = true;             final float dxk = 0.5f * (dx1 + dx2);             final float dyk = 0.5f * (dy1 + dy2);             smoothzoomto(math.max(1.0f, zoom * d / (d - dd)), zoomx - dxk / zoom, zoomy - dyk / zoom);         }          break;      case motionevent.action_up:     default:         pinching = false;         break;     }      ev.setaction(motionevent.action_cancel);     super.dispatchtouchevent(ev); }  private float clamp(final float min, final float value, final float max) {     return math.max(min, math.min(value, max)); }  private float lerp(final float a, final float b, final float k) {     return + (b - a) * k; }  private float bias(final float a, final float b, final float k) {     return math.abs(b - a) >= k ? + k * math.signum(b - a) : b; }  @override protected void dispatchdraw(final canvas canvas) {     // zoom     zoom = lerp(bias(zoom, smoothzoom, 0.05f), smoothzoom, 0.2f);     smoothzoomx = clamp(0.5f * getwidth() / smoothzoom, smoothzoomx, getwidth() - 0.5f * getwidth() / smoothzoom);     smoothzoomy = clamp(0.5f * getheight() / smoothzoom, smoothzoomy, getheight() - 0.5f * getheight() / smoothzoom);      zoomx = lerp(bias(zoomx, smoothzoomx, 0.1f), smoothzoomx, 0.35f);     zoomy = lerp(bias(zoomy, smoothzoomy, 0.1f), smoothzoomy, 0.35f);     if (zoom != smoothzoom && listener != null) {         listener.onzooming(zoom, zoomx, zoomy);     }      final boolean animating = math.abs(zoom - smoothzoom) > 0.0000001f             || math.abs(zoomx - smoothzoomx) > 0.0000001f || math.abs(zoomy - smoothzoomy) > 0.0000001f;      // nothing draw     if (getchildcount() == 0) {         return;     }      // prepare matrix     m.settranslate(0.5f * getwidth(), 0.5f * getheight());     m.prescale(zoom, zoom);     m.pretranslate(-clamp(0.5f * getwidth() / zoom, zoomx, getwidth() - 0.5f * getwidth() / zoom),             -clamp(0.5f * getheight() / zoom, zoomy, getheight() - 0.5f * getheight() / zoom));      // view     final view v = getchildat(0);     m.pretranslate(v.getleft(), v.gettop());      // drawing cache if available     if (animating && ch == null && isanimationcacheenabled()) {         v.setdrawingcacheenabled(true);         ch = v.getdrawingcache();     }      // draw using cache while animating     if (animating && isanimationcacheenabled() && ch != null) {         p.setcolor(0xffffffff);         canvas.drawbitmap(ch, m, p);     } else { // zoomed or cache unavailable         ch = null;         canvas.save();         canvas.concat(m);         v.draw(canvas);         canvas.restore();     }      // draw minimap     if (showminimap) {         if (minimapheight < 0) {             minimapheight = getheight() / 4;         }          canvas.translate(10.0f, 10.0f);          p.setcolor(0x80000000 | 0x00ffffff & minimapcolor);         final float w = minimapheight * (float) getwidth() / getheight();         final float h = minimapheight;         canvas.drawrect(0.0f, 0.0f, w, h, p);          if (minimapcaption != null && minimapcaption.length() > 0) {             p.settextsize(minimapcaptionsize);             p.setcolor(minimapcaptioncolor);             p.setantialias(true);             canvas.drawtext(minimapcaption, 10.0f, 10.0f + minimapcaptionsize, p);             p.setantialias(false);         }          p.setcolor(0x80000000 | 0x00ffffff & minimapcolor);         final float dx = w * zoomx / getwidth();         final float dy = h * zoomy / getheight();         canvas.drawrect(dx - 0.5f * w / zoom, dy - 0.5f * h / zoom, dx + 0.5f * w / zoom, dy + 0.5f * h / zoom, p);          canvas.translate(-10.0f, -10.0f);     }      // redraw     // if (animating) {     getrootview().invalidate();     invalidate();     // } } 

}

public class drawingview extends imageview {  //drawing path private path drawpath; //drawing , canvas paint private paint drawpaint, canvaspaint; //initial color private int paintcolor = 0xff660000; //canvas private canvas drawcanvas; //canvas bitmap private bitmap canvasbitmap; private float brushsize, lastbrushsize; private boolean erase=false; private boolean moded=false;   public drawingview(context context, attributeset attrs){     super(context, attrs);     setupdrawing(); }  private void setupdrawing(){     //get drawing area setup interaction       drawpath = new path();     drawpaint = new paint();     drawpaint.setcolor(paintcolor);     drawpaint.setantialias(true);     drawpaint.setstrokewidth(brushsize);     drawpaint.setstyle(paint.style.stroke);     drawpaint.setstrokejoin(paint.join.round);     drawpaint.setstrokecap(paint.cap.round);     canvaspaint = new paint(paint.dither_flag);     brushsize = getresources().getinteger(r.integer.medium_size);     lastbrushsize = brushsize;     }  @override protected void onsizechanged(int w, int h, int oldw, int oldh) {     super.onsizechanged(w, h, oldw, oldh); //view given size     canvasbitmap = bitmap.createbitmap(w, h, bitmap.config.argb_8888);     drawcanvas = new canvas(canvasbitmap); } @override protected void ondraw(canvas canvas) { //draw view      canvas.drawbitmap(canvasbitmap, 0, 0, canvaspaint);     canvas.drawpath(drawpath, drawpaint);  } @override public boolean ontouchevent(motionevent event) { //detect user touch       //check if editing or touching     if(moded){     float touchx = event.getx();     float touchy = event.gety();      switch (event.getaction()) {     case motionevent.action_down:         drawpath.moveto(touchx, touchy);         break;     case motionevent.action_move:         drawpath.lineto(touchx, touchy);         break;     case motionevent.action_up:         drawcanvas.drawpath(drawpath, drawpaint);         drawpath.reset();         break;     default:        // return true;     }     invalidate();     }     return true; } public void setcolor(string newcolor){     //set color      invalidate();     paintcolor = color.parsecolor(newcolor);     drawpaint.setcolor(paintcolor);     } public void setbrushsize(float newsize){     //update size     float pixelamount = typedvalue.applydimension(typedvalue.complex_unit_dip,              newsize, getresources().getdisplaymetrics());         brushsize=pixelamount;         drawpaint.setstrokewidth(brushsize);     } public void setlastbrushsize(float lastsize){     lastbrushsize=lastsize; } public float getlastbrushsize(){     return lastbrushsize; } public void seterase(boolean iserase){     //set erase true or false      erase=iserase;     if(erase) drawpaint.setxfermode(new porterduffxfermode(porterduff.mode.clear));     else drawpaint.setxfermode(null);     }  public void setmode(boolean ismoded){     moded=ismoded; }  @suppresswarnings("deprecation") public void setbitmap(bitmap bitmap){     setbackgrounddrawable(new bitmapdrawable(bitmap)); } 

}


Comments

Popular posts from this blog

c# - How to get the current UAC mode -

postgresql - Lazarus + Postgres: incomplete startup packet -

javascript - Ajax jqXHR.status==0 fix error -