JavascriptProva

Visualizzazione post con etichetta scroll. Mostra tutti i post
Visualizzazione post con etichetta scroll. Mostra tutti i post

martedì 10 maggio 2016

Impostare i limiti dello scorrimento di un'immagine senza far ricorso alla Matrix.

Cerchiamo di capire questa formula del Math.max.

 x = Math.max(AXIS_X_MIN, Math.min(x, AXIS_X_MAX - curWidth));
 y = Math.max(AXIS_Y_MIN + curHeight, Math.min(y, AXIS_Y_MAX));
AXIS_X_MIN sarebbe il numero minimo sull'asse delle X. La funzione Math.max sceglie il massimo fra questo valore minimo e un altro valore, che è Math.min(x, AXIS_X_MAX - curWidth).
Dobbiamo interpretare questo, adesso.
Sceglie il valore minimo fra la x corrente e la larghezza, credo, della larghezza di un rettangolo.
Se la x corrente è bassa, viene scelta come valore dalla funzione Math.min.
Se la x comincia a crescere, quando raggiunge il valore di AXIS_X_MAX - curWidth non viene più scelta, ma viene scelta la X.
Questo potrebbe essere un modo per limitare lo scorrimento di un'immagine in una finestra senza far ricorso alle matrici come ho fatto io...

Se infatti io imposto che x è uguale a x se però la x è inferiore a un certo valore, altrimenti è uguale a quel valore, il problema dovrebbe essere risolto in modo molto semplice e senza scomodare matrici varie...

Math.max invece serve per rendere la x uguale a x nel caso in cui questa sia superiore al valore minimo, ossia AXIS_X_MIN.
Ci potrebbe essere un problema nel caso in cui la x sia maggiore del valore massimo considerato, perché verrebbe scelto questo, ma è un falso problema, perché questo è considerato solo se la x tende a eccederlo.

Ho capito la formula!

Ora provo a costruire una limitazione dei movimenti semplicemente per mezzo di quella funzione che non coinvolgeva la Matrix ma era molto più semplice.


   OnTouchListener onTouchListener =new View.OnTouchListener() {
   
    int X,Y;
   @Override
   public boolean onTouch(View v, MotionEvent event) {
    
    int action=event.getAction();
    switch(action & MotionEvent.ACTION_MASK){
    case MotionEvent.ACTION_DOWN:
     X=(int)event.getX();
     Y=(int)event.getY();
     
     break;
    case MotionEvent.ACTION_MOVE:
     int currentX=(int)event.getX();
     int currentY=(int)event.getY();
     v.scrollBy(X-currentX, Y-currentY);
     X=currentX;
     Y=currentY;
     break;
    }
    return true;
   }
  };
  imageView.setOnTouchListener(onTouchListener);
Ecco, questo è il semplicissimo modellino di un'immagine scrollabile.
Però ora dobbiamo provare a metterci dei limiti secondo quanto visto con la formula di cui sopra.

   OnTouchListener onTouchListener =new View.OnTouchListener() {
   int fetta=50;
   int X,Y;
   @Override
   public boolean onTouch(View v, MotionEvent event) {
    
    int action=event.getAction();
    switch(action & MotionEvent.ACTION_MASK){
    case MotionEvent.ACTION_DOWN:
     X=(int)event.getX();
     Y=(int)event.getY();
     
     break;
    case MotionEvent.ACTION_MOVE:
     int currentX=(int)Math.max(fetta,Math.min(event.getX(),v.getWidth()-fetta));
     int currentY=(int)Math.max(fetta,Math.min(event.getY(),v.getWidth()-fetta));
     v.scrollBy(X-currentX, Y-currentY);
     X=currentX;
     Y=currentY;
     break;
    }
    return true;
   }
  };
  imageView.setOnTouchListener(onTouchListener);
Funziona egregiamente!
Studiamo lo scaling, adesso...

