Skip to content

Commit

Permalink
Fixed pinch zoom in place
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonpolites committed Feb 20, 2012
1 parent 493c4ed commit b3f97fd
Show file tree
Hide file tree
Showing 8 changed files with 228 additions and 88 deletions.
2 changes: 1 addition & 1 deletion example/project.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@

# Project target.
target=android-7
android.library.reference.1=../gesture-imageview/main
android.library.reference.1=../main
8 changes: 6 additions & 2 deletions example/res/layout/main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@
android:orientation="vertical"
android:background="#000000">

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="GestureImageView Example"/>

<com.polites.android.GestureImageView

android:id="@+id/image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_height="wrap_content"
gesture-image:min-scale="0.1"
gesture-image:max-scale="10.0"
android:src="@drawable/image"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;

public class GestureListener extends SimpleOnGestureListener {
public class DoubleTapListener extends SimpleOnGestureListener {

private GestureImageView image;

public GestureListener(GestureImageView image) {
public DoubleTapListener(GestureImageView image) {
super();
this.image = image;
}
Expand Down
35 changes: 11 additions & 24 deletions main/src/com/polites/android/GestureImageView.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,25 +68,17 @@ public GestureImageView(Context context, AttributeSet attrs) {
public GestureImageView(Context context) {
super(context);
}



@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);

int orientation = getResources().getConfiguration().orientation;

System.out.println(orientation);
setupCanvas(w, h, orientation);

setupCanvas(w, h, getResources().getConfiguration().orientation);
}

protected void setupCanvas(int measuredWidth, int measuredHeight, int orientation) {

if(bitmap != null) {


int imageWidth = this.bitmap.getWidth();
int imageHeight = this.bitmap.getHeight();

Expand Down Expand Up @@ -114,13 +106,15 @@ protected void setupCanvas(int measuredWidth, int measuredHeight, int orientatio
float heightRatio = (float) imageHeight / (float) displayHeight;

if(widthRatio > heightRatio) {
scaleAdjust = (float) displayWidth / (float) imageWidth;
startingScale = (float) displayWidth / (float) imageWidth;
}
else {
scaleAdjust = (float) displayHeight / (float) imageHeight;
startingScale = (float) displayHeight / (float) imageHeight;
}

startingScale = scaleAdjust;
if(!layout) {
scaleAdjust = startingScale;
}

this.centerX = (float)measuredWidth / 2.0f;
this.centerY = (float)measuredHeight / 2.0f;
Expand All @@ -135,21 +129,10 @@ protected void setupCanvas(int measuredWidth, int measuredHeight, int orientatio
setOnTouchListener(gestureImageViewTouchListener);

layout = true;
viewSet = false;
}
}

// @Override
// protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// if(bitmap != null) {
//
//
// setMeasuredDimension(measuredWidth, measuredHeight);
// }
// else {
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// }
// }

@Override
protected void onDraw(Canvas canvas) {
if(layout) {
Expand Down Expand Up @@ -189,6 +172,7 @@ protected void onAttachedToWindow() {
protected void onDetachedFromWindow() {
if(recycle && bitmap != null && !bitmap.isRecycled()) {
bitmap.recycle();
bitmap = null;
}
super.onDetachedFromWindow();
}
Expand All @@ -199,6 +183,9 @@ public void setImageBitmap(Bitmap image) {
}

public void setImageResource(int id) {
if(this.bitmap != null) {
this.bitmap.recycle();
}
if(id >= 0) {
this.recycle = true;
this.resId = id;
Expand Down
152 changes: 93 additions & 59 deletions main/src/com/polites/android/GestureImageViewTouchListener.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.polites.android;

import android.graphics.PointF;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
Expand All @@ -9,7 +10,9 @@ public class GestureImageViewTouchListener implements OnTouchListener {

private GestureImageView image;

private float currentX = 0, currentY = 0, lastX = 0, lastY = 0, nextX = 0, nextY = 0;
private PointF current = new PointF();
private PointF last = new PointF();
private PointF next = new PointF();

boolean touched = false;

Expand Down Expand Up @@ -41,8 +44,12 @@ public class GestureImageViewTouchListener implements OnTouchListener {
private int imageWidth;
private int imageHeight;

private GestureListener gListener;
private GestureDetector gDetector;
private final PointF midpoint = new PointF();

private final VectorF lastVector = new VectorF();

private DoubleTapListener doubleTapListener;
private GestureDetector doubleTapDetector;
private GestureImageViewListener imageListener;

public GestureImageViewTouchListener(GestureImageView image, int displayWidth, int displayHeight) {
Expand Down Expand Up @@ -70,11 +77,11 @@ public GestureImageViewTouchListener(GestureImageView image, int displayWidth, i
boundaryLeft = 0;
boundaryTop = 0;

nextX = image.getX();
nextY = image.getY();
next.x = image.getX();
next.y = image.getY();

gListener = new GestureListener(image);
gDetector = new GestureDetector(gListener);
doubleTapListener = new DoubleTapListener(image);
doubleTapDetector = new GestureDetector(doubleTapListener);
imageListener = image.getGestureImageViewListener();

calculateBoundaries();
Expand All @@ -84,12 +91,12 @@ public GestureImageViewTouchListener(GestureImageView image, int displayWidth, i
@Override
public boolean onTouch(View v, MotionEvent event) {

if(gDetector.onTouchEvent(event)) {
if(doubleTapDetector.onTouchEvent(event)) {
lastDistance = 0;
lastScale = startingScale;
currentScale = startingScale;
nextX = image.getX();
nextY = image.getY();
next.x = image.getX();
next.y = image.getY();
}

if(event.getAction() == MotionEvent.ACTION_UP) {
Expand All @@ -100,11 +107,11 @@ public boolean onTouch(View v, MotionEvent event) {
lastScale = currentScale;

if(!canDragX) {
nextX = centerX;
next.x = centerX;
}

if(!canDragY) {
nextY = centerY;
next.y = centerY;
}

boundCoordinates();
Expand All @@ -115,59 +122,86 @@ public boolean onTouch(View v, MotionEvent event) {
}

image.setScale(currentScale);
image.setPosition(nextX, nextY);
image.setPosition(next.x, next.y);

if(imageListener != null) {
imageListener.onScale(currentScale);
imageListener.onPosition(nextX, nextY);
}
imageListener.onPosition(next.x, next.y);
}

image.redraw();
}
else if(event.getAction() == MotionEvent.ACTION_DOWN) {
lastX = event.getX();
lastY = event.getY();
last.x = event.getX();
last.y = event.getY();

if(imageListener != null) {
imageListener.onTouch(lastX, lastY);
imageListener.onTouch(last.x, last.y);
}

touched = true;
}
else if(event.getAction() == MotionEvent.ACTION_MOVE) {
if(event.getPointerCount() > 1) {
multiTouch = true;
if(lastDistance > 0) {
float distance = MathUtils.distance(event);
currentScale = (distance / lastDistance) * lastScale;

if(currentScale > maxScale) {
currentScale = maxScale;
}
else if (currentScale < minScale) {
currentScale = minScale;
if(lastDistance != distance) {

// We have moved (scaled)
currentScale = (distance / lastDistance) * lastScale;

if(currentScale > maxScale) {
currentScale = maxScale;
}
else if (currentScale < minScale) {
currentScale = minScale;
}

calculateBoundaries();

lastVector.length *= currentScale;

lastVector.calculateEndPoint();

lastVector.length /= currentScale;

next.x = lastVector.end.x;
next.y = lastVector.end.y;

image.setScale(currentScale);
image.setPosition(next.x, next.y);

if(imageListener != null) {
imageListener.onScale(currentScale);
imageListener.onPosition(next.x, next.y);
}

image.redraw();
}

calculateBoundaries();
// midpoint(event);
image.setScale(currentScale);

if(imageListener != null) {
imageListener.onScale(currentScale);
}

image.redraw();
}
else {
lastDistance = MathUtils.distance(event);

MathUtils.midpoint(event, midpoint);

lastVector.setStart(midpoint);
lastVector.setEnd(next);

lastVector.calculateLength();
lastVector.calculateAngle();

lastVector.length /= lastScale;
}
}
else {
if(!touched) {
touched = true;
lastX = event.getX();
lastY = event.getY();
nextX = image.getX();
nextY = image.getY();
last.x = event.getX();
last.y = event.getY();
next.x = image.getX();
next.y = image.getY();
}
else if(!multiTouch) {
if(handleDrag(event.getX(), event.getY())) {
Expand All @@ -180,27 +214,27 @@ else if(!multiTouch) {
}

protected boolean handleDrag(float x, float y) {
currentX = x;
currentY = y;
current.x = x;
current.y = y;

float diffX = (currentX - lastX);
float diffY = (currentY - lastY);
float diffX = (current.x - last.x);
float diffY = (current.y - last.y);

if(diffX != 0 || diffY != 0) {

if(canDragX) nextX += diffX;
if(canDragY) nextY += diffY;
if(canDragX) next.x += diffX;
if(canDragY) next.y += diffY;

boundCoordinates();

lastX = currentX;
lastY = currentY;
last.x = current.x;
last.y = current.y;

if(canDragX || canDragY) {
image.setPosition(nextX, nextY);
image.setPosition(next.x, next.y);

if(imageListener != null) {
imageListener.onPosition(nextX, nextY);
imageListener.onPosition(next.x, next.y);
}

return true;
Expand All @@ -212,11 +246,11 @@ protected boolean handleDrag(float x, float y) {

public void reset() {
currentScale = startingScale;
nextX = centerX;
nextY = centerY;
next.x = centerX;
next.y = centerY;
calculateBoundaries();
image.setScale(currentScale);
image.setPosition(nextX, nextY);
image.setPosition(next.x, next.y);
image.redraw();
}

Expand All @@ -238,18 +272,18 @@ public void setMinScale(float minScale) {
}

protected void boundCoordinates() {
if(nextX < boundaryLeft) {
nextX = boundaryLeft;
if(next.x < boundaryLeft) {
next.x = boundaryLeft;
}
else if(nextX > boundaryRight) {
nextX = boundaryRight;
else if(next.x > boundaryRight) {
next.x = boundaryRight;
}

if(nextY < boundaryTop) {
nextY = boundaryTop;
if(next.y < boundaryTop) {
next.y = boundaryTop;
}
else if(nextY > boundaryBottom) {
nextY = boundaryBottom;
else if(next.y > boundaryBottom) {
next.y = boundaryBottom;
}
}

Expand Down
Loading

0 comments on commit b3f97fd

Please sign in to comment.