Skip to content
This repository has been archived by the owner on Apr 19, 2018. It is now read-only.

Commit

Permalink
Properly honor pivot for scale operation.
Browse files Browse the repository at this point in the history
Add ViewHelper class which will correctly set the pivot in the appropriate place depending on the current API level.
  • Loading branch information
JakeWharton committed May 27, 2012
1 parent 399abe8 commit 3cb6d1d
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 72 deletions.
38 changes: 38 additions & 0 deletions library/src/com/nineoldandroids/view/ViewHelper.java
@@ -0,0 +1,38 @@
package com.nineoldandroids.view;

import android.view.View;

import static com.nineoldandroids.view.animation.AnimatorProxy.NEEDS_PROXY;
import static com.nineoldandroids.view.animation.AnimatorProxy.wrap;

public final class ViewHelper {
private ViewHelper() {}

public static void setPivotX(View view, float pivotX) {
if (NEEDS_PROXY) {
wrap(view).setPivotX(pivotX);
} else {
SetPivotX.invoke(view, pivotX);
}
}

public static void setPivotY(View view, float pivotY) {
if (NEEDS_PROXY) {
wrap(view).setPivotY(pivotY);
} else {
SetPivotY.invoke(view, pivotY);
}
}

private static final class SetPivotX {
static void invoke(View view, float pivotX) {
view.setPivotX(pivotX);
}
}

private static final class SetPivotY {
static void invoke(View view, float pivotY) {
view.setPivotY(pivotY);
}
}
}
Expand Up @@ -295,15 +295,15 @@ private void computeRect(final RectF r, View view) {
private void transformMatrix(Matrix m, View view) {
final float w = view.getWidth();
final float h = view.getHeight();
final boolean hasPivot = mHasPivot;
final float pX = hasPivot ? mPivotX : w / 2f;
final float pY = hasPivot ? mPivotY : h / 2f;

final float rX = mRotationX;
final float rY = mRotationY;
final float rZ = mRotationZ;
if ((rX != 0) || (rY != 0) || (rZ != 0)) {
final Camera camera = mCamera;
final boolean hasPivot = mHasPivot;
final float pX = hasPivot ? mPivotX : w / 2f;
final float pY = hasPivot ? mPivotY : h / 2f;
camera.save();
camera.rotateX(rX);
camera.rotateY(rY);
Expand All @@ -317,11 +317,10 @@ private void transformMatrix(Matrix m, View view) {
final float sX = mScaleX;
final float sY = mScaleY;
if ((sX != 1.0f) || (sY != 1.0f)) {
final float deltaSX = ((sX * w) - w) / 2f;
final float deltaSY = ((sY * h) - h) / 2f;
m.postScale(sX, sY);
m.postTranslate(-deltaSX, -deltaSY);
m.postTranslate(-pX, -pY);
}

m.postTranslate(mTranslationX, mTranslationY);
}

Expand Down
131 changes: 75 additions & 56 deletions sample/res/layout/toggles.xml
@@ -1,75 +1,94 @@
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/tx"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TX"/>
android:id="@+id/tx"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TX"/>
<Button
android:id="@+id/ty"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TY"/>
android:id="@+id/ty"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TY"/>
<Button
android:id="@+id/sx"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="SX"/>
android:id="@+id/sx"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="SX"/>
<Button
android:id="@+id/sy"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="SY"/>
android:id="@+id/sy"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="SY"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/a"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Alpha"/>
android:id="@+id/a"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Alpha"/>
<Button
android:id="@+id/rx"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="RX"/>
android:id="@+id/rx"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="RX"/>
<Button
android:id="@+id/ry"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="RY"/>
android:id="@+id/ry"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="RY"/>
<Button
android:id="@+id/rz"
android:layout_width="0dp"
android:id="@+id/rz"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="RZ"/>
</LinearLayout>
<LinearLayout
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="RZ"/>
android:layout_width="fill_parent"
android:orientation="horizontal">
<Button
android:id="@+id/pivot_corner"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
android:text="Pivot Corner"/>
<Button
android:id="@+id/pivot_center"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
android:text="Pivot Center"/>
</LinearLayout>
<LinearLayout
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:gravity="center">
<FrameLayout
android:id="@+id/target"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#FFFF0000"/>
android:layout_height="0dp"
android:layout_width="fill_parent"
android:layout_weight="1"
android:gravity="center">
<Button
android:id="@+id/target"
android:layout_width="100dp"
android:layout_height="100dp"
android:text="Sample Text"
android:gravity="center"/>
</LinearLayout>
</LinearLayout>
34 changes: 24 additions & 10 deletions sample/src/com/jakewharton/nineoldandroids/sample/Toggles.java
@@ -1,11 +1,11 @@
package com.jakewharton.nineoldandroids.sample;

import com.nineoldandroids.animation.ObjectAnimator;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.nineoldandroids.animation.ObjectAnimator;
import com.nineoldandroids.view.ViewHelper;

public class Toggles extends Activity {
@Override
Expand All @@ -16,53 +16,67 @@ public void onCreate(Bundle savedInstanceState) {
final View target = findViewById(R.id.target);
final int duration = 2 * 1000;

((Button)findViewById(R.id.tx)).setOnClickListener(new OnClickListener() {
findViewById(R.id.tx).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ObjectAnimator.ofFloat(target, "translationX", 0, 50, -50, 0).setDuration(duration).start();
}
});
((Button)findViewById(R.id.ty)).setOnClickListener(new OnClickListener() {
findViewById(R.id.ty).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ObjectAnimator.ofFloat(target, "translationY", 0, 50, -50, 0).setDuration(duration).start();
}
});
((Button)findViewById(R.id.sx)).setOnClickListener(new OnClickListener() {
findViewById(R.id.sx).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ObjectAnimator.ofFloat(target, "scaleX", 1, 2, 1).setDuration(duration).start();
}
});
((Button)findViewById(R.id.sy)).setOnClickListener(new OnClickListener() {
findViewById(R.id.sy).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ObjectAnimator.ofFloat(target, "scaleY", 1, 2, 1).setDuration(duration).start();
}
});
((Button)findViewById(R.id.a)).setOnClickListener(new OnClickListener() {
findViewById(R.id.a).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ObjectAnimator.ofFloat(target, "alpha", 1, 0, 1).setDuration(duration).start();
}
});
((Button)findViewById(R.id.rx)).setOnClickListener(new OnClickListener() {
findViewById(R.id.rx).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ObjectAnimator.ofFloat(target, "rotationX", 0, 180, 0).setDuration(duration).start();
}
});
((Button)findViewById(R.id.ry)).setOnClickListener(new OnClickListener() {
findViewById(R.id.ry).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ObjectAnimator.ofFloat(target, "rotationY", 0, 180, 0).setDuration(duration).start();
}
});
((Button)findViewById(R.id.rz)).setOnClickListener(new OnClickListener() {
findViewById(R.id.rz).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ObjectAnimator.ofFloat(target, "rotation", 0, 180, 0).setDuration(duration).start();
}
});
findViewById(R.id.pivot_corner).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ViewHelper.setPivotX(target, 0);
ViewHelper.setPivotY(target, 0);
}
});
findViewById(R.id.pivot_center).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ViewHelper.setPivotX(target, target.getWidth() / 2f);
ViewHelper.setPivotY(target, target.getHeight() / 2f);
}
});
}
}

0 comments on commit 3cb6d1d

Please sign in to comment.