private class ScaleListener 
        extends ScaleGestureDetector.SimpleOnScaleGestureListener {
    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        mScaleFactor *= detector.getScaleFactor();

        // Don't let the object get too small or too large.
        mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f));

        invalidate();
        return true;
    }
}
che cosa è mScaleFactor?
Andiamo a cercarci la definizione...
private float mScaleFactor = 1.f;
che non aggiunge niente... vediamo come viene usato.
 canvas.scale(mScaleFactor, mScaleFactor);
Ora, sul canvas sono ancora poco esperto.
Ma sarebbe il fattore scala...

Come posso usarlo qui?
Proviamo...

Con una matrix è l'unico modo che mi venga in mente...

lunedì 2 maggio 2016

Codice per scrolling e zoom di un'immagine.

Ecco il codice che realizza un'immagine scrollabile e zoomabile:
public class MainActivity extends Activity {
 float scale=1f;
 ScaleGestureDetector SGD;
 
 RelativeLayout mainLayout;
 ImageView imageView;
 
 Bitmap bitmap;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  SGD = new ScaleGestureDetector(this, new ScaleListener());
  mainLayout=(RelativeLayout)findViewById(R.id.mainLayout);
  
  bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.angurie2);
  final int larghezza=300;
  final int altezza=300;
  ImageView i=newImage(mainLayout,larghezza, altezza, 10, 10, bitmap, Color.BLACK, ScaleType.MATRIX);
    
  View.OnTouchListener onTouchListener=new View.OnTouchListener() {
   Matrix matrix=new Matrix();
   Matrix inversa=new Matrix();
   float X,Y,currentX, currentY;
   float deltaX, deltaY;
   @Override
   public boolean onTouch(View v, MotionEvent event) {
    switch(event.getAction()){
    case MotionEvent.ACTION_DOWN:
     X=event.getX();
     Y=event.getY();
     
     break;
    case MotionEvent.ACTION_MOVE:
     
     currentX=event.getX();
     currentY=event.getY();
     float[] pts={0,0};
     ((ImageView)v).getImageMatrix().invert(inversa);
     inversa.mapPoints(pts);
     
     
     if(currentX<X){
      if((pts[0]-currentX+X)<(bitmap.getWidth()-larghezza/scale)){
       deltaX=-pts[0]+currentX-X;
      }
      else{
       if((pts[0]-currentX+X)>(bitmap.getWidth()-larghezza/scale))
       deltaX=-(bitmap.getWidth()-larghezza/scale);
       
      }
     }
     if(currentX>X){
      if((pts[0]-currentX+X)>0){
       deltaX=-pts[0]+currentX-X;
      }
      else{
       if((pts[0]-currentX+X)<0) deltaX=0;
      }
     }
     
     if(currentY<Y){
      if((pts[1]-currentY+Y)<(bitmap.getHeight()-altezza/scale)){
       deltaY=-pts[1]+currentY-Y;
      }
      else{
       if((pts[1]-currentY+Y)>(bitmap.getHeight()-altezza/scale))
        deltaY=-(bitmap.getHeight()-altezza/scale);
       
      }
     }
     if(currentY>Y){
      if((pts[1]-currentY+Y)>0){
       deltaY=-pts[1]+currentY-Y;
      }
      else{
       if((pts[1]-currentY+Y)<0) deltaY=0;
      }
     }
     
     
     matrix.setTranslate(deltaX,deltaY);
     matrix.postScale(scale, scale);
     ((ImageView)v).setImageMatrix(matrix);
     X=currentX;
     Y=currentY;
     SGD.onTouchEvent(event);
     break;
    }
    return true;
   }
  };
  i.setOnTouchListener(onTouchListener);
 
  
  
  
 }

 class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener{
  @Override
  public boolean onScale(ScaleGestureDetector SGD){
   scale *= SGD.getScaleFactor();
   return true;
  }
 }
 public ImageView newImage(ViewGroup layout, int larghezza, int altezza, 
   float X, float Y, Bitmap bitmap, int colore, 
   ScaleType scaletype){
  ImageView imageView=new ImageView(this);
  layout.addView(imageView);
  imageView.getLayoutParams().width=larghezza;
  imageView.getLayoutParams().height=altezza;
  imageView.setX(X);
  imageView.setY(Y);

  imageView.setImageBitmap(bitmap);
  imageView.setBackgroundColor(colore);
  imageView.setScaleType(scaletype);
  return imageView;
 }

} 
Ora devo provvedere a metterlo nell'applicazione...
Dopo averla opportunamente SALVATA!!!

