2016-07-22 2 views
0

я использую этот код, чтобы масштабировать свой холст вокруг фокусной точкикак масштабировать с помощью холста

private class MyScaleDetector 
      extends ScaleGestureDetector.SimpleOnScaleGestureListener { 


     @Override 
     public boolean onScaleBegin(ScaleGestureDetector detector) { 
      float focusx=detector.getFocusX(); 
      float focusy=detector.getFocusY(); 
      return super.onScaleBegin(detector); 

     } 

     @Override 
     public boolean onScale(ScaleGestureDetector detector) { 
      float factor=detector.getScaleFactor(); 

       scale *= factor; 


      scale = Math.max(0.4f, Math.min(scale, 20.0f)); 


      return true; 
     } 
    } 

и это код, я использую для масштабирования внутри OnDraw метода

@Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 

     canvas.scale(scale,scale,focusx,focusy); 
} 

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

Я думаю, что я должен использовать canvas.translate() вместе с ним, но я не знаю, как много я должен перемещать позицию холста x и y при масштабировании.

Edit: изображение ниже суммировать то, что я пытаюсь сказать

image

ответ

0

Есть несколько вещей, чтобы иметь в виду здесь:

  1. ScaleDetector улавливает лишь масштабные события; это звучит неплохо, но само по себе недостаточно для обработки щепотки/увеличения в 2D (например, на картинке).
  2. «Фокус», возвращаемый детектором, является средней точкой между двумя указателями (пальцами); это менее полезно, поскольку естественное предположение, когда вы начинаете масштабирование, заключается в том, что пиксель изображения под пальцем останется под пальцем при масштабировании. Люди часто перемещают пальцы с разной скоростью (или намеренно держат один палец неподвижным), что делает недействительным использование средней точки.
  3. Вы, вероятно, тоже хотите обрабатывать вращение.

Широкий подход, который я использовал в прошлом:

  • вручную обнаружить первые и вторые сенсорные события; запишите координату двух указателей, когда произойдет второе касательное событие указателя. Эти точки должны логически «следовать» указателям с этого момента.
  • , когда происходит событие движения, которое продолжает иметь два указателя вниз, определяют перевод, масштаб и угол поворота следующим образом (т.е. два перебирал вращение, масштабирование или перетаскивание.):
    • шкала основана на расстояние между новыми точками по сравнению с исходными точками (записано в начале)
    • вращение основано на различии в углу между двумя первыми точками и углом между последними точками
    • перевод базируется произвольно на одной из точек (обычно первой) - просто перевести на основе пикселей между исходной точкой и последней точкой
    • эти значения могут быть вычислены и сохранены во время события движения, затем используется в OnDraw() метод

Обратите внимание, что в OnDraw():

  • Это важно для выполнения перевода сначала, поскольку вы работаете в пикселях экрана для двух контрольных точек.
  • вы можете вращать шкалу & в любом порядке, так как масштаб всегда равен в направлении X & Y

Edit для решения более конкретный запрос:

Если все, что вам действительно нужно сделать просто масштабировать вокруг конкретного переопределены точки р (рх, ру) на величину s, и держать р видно, то вы можете сделать следующее:

canvas.translate(px, py); 
canvas.scale(s,s); 
canvas.translate(-px*s, py*s); 

Это должно держать p в том же положении пикселя, что и перед масштабированием. Это будет страдать от всех проблем, упомянутых выше, а также рисков дрейфа из-за последовательных событий масштаба вокруг движущегося фокуса (на основе вашего исходного кода). Вы намного лучше делаете то, что я описал выше.

+0

thx для деталей, но вы не упомянули, как можно масштабировать вокруг определенной точки, которая является проблемой, я уже знаю, насколько масштабируется, и она отлично работает, я тестировал ее для масштабирования вокруг середины высоты и ширины экрана и он работал очень хорошо, но если я масштабируюсь вокруг другой точки, он начинает идти туда в начале масштабирования, но он начинает уходить от точки, так как вы можете видеть, что мне нужно найти способ, чтобы я мог сделать эту точку фокусировки центр области просмотра при масштабировании – hm9

+0

Вы масштабируете вокруг определенной точки точно так же, как и вы. Чтобы убедиться, что точка остается видимой, немного больше работы, см. Мой обновленный ответ – RabidMutant