提交 6a5938b1 编写于 作者: H huangziwei

DoodlePath支持旋转。可旋转item可设置围绕某个点旋转

上级 637b45a0
......@@ -41,7 +41,6 @@
android:background="@drawable/ic_launcher" />
<TextView
android:id="@+id/author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
......
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
</resources>
<resources></resources>
......@@ -110,10 +110,7 @@ public class CopyLocation {
* 判断是否点中
*/
public boolean contains(float x, float y, float mPaintSize) {
if ((mX - x) * (mX - x) + (mY - y) * (mY - y) <= mPaintSize * mPaintSize) {
return true;
}
return false;
return (mX - x) * (mX - x) + (mY - y) * (mY - y) <= mPaintSize * mPaintSize;
}
public CopyLocation copy() {
......
......@@ -5,7 +5,6 @@ import android.graphics.Canvas;
import android.graphics.Rect;
import cn.hzw.doodle.core.IDoodle;
import cn.hzw.doodle.core.IDoodleColor;
/**
* 图片item
......@@ -20,14 +19,27 @@ public class DoodleBitmap extends DoodleRotatableItemBase {
public DoodleBitmap(IDoodle doodle, Bitmap bitmap, float size, float x, float y) {
super(doodle, -doodle.getDoodleRotation(), x, y); // 设置item旋转角度,使其在当前状态下显示为“无旋转”效果
setPivotX(x);
setPivotY(y);
this.mBitmap = bitmap;
setSize(size);
resetBounds(getBounds());
}
public void setBitmap(Bitmap bitmap) {
mBitmap = bitmap;
resetBounds(getBounds());
setPivotX(getLocation().x + getBounds().width() / 2);
setPivotY(getLocation().y + getBounds().height() / 2);
}
@Override
public void setSize(float size) {
float oldPivotX = getPivotX();
float oldPivotY = getPivotY();
super.setSize(size);
setPivotX(getLocation().x + getBounds().width() / 2);
setPivotY(getLocation().y + getBounds().height() / 2);
setLocation(getLocation().x - (getPivotX() - oldPivotX), getLocation().y - (getPivotY() - oldPivotY));
}
public Bitmap getBitmap() {
......
......@@ -8,7 +8,6 @@ import cn.hzw.doodle.core.IDoodleColor;
import cn.hzw.doodle.core.IDoodleItem;
import cn.hzw.doodle.core.IDoodlePen;
import cn.hzw.doodle.core.IDoodleShape;
import cn.hzw.doodle.util.DrawUtil;
/**
* Created on 29/06/2018.
......@@ -50,7 +49,6 @@ public abstract class DoodleItemBase implements IDoodleItem {
}
mDoodle = doodle;
if (doodle == null) {
return;
}
}
......@@ -79,8 +77,6 @@ public abstract class DoodleItemBase implements IDoodleItem {
return mPivotY;
}
private PointF mPointF = new PointF();
@Override
public void setItemRotate(float textRotate) {
mItemRotate = textRotate;
......@@ -92,10 +88,31 @@ public abstract class DoodleItemBase implements IDoodleItem {
return mItemRotate;
}
/**
* 默认改变相应的中心点位置
*
* @param x
* @param y
*/
@Override
public void setLocation(float x, float y) {
setLocation(x, y, true);
}
/**
* @param x
* @param y
* @param changePivot 是否随着移动相应改变中心点的位置
*/
public void setLocation(float x, float y, boolean changePivot) {
float diffX = x - mLocation.x, diffY = y - mLocation.y;
mLocation.x = x;
mLocation.y = y;
if (changePivot) {
mPivotX = mPivotX + diffX;
mPivotY = mPivotY + diffY;
}
refresh();
}
......@@ -152,9 +169,9 @@ public abstract class DoodleItemBase implements IDoodleItem {
public void draw(Canvas canvas) {
canvas.save();
mLocation = getLocation(); // 获取旋转后的起始坐标
canvas.translate(mLocation.x, mLocation.y); // 把坐标系平移到文字矩形范围
canvas.rotate(mItemRotate, 0, 0); // 旋转坐标系
canvas.translate(mLocation.x, mLocation.y); // 偏移,把坐标系平移到item矩形范围
float px = mPivotX - mLocation.x, py = mPivotY - mLocation.y; // 需要减去偏移
canvas.rotate(mItemRotate, px, py); // 旋转坐标系
doDraw(canvas);
canvas.restore();
......
......@@ -36,7 +36,7 @@ public class DoodleOnTouchGestureListener extends TouchGestureDetector.OnTouchGe
private float mSelectedItemX, mSelectedItemY;
private float mRotateTextDiff; // 开始旋转图片时的差值(当前图片与触摸点的角度)
private float mRotateDiff; // 开始旋转item时的差值(当前item的中心点与触摸点的角度)
private Path mCurrPath; // 当前手写的路径
private DoodlePath mCurrDoodlePath;
......@@ -111,8 +111,8 @@ public class DoodleOnTouchGestureListener extends TouchGestureDetector.OnTouchGe
if (mSelectedItem instanceof DoodleRotatableItemBase
&& (((DoodleRotatableItemBase) mSelectedItem).canRotate(mDoodle.toX(mTouchX), mDoodle.toY(mTouchY)))) {
((DoodleRotatableItemBase) mSelectedItem).setIsRotating(true);
mRotateTextDiff = mSelectedItem.getItemRotate() -
computeAngle(xy.x, xy.y, mDoodle.toX(mTouchX), mDoodle.toY(mTouchY));
mRotateDiff = mSelectedItem.getItemRotate() -
computeAngle(mSelectedItem.getPivotX(), mSelectedItem.getPivotY(), mDoodle.toX(mTouchX), mDoodle.toY(mTouchY));
}
}
} else {
......@@ -179,8 +179,8 @@ public class DoodleOnTouchGestureListener extends TouchGestureDetector.OnTouchGe
if (mSelectedItem != null) {
if ((mSelectedItem instanceof DoodleRotatableItemBase) && (((DoodleRotatableItemBase) mSelectedItem).isRotating())) { // 旋转item
PointF xy = mSelectedItem.getLocation();
mSelectedItem.setItemRotate(mRotateTextDiff + computeAngle(
xy.x, xy.y, mDoodle.toX(mTouchX), mDoodle.toY(mTouchY)
mSelectedItem.setItemRotate(mRotateDiff + computeAngle(
mSelectedItem.getPivotX(), mSelectedItem.getPivotY(), mDoodle.toX(mTouchX), mDoodle.toY(mTouchY)
));
} else { // 移动item
mSelectedItem.setLocation(
......
......@@ -15,7 +15,7 @@ import cn.hzw.doodle.util.DrawUtil;
* Created by huangziwei on 2017/3/16.
*/
public class DoodlePath extends DoodleSelectableItemBase {
public class DoodlePath extends DoodleRotatableItemBase {
private Path mPath; // 画笔的路径
private PointF mSxy = new PointF(); // 映射后的起始坐标,(手指点击)
......@@ -50,6 +50,7 @@ public class DoodlePath extends DoodleSelectableItemBase {
} else if (DoodleShape.FILL_RECT.equals(getShape()) || DoodleShape.HOLLOW_RECT.equals(getShape())) {
updateRectPath(mPath, mSxy.x, mSxy.y, mDxy.x, mDxy.y, getSize());
}
// 改变中心点位置
mPath.computeBounds(mBound, false);
setPivotX(mBound.left);
setPivotY(mBound.top);
......@@ -58,9 +59,10 @@ public class DoodlePath extends DoodleSelectableItemBase {
public void updatePath(Path path) {
this.mPath = path;
if (mPath != null) {
// 改变中心点位置
mPath.computeBounds(mBound, false);
setPivotX(mBound.left);
setPivotY(mBound.top);
setPivotX(mBound.left + mBound.width() / 2);
setPivotY(mBound.top + mBound.height() / 2);
}
}
......
......@@ -31,10 +31,10 @@ public abstract class DoodleRotatableItemBase extends DoodleSelectableItemBase {
public void doDrawSelectedBackground(Canvas canvas) {
mRectTemp.set(getBounds());
float unit = getDoodle().getUnitSize();
mRectTemp.left -= 10 * unit;
mRectTemp.top -= 10 * unit;
mRectTemp.right += 10 * unit;
mRectTemp.bottom += 10 * unit;
mRectTemp.left -= ITEM_PADDING * unit;
mRectTemp.top -= ITEM_PADDING * unit;
mRectTemp.right += ITEM_PADDING * unit;
mRectTemp.bottom += ITEM_PADDING * unit;
mPaint.setShader(null);
mPaint.setColor(0x33888888);
mPaint.setStyle(Paint.Style.FILL);
......@@ -72,7 +72,21 @@ public abstract class DoodleRotatableItemBase extends DoodleSelectableItemBase {
canvas.drawLine(mRectTemp.right, mRectTemp.top + mRectTemp.height() / 2,
mRectTemp.right + (DoodleSelectableItemBase.ITEM_CAN_ROTATE_BOUND - 16) * unit, mRectTemp.top + mRectTemp.height() / 2, mPaint);
canvas.drawCircle(mRectTemp.right + (DoodleSelectableItemBase.ITEM_CAN_ROTATE_BOUND - 8) * unit, mRectTemp.top + mRectTemp.height() / 2, 8 * unit, mPaint);
}
@Override
public void doDrawSelectedForeground(Canvas canvas) {
float unit = getDoodle().getUnitSize();
// pivot
mPaint.setColor(0xffffffff);
mPaint.setStrokeWidth(1f * unit);
mPaint.setStyle(Paint.Style.STROKE);
// +
int length = 3;
canvas.drawLine(getPivotX() - getLocation().x - length * unit, getPivotY() - getLocation().y, getPivotX() - getLocation().x + length * unit, getPivotY() - getLocation().y, mPaint);
canvas.drawLine(getPivotX() - getLocation().x, getPivotY() - getLocation().y - length * unit, getPivotX() - getLocation().x, getPivotY() - getLocation().y + length * unit, mPaint);
mPaint.setStyle(Paint.Style.FILL);
canvas.drawCircle(getPivotX() - getLocation().x, getPivotY() - getLocation().y, unit, mPaint);
}
/**
......@@ -85,7 +99,7 @@ public abstract class DoodleRotatableItemBase extends DoodleSelectableItemBase {
x = x - location.x;
y = y - location.y;
// 把变换后矩形中的触摸点,还原回未变换前矩形中的点,然后判断是否矩形中
PointF xy = rotatePoint(mTemp, (int) -getItemRotate(), x, y, 0, 0);
PointF xy = rotatePoint(mTemp, (int) -getItemRotate(), x, y, getPivotX() - getLocation().x, getPivotY() - getLocation().y);
mRectTemp.set(getBounds());
float unit = doodle.getUnitSize();
......
......@@ -17,7 +17,8 @@ import static cn.hzw.doodle.util.DrawUtil.rotatePoint;
public abstract class DoodleSelectableItemBase extends DoodleItemBase implements IDoodleSelectableItem {
public final static int ITEM_CAN_ROTATE_BOUND = 70;
public final static int ITEM_CAN_ROTATE_BOUND = 35;
public final static int ITEM_PADDING = 5; // 绘制item矩形区域时增加的padding
private Rect mRect = new Rect();
private Rect mRectTemp = new Rect();
......@@ -61,13 +62,13 @@ public abstract class DoodleSelectableItemBase extends DoodleItemBase implements
x = x - location.x;
y = y - location.y;
// 把变换后相对于矩形的触摸点,还原回未变换前的点,然后判断是否矩形中
mTemp = rotatePoint(mTemp, (int) -getItemRotate(), x, y, 0, 0);
mTemp = rotatePoint(mTemp, (int) -getItemRotate(), x, y, getPivotX() - getLocation().x, getPivotY() - getLocation().y);
mRectTemp.set(mRect);
float unit = getDoodle().getUnitSize();
mRectTemp.left -= 10 * unit;
mRectTemp.top -= 10 * unit;
mRectTemp.right += 10 * unit;
mRectTemp.bottom += 10 * unit;
mRectTemp.left -= ITEM_PADDING * unit;
mRectTemp.top -= ITEM_PADDING * unit;
mRectTemp.right += ITEM_PADDING * unit;
mRectTemp.bottom += ITEM_PADDING * unit;
return mRectTemp.contains((int) mTemp.x, (int) mTemp.y);
}
......@@ -78,6 +79,13 @@ public abstract class DoodleSelectableItemBase extends DoodleItemBase implements
}
}
@Override
protected void drawAfter(Canvas canvas) {
if (isSelected()) {
drawSelectedForeground(canvas);
}
}
/**
* 绘制选别时的背景
*
......@@ -87,21 +95,33 @@ public abstract class DoodleSelectableItemBase extends DoodleItemBase implements
public void drawSelectedBackground(Canvas canvas) {
canvas.save();
PointF location = getLocation(); // 获取旋转后的起始坐标
canvas.translate(location.x, location.y); // 把坐标系平移到文字矩形范围
canvas.rotate(getItemRotate(), 0, 0); // 旋转坐标系
canvas.translate(location.x, location.y); // 把坐标系平移到item矩形范围
canvas.rotate(getItemRotate(), getPivotX() - getLocation().x, getPivotY() - getLocation().y); // 旋转坐标系
doDrawSelectedBackground(canvas);
canvas.restore();
}
@Override
public void drawSelectedForeground(Canvas canvas) {
canvas.save();
PointF location = getLocation(); // 获取旋转后的起始坐标
canvas.translate(location.x, location.y); // 把坐标系平移到item矩形范围
canvas.rotate(getItemRotate(), getPivotX() - getLocation().x, getPivotY() - getLocation().y); // 旋转坐标系
doDrawSelectedForeground(canvas);
canvas.restore();
}
public void doDrawSelectedBackground(Canvas canvas) {
mRectTemp.set(getBounds());
float unit = getDoodle().getUnitSize();
mRectTemp.left -= 10 * unit;
mRectTemp.top -= 10 * unit;
mRectTemp.right += 10 * unit;
mRectTemp.bottom += 10 * unit;
mRectTemp.left -= ITEM_PADDING * unit;
mRectTemp.top -= ITEM_PADDING * unit;
mRectTemp.right += ITEM_PADDING * unit;
mRectTemp.bottom += ITEM_PADDING * unit;
mPaint.setShader(null);
mPaint.setColor(0x33888888);
mPaint.setStyle(Paint.Style.FILL);
......@@ -119,6 +139,10 @@ public abstract class DoodleSelectableItemBase extends DoodleItemBase implements
canvas.drawRect(mRectTemp, mPaint);
}
public void doDrawSelectedForeground(Canvas canvas) {
}
@Override
public boolean isSelected() {
return mIsSelected;
......
......@@ -21,10 +21,9 @@ public class DoodleText extends DoodleRotatableItemBase {
public DoodleText(IDoodle doodle, String text, float size, IDoodleColor color, float x, float y) {
super(doodle, -doodle.getDoodleRotation(), x, y);
this.mText = text;
mText = text;
setSize(size);
setColor(color);
resetBounds(getBounds());
}
public String getText() {
......@@ -34,6 +33,18 @@ public class DoodleText extends DoodleRotatableItemBase {
public void setText(String text) {
mText = text;
resetBounds(getBounds());
setPivotX(getLocation().x + getBounds().width() / 2);
setPivotY(getLocation().y - getBounds().height() / 2);
}
@Override
public void setSize(float size) {
float oldPivotX = getPivotX();
float oldPivotY = getPivotY();
super.setSize(size);
setPivotX(getLocation().x + getBounds().width() / 2);
setPivotY(getLocation().y - getBounds().height() / 2);
setLocation(getLocation().x - (getPivotX() - oldPivotX), getLocation().y - (getPivotY() - oldPivotY));
}
@Override
......
......@@ -63,7 +63,6 @@ public class DoodleView extends FrameLayout implements IDoodle {
private float mMinScale = MIN_SCALE; // 最小缩放倍数
private float mMaxScale = MAX_SCALE; // 最大缩放倍数
private Paint mPaint;
private float mSize;
private IDoodleColor mColor; // 画笔底色
......@@ -127,11 +126,6 @@ public class DoodleView extends FrameLayout implements IDoodle {
mScale = 1f;
mColor = new DoodleColor(Color.RED);
mPaint = new Paint();
mPaint.setStrokeWidth(mSize);
mPaint.setAntiAlias(true);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);// 圆滑
mPen = DoodlePen.BRUSH;
mShape = DoodleShape.HAND_WRITE;
......
......@@ -4,8 +4,6 @@ import android.graphics.Bitmap;
import java.util.List;
import cn.hzw.doodle.DoodleColor;
/**
* Created on 27/06/2018.
*/
......
......@@ -3,8 +3,6 @@ package cn.hzw.doodle.core;
import android.graphics.Canvas;
import android.graphics.PointF;
import cn.hzw.doodle.DoodleColor;
/**
* Created on 27/06/2018.
*/
......
......@@ -33,10 +33,17 @@ public interface IDoodleSelectableItem extends IDoodleItem {
public boolean contains(float x, float y);
/**
* 绘制选时的背景
* 绘制选时的背景
*
* @param canvas
*/
public void drawSelectedBackground(Canvas canvas);
/**
* 绘制选中时的前景
*
* @param canvas
*/
public void drawSelectedForeground(Canvas canvas);
}
......@@ -15,7 +15,6 @@ import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
import cn.forward.androids.utils.Util;
......@@ -68,7 +67,7 @@ public class ColorPickerDialog extends Dialog {
private Paint mLinePaint;//分隔线画笔
private Paint mRectPaint;//渐变方块画笔
private Shader rectShader;//渐变方块渐变图像
private Shader rectShader;//渐变方块渐变图像
private float rectLeft;//渐变方块左x坐标
private float rectTop;//渐变方块右x坐标
private float rectRight;//渐变方块上y坐标
......@@ -259,11 +258,7 @@ public class ColorPickerDialog extends Dialog {
double outCircle = Math.PI * outRadius * outRadius;
double inCircle = Math.PI * inRadius * inRadius;
double fingerCircle = Math.PI * (x * x + y * y);
if (fingerCircle < outCircle && fingerCircle > inCircle) {
return true;
} else {
return false;
}
return fingerCircle < outCircle && fingerCircle > inCircle;
}
/**
......@@ -277,11 +272,7 @@ public class ColorPickerDialog extends Dialog {
private boolean inCenter(float x, float y, float centerRadius) {
double centerCircle = Math.PI * centerRadius * centerRadius;
double fingerCircle = Math.PI * (x * x + y * y);
if (fingerCircle < centerCircle) {
return true;
} else {
return false;
}
return fingerCircle < centerCircle;
}
/**
......@@ -292,11 +283,7 @@ public class ColorPickerDialog extends Dialog {
* @return
*/
private boolean inRect(float x, float y) {
if (x <= rectRight && x >= rectLeft && y <= rectBottom && y >= rectTop) {
return true;
} else {
return false;
}
return x <= rectRight && x >= rectLeft && y <= rectBottom && y >= rectTop;
}
/**
......
......@@ -2,8 +2,6 @@ package cn.hzw.doodle.dialog;
import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.text.Editable;
import android.text.Html;
import android.text.TextUtils;
......@@ -17,12 +15,8 @@ import android.widget.TextView;
import java.util.List;
import cn.forward.androids.base.InjectionLayoutInflater;
import cn.forward.androids.utils.ImageUtils;
import cn.forward.androids.utils.StatusBarUtil;
import cn.hzw.doodle.DoodleBitmap;
import cn.hzw.doodle.DoodleText;
import cn.hzw.doodle.R;
import cn.hzw.doodle.core.IDoodleSelectableItem;
import cn.hzw.doodle.imagepicker.ImageSelectorView;
import cn.hzw.doodle.util.DrawUtil;
......
......@@ -145,7 +145,7 @@ public class DrawUtil {
}
// 顺时针旋转
public static PointF rotatePoint(PointF coords, int degree, float x, float y, float px, float py) {
public static PointF rotatePoint(PointF coords, float degree, float x, float y, float px, float py) {
if (degree % 360 == 0) {
coords.x = x;
coords.y = y;
......
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/doodle_shape_circle_pressed" android:state_pressed="true" />
<item android:drawable="@drawable/doodle_shape_circle_pressed" android:state_selected="true" />
<item android:drawable="@drawable/doodle_shape_circle_pressed" android:state_checked="true" />
</selector>
......@@ -6,8 +6,6 @@
<string name="doodle_saving_picture">Save before exit?</string>
<string name="doodle_enter">Enter</string>
<string name="doodle_cancel">Cancel</string>
<string name="doodle_success">Success</string>
<string name="doodle_failed">Failed</string>
<string name="doodle_edit">Edit</string>
<string name="doodle_remove">Delete</string>
......
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="doodle_btn_pressed_color">#ffffd943</color>
<color name="doodle_btn_text">#000000</color>
<color name="doodle_btn_border">#88cccccc</color>
</resources>
\ No newline at end of file
......@@ -6,8 +6,6 @@
<string name="doodle_saving_picture">保存图片</string>
<string name="doodle_enter">确定</string>
<string name="doodle_cancel">取消</string>
<string name="doodle_success">成功</string>
<string name="doodle_failed">失败</string>
<string name="doodle_edit">编辑</string>
<string name="doodle_remove">移除</string>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册