Il codice per prendere l'immagine devo andare a ripescarmelo...

Eccolo:
  button.setOnClickListener(new View.OnClickListener() {
   
   @Override
   public void onClick(View v) {
    
    imageView.destroyDrawingCache();
    imageView.buildDrawingCache();
    Bitmap bmp=imageView.getDrawingCache();
    imgControllo.setImageBitmap(bmp);
    
   }
  });

domenica 1 maggio 2016

Scrolling di un'immagine per mezzo di Matrix (mio codice)

Questo è il codice per mezzo del quale sono riuscito a imporre dei limiti allo scorrimento di un'immagine all'interno di una finestra.
Me lo annoto, e poi cerco, se possibile, di apporre dei perfezionamenti.
public class MainActivity extends Activity {

 
 RelativeLayout mainLayout;
 ImageView imageView;
 
 Bitmap bitmap;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  mainLayout=(RelativeLayout)findViewById(R.id.mainLayout);
  
  bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.anguria);
  
 
  ImageView imageView=new ImageView(this);
 
  

  
  imageView.setImageBitmap(bitmap);
  imageView.setBackgroundColor(Color.BLACK);
  imageView.setScaleType(ScaleType.MATRIX);
  
  
  mainLayout.addView(imageView);
  imageView.setX(200);
  imageView.setY(10);
  imageView.getLayoutParams().width=200;
  imageView.getLayoutParams().height=200;
  
  
  View.OnTouchListener onTouchListener=new View.OnTouchListener() {
   Matrix matrix=new Matrix();
   Matrix inversa=new Matrix();
   float X,Y,currentX, currentY;
   float deltaX, deltaY;
   @Override
   public boolean onTouch(View v, MotionEvent event) {
    switch(event.getAction()){
    case MotionEvent.ACTION_DOWN:
     X=event.getX();
     Y=event.getY();
     break;
    case MotionEvent.ACTION_MOVE:
     currentX=event.getX();
     currentY=event.getY();
     float[] pts={0,0};
     ((ImageView)v).getImageMatrix().invert(inversa);
     inversa.mapPoints(pts);
     
     /*se la direzione è da destra a sinistra il punto d'arresto
      * è a bitmap.getWidth-200. Per valori inferiori la 
      * translazione è normale, per valori uguali la translazione
      * è zero, per valori superiori torna al valore massimo
      */
     Log.d(pts[0]+"",""+(bitmap.getWidth()-200));
     if(currentX<X){
      if(pts[0]<(bitmap.getWidth()-200)){
       deltaX=-pts[0]+currentX-X;
      }
      else{
       if(pts[0]>(bitmap.getWidth()-200))
       deltaX=-(bitmap.getWidth()-200);
       
      }
     }
     if(currentX>X){
      if(pts[0]>0){
       deltaX=-pts[0]+currentX-X;
      }
      else{
       if(pts[0]<0) deltaX=0;
      }
     }
     
     if(currentY<Y){
      if(pts[1]<(bitmap.getHeight()-200)){
       deltaY=-pts[1]+currentY-Y;
      }
      else{
       if(pts[1]>(bitmap.getHeight()-200))
        deltaY=-(bitmap.getHeight()-200);
       
      }
     }
     if(currentY>Y){
      if(pts[1]>0){
       deltaY=-pts[1]+currentY-Y;
      }
      else{
       if(pts[1]<0) deltaY=0;
      }
     }
     
     
     matrix.setTranslate(deltaX,deltaY);
     ((ImageView)v).setImageMatrix(matrix);
     X=currentX;
     Y=currentY;
    }
    return true;
   }
  };
  imageView.setOnTouchListener(onTouchListener);
  
  
 }

}