Сжатие холста -Увеличение до точки в пределах границ

Я застрял на этой проблеме в течение восьми часов, поэтому я решил, что пришло время получить помощь.

Прежде чем я начну свою проблему, я просто сообщу, что я просмотрел этот сайт и Google, и ни один из ответов, которые я нашел, не помог.(Это одно, другое , а другое .)

Вот в чем дело :У меня есть класс, который расширяетсяSurfaceView(назовем этоMySurface)и переопределяет многие методы в нем. Обычно он рисует несколько квадратов и текстовых полей, и это нормально. Как только пользователь начинает касаться, он преобразуется в Bitmap, а затем рисует каждый кадр до тех пор, пока пользователь не отпустит.

Вот в чем загвоздка :Я хочу реализовать такую ​​функциональность, чтобы пользователь мог прикоснуться к экрану двумя пальцами, сводить для масштабирования,а также панорамировать (, но ТОЛЬКО двумя пальцами вниз ).

Я нашел несколько реализаций масштабирования от -до -и адаптировал их к моему объекту Canvasв MySurfaceс помощью следующего:

public void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    canvas.save();

    canvas.scale(mScaleVector.z, mScaleVector.z); // This is the scale factor as seen below
    canvas.translate(mScaleVector.x, mScaleVector.y); // These are offset values from 0,0, both working fine

    // Start draw code

    //...

    // End draw code

    canvas.restore();
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        float factor = detector.getScaleFactor();
        if (Math.abs(factor - 1.0f) >= 0.0075f) {
            mScaleVector.z *= factor;
            mScaleVector.z = Math.max(MIN_ZOOM, Math.min(mScaleVector.z, MAX_ZOOM));
        }

        //...

        invalidate();

        return true;
    }
}
public boolean onTouchEvent(MotionEvent event) {
    int action = event.getAction() & MotionEvent.ACTION_MASK;
    int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
    if (event.getPointerCount() == 2) {
        if (action == MotionEvent.ACTION_POINTER_DOWN && pointerIndex == 1) {
            // The various pivot coordinate codes would belong here
        }
    }

    detector.onTouchEvent(event); // Calls the Scale Gesture Detector
    return true;
}

В то время как оба элемента работают нормально --прокрутка вперед и назад и масштабирование -до -масштабирование --, есть одна большая проблема. Масштабирование щипком от -до -при использовании увеличивает масштаб до точки 0,0вместо увеличения точки пальца.

Я пробовал много способов исправить это:

  • Используя canvas.scale(mScaleVector.z, mScaleVector.z, mScaleVector.x, mScaleVector.y);; очевидно, это приводит к нежелательным результатам, поскольку значения mScaleVectorx и y равны 0 -смещениям.
  • Управление «поворотной» координатой, которая использует то же смещение, что и метод translate(), но вызывает либо ту же проблему 0,0, либо скачки при касании представления.
  • Множество других вещей... Я многое сделал с вышеупомянутой координатой поворота, пытаясь определить ее местоположение по первому касанию пользователя и перемещая ее относительно этого касания при каждом последующем жесте.

Кроме того, этот холст должен быть ограничен, чтобы пользователь не мог прокручивать его вечно. Однако, когда я использую метод .scale(sx, sy, px, py), он выходит за все границы, которые я установил в .translate().

Я... в значительной степени открыта ко всему на данный момент. Я знаю, что эту функцию можно добавить, так как она видна в галерее Android 4.0 (при просмотре одного изображения ). Я пытался отследить исходный код, который обрабатывает это, но безрезультатно.

9
задан Community 23 May 2017 в 10:30
поделиться