java - Android Canvas - Scale and Translate -
i have svg want zoom , pan using gestures in android. works, not smoothly enough tastes. how can improve class have smooth panning works @ zoom levels , stays under finger, scales using pinch gesture zooms area of gesture (aka focus) , bonus double tapping should result in snapping image 1.0? i'm using svg library. acceptable answer should meet these functional requirements, not jump around unexpectedly , stick gesturedetectors unless case can made won't work.
public class mapview extends viewgroup { private static final float minimum_scale_factor = 1.0f; private static final float maximum_scale_factor = 10.0f; private picture mpicture; private paint mpaint; private scalegesturedetector mscaledetector; private gesturedetector mmovedetector; private float mscalefactor; private float mscalefocusx; private float mscalefocusy; private float mfocusx = 0.0f; private float mfocusy = 0.0f; private float mimageheight; private float mimagewidth; private int mviewheight; private int mviewwidth; private rectf mdrawingrect; public mapview(context context) { super(context); init(context); } public mapview(context context, attributeset attrs) { super(context, attrs); init(context); } public mapview(context context, attributeset attrs, int defstyle) { super(context, attrs, defstyle); init(context); } public void init(context context) { log.d(getclass().getcanonicalname(), "initialized."); this.setbackgroundcolor(color.white); this.mpaint = new paint(); mpaint.setstyle(paint.style.stroke); mpaint.setcolor(color.blue); mpaint.setstrokewidth(2); mpaint.setantialias(true); this.mscalefactor = minimum_scale_factor; // setup gesture detectors this.mscaledetector = new scalegesturedetector(context, new scalelistener()); this.mmovedetector = new gesturedetector(context, new movelistener()); } @override protected void onlayout(boolean changed, int l, int t, int r, int b) { log.d(getclass().getcanonicalname(), "onlayout"); this.mdrawingrect = getdrawingsquare(); } @override protected void onsizechanged(int w, int h, int oldw, int oldh) { super.onsizechanged(w, h, oldw, oldh); this.mviewwidth = w; this.mviewheight = h; } @override protected void ondraw(canvas canvas) { super.ondraw(canvas); log.d(getclass().getcanonicalname(), "ondraw()"); canvas.save(); canvas.scale(mscalefactor, mscalefactor, mscalefocusx, mscalefocusy); canvas.translate(mfocusx, mfocusy); canvas.drawrect((int) mdrawingrect.left, (int) mdrawingrect.top, (int) mdrawingrect.right, (int) mdrawingrect.bottom, mpaint); canvas.drawpicture(mpicture, mdrawingrect); canvas.restore(); } @override public boolean ontouchevent(motionevent ev) { mscaledetector.ontouchevent(ev); mmovedetector.ontouchevent(ev); return true; } public rectf getdrawingsquare() { float width = getwidth(); float height = getheight(); log.d(getclass().getcanonicalname(), "picture width " + width + " - height " + height); float side = math.min(width, height); return new rectf(0, 0, side, side); } public void setsvg(svg svg) { log.d(getclass().getcanonicalname(), "svg picture."); this.mpicture = svg.getpicture(); this.mimageheight = mpicture.getheight(); this.mimagewidth = mpicture.getwidth(); invalidate(); } private class scalelistener extends scalegesturedetector.simpleonscalegesturelistener { @override public boolean onscale(scalegesturedetector detector) { mscalefactor *= detector.getscalefactor(); // scale change since previous event mscalefocusx = detector.getfocusx(); mscalefocusy = detector.getfocusy(); // don't let object small or large. mscalefactor = math.max(minimum_scale_factor, math.min(mscalefactor, maximum_scale_factor)); invalidate(); return true; } } private class movelistener extends gesturedetector.simpleongesturelistener { // @override // public boolean ondown(motionevent e) { // return true; // } @override public boolean onscroll(motionevent e1, motionevent e2, float distancex, float distancey) { scrollby((int)distancex, (int)distancey); // mfocusx += distancex; // mfocusy += distancey; // return true; return true; } } }
if (re)drawing picture isn't fast enough, might have draw bitmap instead , scroll about.
Comments
Post a Comment