центрированный зум в пользовательском представлении - вычисление координат холста - PullRequest
6 голосов
/ 18 марта 2011

Я работаю над своим первым «настоящим» Android-приложением, графическим редактором рабочего процесса. Рисование выполняется в пользовательском классе, который является подклассом View. В данный момент мои элементы представляют собой прямоугольники, которые нарисованы на холсте. Чтобы обнаружить действия над элементами, я сравниваю координаты и проверяю элементы на месте касания.

Чтобы реализовать жест масштабирования, я попытался http://android -developers.blogspot.com / 2010/06 / making-sense-of-multitouch.html

С помощью функции 4 аргумента canvas.scale (...) хорошо работает центрированное масштабирование, но я теряю возможность вычислять координаты холста, используя смещение с помощью mPosX и mPosY, чтобы определить, находится ли касание после увеличения на элемент.

Я попытался изменить пример в посте блога выше, чтобы центрировать холст на жесте увеличения с помощью:

canvas.save();
canvas.translate(mPosX, mPosY);
canvas.scale(mScaleFactor, mScaleFactor, mScalePivotX, mScalePivotY);
//drawing ....
canvas.restore();

Я не нашел каких-либо примеров о том, как это может быть сделано без потери ссылок смещения для вычисления координат. Есть ли легкий обходной путь? Я попытался вычислить смещение по центру жеста и коэффициенту масштабирования, но не получилось: /

Я видел, что другие примеры, в которых используется ImageView, часто используют матрицу для преобразования изображения. Можно ли это сделать с помощью пользовательского View и Canvas? Если да, как я могу получить смещение x и y для проверки координат?

Кроме того, если мои идеи полностью неверны, я был бы очень рад увидеть некоторые примеры того, как это делается правильно.

Thx! ;)

1 Ответ

3 голосов
/ 09 августа 2011

Возможно, следующий код поможет вам рассчитать координаты с центром жеста и коэффициентом масштабирования. Я использую этот метод в своем классе, представляющем opengl-sprite.

void zoom(float scale, PointF midPoint) {
    if (zoomFactor == MAX_ZOOM_FACTOR && scale > 1) return;
    if (zoomFactor == MIN_ZOOM_FACTOR && scale < 1) return;

    zoomFactor *= scale;
    x = (x - midPoint.x) * scale + midPoint.x;
    y = (y - height + midPoint.y) * scale + height - midPoint.y;
    if (zoomFactor >= MAX_ZOOM_FACTOR) {
        zoomFactor = MAX_ZOOM_FACTOR;
    } else if (zoomFactor < MIN_ZOOM_FACTOR) {
        zoomFactor = MIN_ZOOM_FACTOR;
        x = 0;
        y = 0;
    }
}

Координаты X и Y обрабатываются по-разному из-за различия между направлениями системы координат opengl (справа и вверх) и системы координат midPoint (справа и вниз). средняя точка берется из MotionEvent s координат.

Все остальные операции, я думаю, понятны.

Надеюсь, это поможет вам.

...