Как увеличить определенную область на холсте в Android

#java #android #canvas #zooming #pinchzoom

Вопрос:

Вот мой код, я пытаюсь увеличить масштаб в определенной области, но мой код работает неправильно. Я хочу, чтобы мой код работал в режиме увеличения масштаба Autocad Canvas, может ли кто-нибудь знать, как увеличивать масштаб холста так же, как в AutoCAD canvas. Я хочу, чтобы приложение САПР работало так же, как работает AutoCAD, пожалуйста, помогите мне. Я хочу, чтобы мой код работал как увеличение-уменьшение холста, перетаскивание, перемещение холста.

 public class Custom_Canvas extends View implements View.OnTouchListener {

private static final int INVALID_POINTER_ID = -1;
private int mActivePointerId = INVALID_POINTER_ID;
Paint paint = new Paint();
// See onTouchEvent!
private float initX = 0f;
private float initY = 0f;
// x and y coord of canvas center!
private float canvasX = 0f;
private float canvasY = 0f;
private boolean drag = false;
private boolean firstdraw = true;

ScaleGestureDetector scaleGestureDetector;
private float scalefactor = 1f;
private float scalePointX, scalePointY;
float min_zoom = 0.1f;
float max_zoom = 10f;

private float lastfocusX = -1;
private float lastfocusY = -1;



@SuppressLint("ClickableViewAccessibility")
public Custom_Canvas(Context context, AttributeSet attrs){
    super(context, attrs);
    this.setOnTouchListener(this);
    scaleGestureDetector = new ScaleGestureDetector(context,new Scalelistener());
    paint.setColor(Color.WHITE);
}

@SuppressLint("ClickableViewAccessibility")
public Custom_Canvas(Context context) {
    super(context);
    this.setOnTouchListener(this);
    paint.setColor(Color.WHITE);
    scaleGestureDetector = new ScaleGestureDetector(context,new Scalelistener());
}

@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.save();
    if(firstdraw){
        canvasX = getWidth()/2f;
        canvasY = getHeight()/2f;
        firstdraw = false;

    }
    canvas.scale(scalefactor,scalefactor,scalePointX,scalePointY);
    canvas.translate(canvasX,canvasY);
    canvas.drawCircle(0,0,20f,paint);
   // canvas.drawCircle(100,100,20f,paint);
    canvas.restore();
}

@Override
public boolean onTouch(View v, MotionEvent event) {

    scaleGestureDetector.onTouchEvent(event);

    switch (event.getAction() amp; MotionEvent.ACTION_MASK) {

        case MotionEvent.ACTION_DOWN:
            float x = event.getX()/scalefactor;
            float y = event.getY()/scalefactor;
          //  drag = true;
            initX = x;
            initY = y;
            mActivePointerId = event.getPointerId(0);
            invalidate();
            break;

        case MotionEvent.ACTION_MOVE:
            //    case MotionEvent.ACTION_POINTER_DOWN:
            final int p = event.findPointerIndex(mActivePointerId);
            final float x1 = event.getX(p) / scalefactor;
            final float y1 = event.getY(p) / scalefactor;

            if (!scaleGestureDetector.isInProgress()) {
                   //   if (drag) {
                          float dx = x1 - initX;
                          float dy = y1 - initY;
                          canvasX  = dx ;
                          canvasY  = dy ;
                          invalidate();
                 //     }
             }
            initX = x1;
            initY = y1;
            break;


        case MotionEvent.ACTION_POINTER_UP:
           // drag = false;
            final int pointerIndex = (event.getAction() amp; MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
            final int pointerId = event.getPointerId(pointerIndex);
            if (pointerId == mActivePointerId) {
                final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                initX = event.getX(newPointerIndex)/scalefactor;
                initY = event.getY(newPointerIndex)/scalefactor;
                mActivePointerId = event.getPointerId(newPointerIndex);
            }
            break;

        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_CANCEL:
         //   drag = false;
            mActivePointerId = INVALID_POINTER_ID;
            break;


    }
    return true;
}


private class Scalelistener extends ScaleGestureDetector.SimpleOnScaleGestureListener{

    @Override
    public boolean onScale(ScaleGestureDetector detector) {

        scalefactor *= detector.getScaleFactor();
        scalePointX = detector.getFocusX();
        scalePointY = detector.getFocusY();
        Toast.makeText(getContext(), " " scalePointX " " scalePointY, Toast.LENGTH_SHORT).show();
        if(lastfocusX == -1){
            lastfocusX = scalePointX;
        }
        if(lastfocusY == -1){
            lastfocusY = scalePointY;
        }

        canvasX  = (scalePointX - lastfocusX);
        canvasY  = (scalePointY - lastfocusY);
        scalefactor = Math.max(min_zoom,Math.min(scalefactor,max_zoom));

        lastfocusX = scalePointX;
        lastfocusY = scalePointY;

        invalidate();
        return true;
    }

    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {
        lastfocusX = -1;
        lastfocusY = -1;
        return  true;
    }

    @Override
    public void onScaleEnd(ScaleGestureDetector detector) { }
}